当前位置: 首页 > news >正文

【开源工具】Windows屏幕控制大师:息屏+亮度调节+快捷键一体化解决方案

🖥️ 从零打造Windows屏幕控制大师:息屏+亮度调节+快捷键一体化解决方案在这里插入图片描述

请添加图片描述

🌈 个人主页:创客白泽 - CSDN博客
🔥 系列专栏:🐍《Python开源项目实战》
💡 热爱不止于代码,热情源自每一个灵感闪现的夜晚。愿以开源之火,点亮前行之路。
🐋 希望大家多多支持,我们一起进步!
👍 🎉如果文章对你有帮助的话,欢迎 点赞 👍🏻 评论 💬 收藏 ⭐️ 加关注+💗分享给更多人哦

请添加图片描述

📜 概述

在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节。今天我将分享一个基于Python和PySide6开发的Windows屏幕控制工具,它集成了一键息屏亮度调节自动息屏时间设置全局快捷键等实用功能,并支持系统托盘运行开机自启动

本文将深入解析这个工具的实现原理关键技术点完整代码,适合有一定Python基础的开发者学习GUI开发、系统级操作和实用工具开发。

🎯 功能亮点

  1. 💤 一键息屏功能

    • 立即关闭显示器节省能源
    • 支持全局快捷键触发(可自定义)
  2. ⏱️ 自动息屏时间设置

    • 预设常用时间(1/5/10/15/30/60分钟)
    • 支持自定义任意分钟数
    • 永不息屏模式
  3. ☀️ 屏幕亮度控制

    • 0-100%无级调节
    • 预设常用亮度档位
    • 亮度调节快捷键支持
  4. ⚙️ 实用附加功能

    • 系统托盘运行
    • 开机自启动
    • 启动时最小化
    • 当前设置实时显示

🖼️ 界面展示

主界面设计

在这里插入图片描述

界面采用现代化设计,包含:

  • 醒目的标题区
  • 快速息屏大按钮
  • 自动息屏时间预设区
  • 亮度控制滑块
  • 应用设置面板
  • 当前设置显示区

系统托盘菜单

在这里插入图片描述

🛠️ 实现步骤详解

1. 环境准备

# 主要依赖库
import sys
import ctypes
import subprocess
import winreg
from PySide6.QtWidgets import (QApplication, QMainWindow, ...)
from PySide6.QtCore import Qt, QTimer, QSettings

2. 亮度控制模块

亮度调节采用了三种备选方案,确保兼容性:

class BrightnessController:def set_brightness(self, level):# 方法1: WMI (Windows Management Instrumentation)try:import wmiw = wmi.WMI(namespace='wmi')methods = w.WmiMonitorBrightnessMethods()[0]methods.WmiSetBrightness(level, 0)# 方法2: PowerShell命令except:script = f"$brightness = {level}; $myMonitor = Get-WmiObject..."subprocess.run(["powershell", "-Command", script])# 方法3: DDC/CI控制except:import screen_brightness_control as sbcsbc.set_brightness(level)

3. 息屏功能实现

使用Windows API发送消息关闭显示器:

def turn_off_screen(self):# 0x0112 = WM_SYSCOMMAND, 0xF170 = SC_MONITORPOWER, 2 = 关闭显示器ctypes.windll.user32.SendMessageW(0xFFFF, 0x0112, 0xF170, 2)

4. 息屏时间设置

通过Windows powercfg命令修改电源设置:

def set_screen_timeout(self, minutes):if minutes == 0:  # 永不息屏subprocess.run(['powercfg', '/change', 'monitor-timeout-ac', '0'])else:  # 设置指定时间subprocess.run(['powercfg', '/change', 'monitor-timeout-ac', str(minutes)])

5. 全局快捷键实现

使用QShortcut捕获全局快捷键:

def setup_global_shortcut(self, key_sequence):self.global_shortcut = QShortcut(key_sequence, self)self.global_shortcut.activated.connect(self.turn_off_screen)

6. 开机自启动

通过修改Windows注册表实现:

def toggle_autostart(self, state):key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"if state == Qt.Checked:  # 添加启动项winreg.SetValueEx(key, "ScreenController", 0, winreg.REG_SZ, exe_path)else:  # 删除启动项winreg.DeleteValue(key, "ScreenController")

7. 系统托盘集成

创建托盘图标和右键菜单:

def setup_tray_icon(self):self.tray_icon = QSystemTrayIcon(self)tray_menu = QMenu()# 添加菜单项show_action = QAction("显示主窗口", self)screen_off_action = QAction("立即息屏", self)# 亮度子菜单brightness_menu = tray_menu.addMenu("屏幕亮度")for level in [0, 25, 50, 75, 100]:action = QAction(f"{level}%", self)action.triggered.connect(lambda l=level: self.set_brightness_level(l))brightness_menu.addAction(action)

🔍 关键代码解析

1. 多方法亮度控制

亮度控制模块采用了策略模式,依次尝试三种不同的亮度调节方法:

  1. WMI方式:最原生的Windows管理接口
  2. PowerShell方式:兼容性更好的脚本方法
  3. DDC/CI方式:直接与显示器通信

这种设计确保了在各种Windows环境和硬件配置下都能正常工作。

2. 设置持久化

使用QSettings实现配置的自动保存和加载:

# 保存设置
self.settings.setValue("shortcut", self.shortcut_edit.keySequence().toString())# 加载设置
shortcut_string = self.settings.value("shortcut", "", type=str)

3. 管理员权限检测

关键系统操作需要管理员权限:

def is_admin(self):try:return ctypes.windll.shell32.IsUserAnAdmin()except:return False

📥 源码下载

import sys
import ctypes
import subprocess
import os
import sys
import winreg
import argparse
from pathlib import Path
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGridLayout, QPushButton, QLabel, QLineEdit, QFrame, QMessageBox,QGroupBox, QSpacerItem, QSizePolicy, QCheckBox, QKeySequenceEdit,QSystemTrayIcon, QMenu, QSlider
)
from PySide6.QtCore import Qt, QTimer, QSettings, QStandardPaths
from PySide6.QtGui import QFont, QPalette, QColor, QKeySequence, QShortcut, QIcon, QPixmap, QAction# 获取应用程序路径(支持打包后的可执行文件)
def get_app_path():"""获取应用程序路径,支持打包后的可执行文件"""if getattr(sys, 'frozen', False):return Path(sys.executable).parentelse:return Path(__file__).parent# 获取配置文件路径
def get_config_path():"""获取配置文件路径"""config_dir = QStandardPaths.writableLocation(QStandardPaths.AppConfigLocation)return Path(config_dir) / "ScreenController"class BrightnessController:"""屏幕亮度控制类"""def __init__(self):self.physical_monitors = self._get_physical_monitors()def _get_physical_monitors(self):"""获取物理显示器句柄"""try:from screeninfo import get_monitorsreturn [monitor for monitor in get_monitors() if monitor.is_primary]except Exception as e:print(f"获取显示器信息失败: {e}")return []def set_brightness(self, level):"""设置屏幕亮度(0-100)"""try:if not (0 <= level <= 100):raise ValueError("亮度值必须在0-100之间")# 方法1: 使用WMI (Windows Management Instrumentation)try:import wmiw = wmi.WMI(namespace='wmi')methods = w.WmiMonitorBrightnessMethods()[0]methods.WmiSetBrightness(level, 0)return Trueexcept Exception as wmi_error:# 方法2: 使用PowerShell命令 (适用于更多系统)try:brightness = max(0, min(100, level))script = f"""$brightness = {brightness}$delay = 0$myMonitor = Get-WmiObject -Namespace root\\wmi -Class WmiMonitorBrightnessMethods$myMonitor.WmiSetBrightness($delay, $brightness)"""subprocess.run(["powershell", "-Command", script], check=True, creationflags=subprocess.CREATE_NO_WINDOW)return Trueexcept subprocess.CalledProcessError:# 方法3: 使用DDC/CI (需要显示器支持)try:if self.physical_monitors:import screen_brightness_control as sbcsbc.set_brightness(level)return Trueexcept Exception as sbc_error:raise Exception(f"所有亮度调节方法均失败: WMI错误: {wmi_error}, DDC/CI错误: {sbc_error}")except Exception as e:raise Exception(f"设置亮度失败: {str(e)}")class ScreenController(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("🖥️ Windows屏幕控制")self.setFixedSize(1000, 800)  # 增加窗口尺寸以容纳亮度控制# 亮度控制器self.brightness_controller = BrightnessController()# 设置存储config_path = get_config_path()config_path.mkdir(parents=True, exist_ok=True)settings_file = config_path / "settings.ini"self.settings = QSettings(str(settings_file), QSettings.IniFormat)# 全局快捷键self.global_shortcut = Noneself.brightness_shortcut = None# 系统托盘self.tray_icon = Noneself.setup_tray_icon()self.setup_ui()self.setup_style()self.load_settings()# 定时器用于更新当前设置self.update_timer = QTimer()self.update_timer.timeout.connect(self.update_current_setting)self.update_timer.start(5000)  # 每5秒更新一次# 初始更新self.update_current_setting()def setup_ui(self):"""设置用户界面"""central_widget = QWidget()self.setCentralWidget(central_widget)# 主布局main_layout = QVBoxLayout(central_widget)main_layout.setSpacing(20)main_layout.setContentsMargins(25, 25, 25, 25)# 标题 - 添加emojititle_label = QLabel("🖥️ Windows屏幕控制器")title_font = QFont("Microsoft YaHei", 20, QFont.Bold)title_label.setFont(title_font)title_label.setAlignment(Qt.AlignCenter)title_label.setStyleSheet("""QLabel {padding: 15px;background: qlineargradient(x1:0, y1:0, x2:1, y2:0,stop:0 #3498db, stop:1 #2ecc71);border-radius: 12px;border: 2px solid #bdc3c7;color: white;}""")main_layout.addWidget(title_label)# 快速息屏按钮self.screen_off_btn = QPushButton("💤 立即息屏")self.screen_off_btn.clicked.connect(self.turn_off_screen)self.screen_off_btn.setFixedHeight(65)button_font = QFont("Microsoft YaHei", 14, QFont.Bold)self.screen_off_btn.setFont(button_font)self.screen_off_btn.setStyleSheet("""QPushButton {background-color: #e74c3c;color: white;border: none;border-radius: 12px;padding: 15px;}QPushButton:hover {background-color: #ec7063;transform: scale(1.02);}QPushButton:pressed {background-color: #c0392b;}""")main_layout.addWidget(self.screen_off_btn)# 分隔线separator = QFrame()separator.setFrameShape(QFrame.HLine)separator.setFrameShadow(QFrame.Sunken)separator.setStyleSheet("""QFrame {color: #bdc3c7;margin: 10px 0;}""")main_layout.addWidget(separator)# 创建水平布局容器horizontal_container = QWidget()horizontal_layout = QHBoxLayout(horizontal_container)horizontal_layout.setSpacing(20)horizontal_layout.setContentsMargins(0, 0, 0, 0)# 左侧:息屏时间设置组settings_group = QGroupBox("⏱️ 自动息屏时间设置")settings_group.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))settings_group.setStyleSheet("""QGroupBox {font-weight: bold;border: 2px solid #3498db;border-radius: 12px;margin-top: 10px;padding-top: 15px;background-color: #f8fafc;}QGroupBox::title {subcontrol-origin: margin;left: 20px;padding: 0 10px 0 10px;color: #2980b9;}""")settings_layout = QVBoxLayout(settings_group)settings_layout.setSpacing(15)# 预设时间按钮网格preset_label = QLabel("⚡ 快速设置(分钟):")preset_label.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))preset_label.setStyleSheet("QLabel { color: #2c3e50; margin-bottom: 5px; }")settings_layout.addWidget(preset_label)# 第一行:1, 5, 10分钟preset_row1 = QWidget()preset_layout1 = QHBoxLayout(preset_row1)preset_layout1.setSpacing(12)preset_layout1.setContentsMargins(0, 0, 0, 0)time_emojis = {1: "⏱️", 5: "⏳", 10: "⌛"}for time_val in [1, 5, 10]:btn = QPushButton(f"{time_emojis.get(time_val, '⏱️')} {time_val}分钟")btn.clicked.connect(lambda checked=None, t=time_val: self.set_screen_timeout(t))btn.setFixedHeight(50)btn.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))btn.setStyleSheet("""QPushButton {background-color: #3498db;color: white;border: none;border-radius: 10px;padding: 10px;min-width: 90px;}QPushButton:hover {background-color: #5dade2;}QPushButton:pressed {background-color: #2980b9;}""")preset_layout1.addWidget(btn)settings_layout.addWidget(preset_row1)# 第二行:15, 30, 60分钟preset_row2 = QWidget()preset_layout2 = QHBoxLayout(preset_row2)preset_layout2.setSpacing(12)preset_layout2.setContentsMargins(0, 0, 0, 0)time_emojis = {15: "🕒", 30: "🕝", 60: "🕐"}for time_val in [15, 30, 60]:btn = QPushButton(f"{time_emojis.get(time_val, '🕒')} {time_val}分钟")btn.clicked.connect(lambda checked=None, t=time_val: self.set_screen_timeout(t))btn.setFixedHeight(50)btn.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))btn.setStyleSheet("""QPushButton {background-color: #16a085;color: white;border: none;border-radius: 10px;padding: 10px;min-width: 90px;}QPushButton:hover {background-color: #48c9b0;}QPushButton:pressed {background-color: #138d75;}""")preset_layout2.addWidget(btn)settings_layout.addWidget(preset_row2)# 添加间距settings_layout.addItem(QSpacerItem(20, 15, QSizePolicy.Minimum, QSizePolicy.Fixed))# 自定义时间设置custom_label = QLabel("🎨 自定义时间:")custom_label.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))custom_label.setStyleSheet("QLabel { color: #2c3e50; margin-bottom: 5px; }")settings_layout.addWidget(custom_label)custom_widget = QWidget()custom_layout = QHBoxLayout(custom_widget)custom_layout.setSpacing(12)custom_layout.setContentsMargins(0, 0, 0, 0)self.custom_time_input = QLineEdit()self.custom_time_input.setPlaceholderText("输入分钟数...")self.custom_time_input.setFixedHeight(50)self.custom_time_input.setFont(QFont("Microsoft YaHei", 11))self.custom_time_input.returnPressed.connect(self.set_custom_timeout)self.custom_time_input.setStyleSheet("""QLineEdit {border: 2px solid #bdc3c7;border-radius: 10px;padding: 12px;background-color: white;font-size: 11pt;}QLineEdit:focus {border-color: #f39c12;background-color: #fffde7;}""")custom_layout.addWidget(self.custom_time_input, 2)minutes_label = QLabel("⏰ 分钟")minutes_label.setFont(QFont("Microsoft YaHei", 11))minutes_label.setStyleSheet("QLabel { color: #7f8c8d; }")custom_layout.addWidget(minutes_label)custom_btn = QPushButton("✅ 设置")custom_btn.clicked.connect(self.set_custom_timeout)custom_btn.setFixedHeight(50)custom_btn.setFixedWidth(100)custom_btn.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))custom_btn.setStyleSheet("""QPushButton {background-color: #f39c12;color: white;border: none;border-radius: 10px;padding: 10px;}QPushButton:hover {background-color: #f4d03f;}QPushButton:pressed {background-color: #d68910;}""")custom_layout.addWidget(custom_btn)settings_layout.addWidget(custom_widget)# 添加间距settings_layout.addItem(QSpacerItem(20, 15, QSizePolicy.Minimum, QSizePolicy.Fixed))# 永不息屏按钮never_btn = QPushButton("🚫 永不息屏")never_btn.clicked.connect(lambda checked=None: self.set_screen_timeout(0))never_btn.setFixedHeight(55)never_btn.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))never_btn.setStyleSheet("""QPushButton {background-color: #e74c3c;color: white;border: none;border-radius: 12px;padding: 12px;font-weight: bold;}QPushButton:hover {background-color: #ec7063;transform: scale(1.02);}QPushButton:pressed {background-color: #c0392b;}""")settings_layout.addWidget(never_btn)# 将息屏时间设置组添加到左侧horizontal_layout.addWidget(settings_group)# 中间:亮度控制组brightness_group = QGroupBox("☀️ 屏幕亮度控制")brightness_group.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))brightness_group.setStyleSheet("""QGroupBox {font-weight: bold;border: 2px solid #f39c12;border-radius: 12px;margin-top: 10px;padding-top: 15px;background-color: #fff9e6;}QGroupBox::title {subcontrol-origin: margin;left: 20px;padding: 0 10px 0 10px;color: #d35400;}""")brightness_layout = QVBoxLayout(brightness_group)brightness_layout.setSpacing(15)# 亮度滑块brightness_slider_layout = QHBoxLayout()self.brightness_slider = QSlider(Qt.Horizontal)self.brightness_slider.setRange(0, 100)self.brightness_slider.setValue(80)self.brightness_slider.setTickInterval(10)self.brightness_slider.setTickPosition(QSlider.TicksBelow)self.brightness_slider.valueChanged.connect(self.adjust_brightness)self.brightness_slider.setStyleSheet("""QSlider::groove:horizontal {height: 10px;background: #e0e0e0;border-radius: 5px;}QSlider::handle:horizontal {width: 20px;height: 20px;background: #f39c12;border-radius: 10px;margin: -5px 0;}QSlider::sub-page:horizontal {background: #f1c40f;border-radius: 5px;}""")brightness_slider_layout.addWidget(self.brightness_slider)self.brightness_label = QLabel("80%")self.brightness_label.setFont(QFont("Microsoft YaHei", 10, QFont.Bold))self.brightness_label.setFixedWidth(40)self.brightness_label.setAlignment(Qt.AlignCenter)brightness_slider_layout.addWidget(self.brightness_label)brightness_layout.addLayout(brightness_slider_layout)# 亮度预设按钮brightness_preset_layout = QHBoxLayout()brightness_preset_layout.setSpacing(10)for level in [0, 25, 50, 75, 100]:btn = QPushButton(f"{level}%")btn.setFixedHeight(35)btn.setFont(QFont("Microsoft YaHei", 9))btn.clicked.connect(lambda checked=None, l=level: self.set_brightness_level(l))btn.setStyleSheet("""QPushButton {background-color: #f1c40f;color: #34495e;border: none;border-radius: 8px;padding: 5px;}QPushButton:hover {background-color: #f39c12;color: white;}QPushButton:pressed {background-color: #e67e22;}""")brightness_preset_layout.addWidget(btn)brightness_layout.addLayout(brightness_preset_layout)# 亮度快捷键设置brightness_shortcut_layout = QHBoxLayout()brightness_shortcut_label = QLabel("🔆 亮度调节快捷键:")brightness_shortcut_label.setFont(QFont("Microsoft YaHei", 10))brightness_shortcut_layout.addWidget(brightness_shortcut_label)self.brightness_shortcut_edit = QKeySequenceEdit()self.brightness_shortcut_edit.setFixedHeight(35)self.brightness_shortcut_edit.keySequenceChanged.connect(self.on_brightness_shortcut_changed)brightness_shortcut_layout.addWidget(self.brightness_shortcut_edit)brightness_layout.addLayout(brightness_shortcut_layout)horizontal_layout.addWidget(brightness_group)# 右侧:应用设置组app_settings_group = QGroupBox("⚙️ 应用设置")app_settings_group.setFont(QFont("Microsoft YaHei", 12, QFont.Bold))app_settings_group.setStyleSheet("""QGroupBox {font-weight: bold;border: 2px solid #9b59b6;border-radius: 12px;margin-top: 15px;padding-top: 15px;background-color: #faf5ff;}QGroupBox::title {subcontrol-origin: margin;left: 20px;padding: 0 15px 0 15px;color: #8e44ad;}""")app_settings_layout = QVBoxLayout(app_settings_group)app_settings_layout.setSpacing(20)# 开机自启动复选框autostart_widget = QWidget()autostart_layout = QHBoxLayout(autostart_widget)autostart_layout.setContentsMargins(10, 5, 10, 5)self.autostart_checkbox = QCheckBox("🚀 开机自启动")self.autostart_checkbox.setFont(QFont("Microsoft YaHei", 11))self.autostart_checkbox.stateChanged.connect(self.toggle_autostart)self.autostart_checkbox.setStyleSheet("""QCheckBox {color: #2c3e50;padding: 8px;font-weight: 500;}QCheckBox::indicator {width: 22px;height: 22px;}QCheckBox::indicator:unchecked {border: 2px solid #bdc3c7;border-radius: 5px;background-color: white;}QCheckBox::indicator:checked {border: 2px solid #9b59b6;border-radius: 5px;background-color: #9b59b6;image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEzIDRMNiAxMkwzIDgiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=);}QCheckBox::indicator:hover {border-color: #9b59b6;}""")autostart_layout.addWidget(self.autostart_checkbox)autostart_layout.addStretch()app_settings_layout.addWidget(autostart_widget)# 启动时最小化复选框minimize_widget = QWidget()minimize_layout = QHBoxLayout(minimize_widget)minimize_layout.setContentsMargins(10, 5, 10, 5)self.minimize_on_start_checkbox = QCheckBox("📥 启动时最小化到系统托盘")self.minimize_on_start_checkbox.setFont(QFont("Microsoft YaHei", 11))self.minimize_on_start_checkbox.stateChanged.connect(self.save_settings)self.minimize_on_start_checkbox.setStyleSheet(self.autostart_checkbox.styleSheet())minimize_layout.addWidget(self.minimize_on_start_checkbox)minimize_layout.addStretch()app_settings_layout.addWidget(minimize_widget)# 快捷键设置shortcut_container = QWidget()shortcut_container_layout = QVBoxLayout(shortcut_container)shortcut_container_layout.setContentsMargins(10, 5, 10, 5)shortcut_container_layout.setSpacing(8)shortcut_header = QWidget()shortcut_header_layout = QHBoxLayout(shortcut_header)shortcut_header_layout.setContentsMargins(0, 0, 0, 0)shortcut_label = QLabel("⌨️ 立即息屏快捷键:")shortcut_label.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))shortcut_label.setStyleSheet("QLabel { color: #2c3e50; font-weight: 500; }")shortcut_header_layout.addWidget(shortcut_label)shortcut_header_layout.addStretch()shortcut_container_layout.addWidget(shortcut_header)shortcut_widget = QWidget()shortcut_layout = QHBoxLayout(shortcut_widget)shortcut_layout.setSpacing(12)shortcut_layout.setContentsMargins(0, 0, 0, 0)self.shortcut_edit = QKeySequenceEdit()self.shortcut_edit.setFixedHeight(45)self.shortcut_edit.setFont(QFont("Microsoft YaHei", 10))self.shortcut_edit.keySequenceChanged.connect(self.on_shortcut_changed)self.shortcut_edit.setStyleSheet("""QKeySequenceEdit {border: 2px solid #bdc3c7;border-radius: 10px;padding: 10px;background-color: white;font-size: 10pt;}QKeySequenceEdit:focus {border-color: #9b59b6;background-color: #fffde7;}""")shortcut_layout.addWidget(self.shortcut_edit, 2)clear_shortcut_btn = QPushButton("🗑️ 清除")clear_shortcut_btn.clicked.connect(self.clear_shortcut)clear_shortcut_btn.setFixedHeight(45)clear_shortcut_btn.setFixedWidth(80)clear_shortcut_btn.setFont(QFont("Microsoft YaHei", 9, QFont.Bold))clear_shortcut_btn.setStyleSheet("""QPushButton {background-color: #95a5a6;color: white;border: none;border-radius: 10px;padding: 8px;}QPushButton:hover {background-color: #b2bec3;}QPushButton:pressed {background-color: #7f8c8d;}""")shortcut_layout.addWidget(clear_shortcut_btn)shortcut_container_layout.addWidget(shortcut_widget)app_settings_layout.addWidget(shortcut_container)# 将应用设置组添加到右侧horizontal_layout.addWidget(app_settings_group)# 将水平布局容器添加到主布局main_layout.addWidget(horizontal_container)# 当前设置显示self.current_setting_label = QLabel("🔍 当前设置:获取中...")self.current_setting_label.setFont(QFont("Microsoft YaHei", 10))self.current_setting_label.setAlignment(Qt.AlignCenter)self.current_setting_label.setStyleSheet("""QLabel {color: #7f8c8d;padding: 15px;background-color: #f8f9fa;border-radius: 8px;border: 1px solid #dee2e6;}""")main_layout.addWidget(self.current_setting_label)# 添加弹性空间main_layout.addItem(QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding))# 底部信息栏footer_label = QLabel("🛠️ 由创客白泽开发 | 🖥️ Windows屏幕控制工具 ")footer_label.setFont(QFont("Microsoft YaHei", 8))footer_label.setAlignment(Qt.AlignCenter)footer_label.setStyleSheet("QLabel { color: #7f8c8d; margin-top: 10px; }")main_layout.addWidget(footer_label)def setup_style(self):"""设置整体样式"""self.setStyleSheet("""QMainWindow {background-color: #ffffff;}QWidget {background-color: #ffffff;}""")def setup_tray_icon(self):"""设置系统托盘图标"""if not QSystemTrayIcon.isSystemTrayAvailable():QMessageBox.critical(self, "系统托盘", "系统托盘不可用")return# 创建托盘图标self.tray_icon = QSystemTrayIcon(self)# 尝试加载favicon.ico图标app_path = get_app_path()icon_path = app_path / "icon.ico"if icon_path.exists():icon = QIcon(str(icon_path))else:# 如果找不到favicon.ico,创建一个简单的图标pixmap = QPixmap(16, 16)pixmap.fill(Qt.blue)icon = QIcon(pixmap)self.tray_icon.setIcon(icon)# 创建托盘菜单tray_menu = QMenu()# 显示主窗口show_action = QAction("🖥️ 显示主窗口", self)show_action.triggered.connect(self.show_main_window)tray_menu.addAction(show_action)# 立即息屏screen_off_action = QAction("💤 立即息屏", self)screen_off_action.triggered.connect(self.turn_off_screen)tray_menu.addAction(screen_off_action)# 亮度调节菜单brightness_menu = tray_menu.addMenu("☀️ 屏幕亮度")brightness_levels = [("🌑 0%", 0),("🌘 25%", 25),("🌗 50%", 50),("🌖 75%", 75),("🌕 100%", 100)]for text, level in brightness_levels:action = QAction(text, self)action.triggered.connect(lambda checked=None, l=level: self.set_brightness_level(l))brightness_menu.addAction(action)tray_menu.addSeparator()# 退出程序quit_action = QAction("🚪 退出", self)quit_action.triggered.connect(QApplication.instance().quit)tray_menu.addAction(quit_action)self.tray_icon.setContextMenu(tray_menu)self.tray_icon.activated.connect(self.tray_icon_activated)# 设置托盘提示self.tray_icon.setToolTip("Windows屏幕控制器")# 显示托盘图标self.tray_icon.show()def tray_icon_activated(self, reason):"""托盘图标被激活时的处理"""if reason == QSystemTrayIcon.DoubleClick:self.show_main_window()def show_main_window(self):"""显示主窗口"""self.show()self.raise_()self.activateWindow()def turn_off_screen(self):"""立即关闭屏幕"""try:# 发送消息关闭显示器ctypes.windll.user32.SendMessageW(0xFFFF, 0x0112, 0xF170, 2)except Exception as e:if self.isVisible():QMessageBox.warning(self, "错误", f"关闭屏幕失败: {str(e)}")else:# 如果窗口不可见,通过托盘显示消息if self.tray_icon:self.tray_icon.showMessage("错误", f"关闭屏幕失败: {str(e)}", QSystemTrayIcon.Warning, 3000)def set_screen_timeout(self, minutes):"""设置屏幕超时时间"""try:if minutes == 0:message = "已设置为永不息屏"# 永不关闭屏幕result1 = subprocess.run(['powercfg', '/change', 'monitor-timeout-ac', '0'], capture_output=True, text=True, check=True, creationflags=subprocess.CREATE_NO_WINDOW)result2 = subprocess.run(['powercfg', '/change', 'monitor-timeout-dc', '0'], capture_output=True, text=True, check=True,creationflags=subprocess.CREATE_NO_WINDOW)else:message = f"已设置息屏时间为 {minutes} 分钟"# 设置指定的超时时间result1 = subprocess.run(['powercfg', '/change', 'monitor-timeout-ac', str(minutes)], capture_output=True, text=True, check=True,creationflags=subprocess.CREATE_NO_WINDOW)result2 = subprocess.run(['powercfg', '/change', 'monitor-timeout-dc', str(minutes)], capture_output=True, text=True, check=True,creationflags=subprocess.CREATE_NO_WINDOW)if self.isVisible():QMessageBox.information(self, "成功", message)else:# 如果窗口不可见,通过托盘显示消息if self.tray_icon:self.tray_icon.showMessage("设置成功", message, QSystemTrayIcon.Information, 3000)self.update_current_setting()except subprocess.CalledProcessError as e:error_msg = f"设置失败: {e.stderr if e.stderr else str(e)}"if self.isVisible():QMessageBox.warning(self, "错误", error_msg)else:if self.tray_icon:self.tray_icon.showMessage("错误", error_msg, QSystemTrayIcon.Warning, 3000)except FileNotFoundError:error_msg = "找不到powercfg命令,请确保在Windows系统上运行"if self.isVisible():QMessageBox.warning(self, "错误", error_msg)else:if self.tray_icon:self.tray_icon.showMessage("错误", error_msg, QSystemTrayIcon.Warning, 3000)except Exception as e:error_msg = f"未知错误: {str(e)}"if self.isVisible():QMessageBox.warning(self, "错误", error_msg)else:if self.tray_icon:self.tray_icon.showMessage("错误", error_msg, QSystemTrayIcon.Warning, 3000)def set_custom_timeout(self):"""设置自定义超时时间"""try:time_str = self.custom_time_input.text().strip()if not time_str:QMessageBox.warning(self, "警告", "请输入时间")returnminutes = int(time_str)if minutes < 0:QMessageBox.warning(self, "警告", "时间不能为负数")returnself.set_screen_timeout(minutes)self.custom_time_input.clear()  # 清空输入框except ValueError:QMessageBox.critical(self, "错误", "请输入有效的数字")def update_current_setting(self):"""更新当前设置显示"""try:# 获取当前屏幕超时设置result = subprocess.run(["powercfg", "/query", "SCHEME_CURRENT", "SUB_VIDEO", "VIDEOIDLE"], capture_output=True, text=True, check=True,creationflags=subprocess.CREATE_NO_WINDOW)# 解析输出获取当前设置lines = result.stdout.split('\n')ac_timeout = Nonefor line in lines:# 支持中英文输出if "Current AC Power Setting Index:" in line or "当前交流电源设置索引:" in line:try:ac_timeout = int(line.split(':')[1].strip(), 16)breakexcept (ValueError, IndexError):continueif ac_timeout is not None:if ac_timeout == 0:setting_text = "🔴 当前设置:永不息屏"else:minutes = ac_timeout // 60setting_text = f"🟢 当前设置:{minutes} 分钟后息屏"else:setting_text = "⚠️ 当前设置:解析失败"self.current_setting_label.setText(setting_text)except subprocess.CalledProcessError as e:error_detail = f"命令执行失败: {e.stderr if e.stderr else '未知错误'}"self.current_setting_label.setText(f"⚠️ 当前设置:获取失败 ({error_detail})")except FileNotFoundError:self.current_setting_label.setText("⚠️ 当前设置:找不到powercfg命令")except Exception as e:self.current_setting_label.setText(f"⚠️ 当前设置:异常错误 ({str(e)})")def adjust_brightness(self, value):"""调整屏幕亮度"""try:self.brightness_label.setText(f"{value}%")self.brightness_controller.set_brightness(value)except Exception as e:QMessageBox.warning(self, "亮度调节失败", f"无法调整亮度: {str(e)}")def set_brightness_level(self, level):"""设置特定亮度级别"""self.brightness_slider.setValue(level)self.adjust_brightness(level)def on_brightness_shortcut_changed(self, key_sequence):"""亮度快捷键改变时的处理"""if key_sequence.isEmpty():return# 检查快捷键冲突if self.check_shortcut_conflict(key_sequence):reply = QMessageBox.question(self, "快捷键冲突", f"⚠️ 快捷键 {key_sequence.toString()} 可能与其他程序冲突。\n是否仍要使用此快捷键?",QMessageBox.Yes | QMessageBox.No,QMessageBox.No)if reply == QMessageBox.No:self.brightness_shortcut_edit.clear()return# 设置新的快捷键self.setup_brightness_shortcut(key_sequence)self.save_settings()QMessageBox.information(self, "成功", f"✅ 已设置亮度调节快捷键:{key_sequence.toString()}")def setup_brightness_shortcut(self, key_sequence):"""设置亮度调节全局快捷键"""# 清除旧的快捷键if self.brightness_shortcut:self.brightness_shortcut.setEnabled(False)self.brightness_shortcut = None# 设置新的快捷键if not key_sequence.isEmpty():self.brightness_shortcut = QShortcut(key_sequence, self)self.brightness_shortcut.activated.connect(self.toggle_brightness)def toggle_brightness(self):"""切换亮度预设"""current = self.brightness_slider.value()if current >= 75:self.set_brightness_level(25)elif current >= 25:self.set_brightness_level(0)else:self.set_brightness_level(75)def is_admin(self):"""检查是否以管理员权限运行"""try:return ctypes.windll.shell32.IsUserAnAdmin()except:return Falsedef toggle_autostart(self, state):"""切换开机自启动"""try:key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"app_name = "WindowsScreenController"if state == Qt.Checked:# 添加到注册表with winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, 0, winreg.KEY_SET_VALUE) as key:if getattr(sys, 'frozen', False):# 打包后的可执行文件,添加启动时最小化参数exe_path = f'"{sys.executable}" --minimized'else:# Python脚本exe_path = sys.executablescript_path = os.path.abspath(__file__)exe_path = f'"{exe_path}" "{script_path}" --minimized'winreg.SetValueEx(key, app_name, 0, winreg.REG_SZ, exe_path)QMessageBox.information(self, "成功", "✅ 已启用开机自启动")else:# 从注册表删除try:with winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, 0, winreg.KEY_SET_VALUE) as key:winreg.DeleteValue(key, app_name)QMessageBox.information(self, "成功", "❌ 已禁用开机自启动")except FileNotFoundError:pass  # 键不存在,无需删除self.save_settings()except PermissionError:QMessageBox.warning(self, "错误", "⛔ 权限不足,无法修改注册表启动项")# 恢复复选框状态self.autostart_checkbox.setChecked(not state)except Exception as e:QMessageBox.critical(self, "错误", f"⚠️ 设置开机自启动失败:{str(e)}")# 恢复复选框状态self.autostart_checkbox.setChecked(not state)def check_autostart_status(self):"""检查开机自启动状态"""try:key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"app_name = "WindowsScreenController"with winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, 0, winreg.KEY_READ) as key:try:winreg.QueryValueEx(key, app_name)return Trueexcept FileNotFoundError:return Falseexcept Exception:return Falsedef on_shortcut_changed(self, key_sequence):"""快捷键改变时的处理"""if key_sequence.isEmpty():return# 检查快捷键冲突if self.check_shortcut_conflict(key_sequence):reply = QMessageBox.question(self, "快捷键冲突", f"⚠️ 快捷键 {key_sequence.toString()} 可能与其他程序冲突。\n是否仍要使用此快捷键?",QMessageBox.Yes | QMessageBox.No,QMessageBox.No)if reply == QMessageBox.No:self.shortcut_edit.clear()return# 设置新的快捷键self.setup_global_shortcut(key_sequence)self.save_settings()QMessageBox.information(self, "成功", f"✅ 已设置快捷键:{key_sequence.toString()}")def check_shortcut_conflict(self, key_sequence):"""检查快捷键冲突(简单检查常见系统快捷键)"""key_string = key_sequence.toString().lower()# 常见的系统快捷键system_shortcuts = ["ctrl+c", "ctrl+v", "ctrl+x", "ctrl+z", "ctrl+y", "ctrl+a", "ctrl+s","ctrl+alt+del", "ctrl+shift+esc", "alt+tab", "alt+f4", "win+l","win+d", "win+r", "win+e", "win+i", "win+x", "ctrl+alt+t","print screen", "alt+print screen", "ctrl+print screen"]return key_string in system_shortcutsdef setup_global_shortcut(self, key_sequence):"""设置全局快捷键"""# 清除旧的快捷键if self.global_shortcut:self.global_shortcut.setEnabled(False)self.global_shortcut = None# 设置新的快捷键if not key_sequence.isEmpty():self.global_shortcut = QShortcut(key_sequence, self)self.global_shortcut.activated.connect(self.turn_off_screen)def clear_shortcut(self):"""清除快捷键"""self.shortcut_edit.clear()if self.global_shortcut:self.global_shortcut.setEnabled(False)self.global_shortcut = Noneself.save_settings()QMessageBox.information(self, "成功", "🗑️ 已清除快捷键")def save_settings(self):"""保存设置"""self.settings.setValue("autostart", self.autostart_checkbox.isChecked())self.settings.setValue("minimize_on_start", self.minimize_on_start_checkbox.isChecked())self.settings.setValue("shortcut", self.shortcut_edit.keySequence().toString())self.settings.setValue("brightness_shortcut", self.brightness_shortcut_edit.keySequence().toString())self.settings.setValue("brightness_level", self.brightness_slider.value())def load_settings(self):"""加载设置"""# 加载开机自启动状态autostart_status = self.check_autostart_status()self.autostart_checkbox.setChecked(autostart_status)# 加载其他设置minimize_on_start = self.settings.value("minimize_on_start", False, type=bool)self.minimize_on_start_checkbox.setChecked(minimize_on_start)shortcut_string = self.settings.value("shortcut", "", type=str)if shortcut_string:key_sequence = QKeySequence(shortcut_string)self.shortcut_edit.setKeySequence(key_sequence)self.setup_global_shortcut(key_sequence)brightness_shortcut_string = self.settings.value("brightness_shortcut", "", type=str)if brightness_shortcut_string:key_sequence = QKeySequence(brightness_shortcut_string)self.brightness_shortcut_edit.setKeySequence(key_sequence)self.setup_brightness_shortcut(key_sequence)brightness_level = self.settings.value("brightness_level", 80, type=int)self.brightness_slider.setValue(brightness_level)self.brightness_label.setText(f"{brightness_level}%")# 如果设置了启动时最小化,则隐藏到托盘if minimize_on_start:self.hide()def showEvent(self, event):"""窗口显示时检查权限"""super().showEvent(event)if not self.is_admin():QMessageBox.warning(self, "权限提示", "⚠️ 建议以管理员权限运行此程序以确保所有功能正常工作")def closeEvent(self, event):"""关闭事件处理"""if self.tray_icon and self.tray_icon.isVisible():# 如果托盘图标可见,隐藏到托盘而不是退出self.hide()event.ignore()if not hasattr(self, '_tray_message_shown'):self.tray_icon.showMessage("程序已最小化到托盘","📌 程序仍在后台运行,双击托盘图标可重新打开",QSystemTrayIcon.Information,3000)self._tray_message_shown = Trueelse:self.save_settings()event.accept()def main():"""主函数"""# 解析命令行参数parser = argparse.ArgumentParser(description='Windows屏幕控制器')parser.add_argument('--minimized', action='store_true', help='启动时最小化到系统托盘')args = parser.parse_args()app = QApplication(sys.argv)# 设置应用程序样式app.setStyle('Fusion')# 设置应用程序信息app.setApplicationName("Windows屏幕控制器")app.setApplicationVersion("2.0")app.setOrganizationName("ScreenController")# 设置应用程序图标app_path = get_app_path()icon_path = app_path / "favicon.ico"if icon_path.exists():app.setWindowIcon(QIcon(str(icon_path)))window = ScreenController()# 如果指定了--minimized参数或设置了启动时最小化,则不显示主窗口if args.minimized or window.minimize_on_start_checkbox.isChecked():# 不显示主窗口,直接最小化到托盘passelse:window.show()sys.exit(app.exec())if __name__ == "__main__":# 检查并安装必要的依赖try:import wmiimport screeninfoimport screen_brightness_controlexcept ImportError:print("正在安装必要的依赖库...")try:import pippip.main(['install', 'wmi', 'screeninfo', 'screen-brightness-control'])except:subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'wmi', 'screeninfo', 'screen-brightness-control'])main()

🏆 项目总结

这个Windows屏幕控制工具通过精心设计的UI和稳健的后台实现,解决了日常使用中的多个痛点:

  1. 一键操作:告别繁琐的系统设置路径
  2. 全局快捷键:随时随地快速息屏
  3. 亮度精细控制:保护眼睛健康
  4. 无感运行:系统托盘常驻不打扰

技术亮点

  • 多方法兼容的亮度控制
  • 完善的异常处理机制
  • 符合Windows应用规范的设置存储
  • 优雅的系统托盘集成

扩展方向

  • 添加多显示器独立控制
  • 实现根据时间自动调整亮度
  • 增加使用统计和提醒功能

💡 使用建议

  1. 建议以管理员权限运行以获得完整功能
  2. 设置开机自启动+最小化,实现无感运行
  3. 为息屏功能设置顺手的全局快捷键(如Ctrl+Alt+L)

希望这个项目能帮助你提升工作效率,也欢迎提交Pull Request共同改进!


版权声明:本文采用CC BY-NC-SA 4.0协议,代码部分可自由使用,商业用途需授权。

相关文章:

  • 金仓数据库在线体验平台:开启国产数据库云端探索之旅
  • Excel数据导出小记
  • Uniapp跨端兼容性全方位解决方案
  • Eureka、Nacos、Zookeeper 优雅上下线机制
  • 大模型安全关键技术研究
  • SpringBoot 通过集成 Flink CDC 来实时追踪 MySql 数据变动
  • Kafka分区机制深度解析:架构原理、负载均衡与性能优化
  • 开源三代示波器720p虚拟界面设计,手机,电脑和Pad均可访问,专用于8通道同步数据采集处理,可玩性高,基于STM32H7(2025-06-17)
  • 02 ( chrome 浏览器插件, 立马翻译), 搭建本地 api
  • 6-16阿里前端面试记录
  • Uniapp设备API全面指南:从位置获取到扫码功能的实现
  • 【Linux】UDP与TCP协议
  • pyqt QMenuBar
  • 【前端基础】摩天之建的艺术:html(上)
  • 【Pandas】pandas DataFrame swaplevel
  • uniapp 小程序 学习(二)
  • YOLOE详解【浅显易懂!】
  • 【前端基础】摩天之建的艺术:html(下)
  • 二十四、【用户管理与权限 - 篇六】前端动态展现:基于权限的菜单与按钮控制
  • 上传本地项目至github
  • 许昌做网站公司/营销技巧五步推销法
  • 免费打开的网站/百度网址安全中心怎么关闭
  • wordpress托管建站/百度官网app
  • 策划会展网站建设/网络工程师培训班要多少钱
  • 公司网站可以自己做么/网络推广企业
  • 网站开发 明细/百度竞价排名是什么