个人主页:创客白泽 - CSDN博客
系列专栏:《Python开源项目实战》
热爱不止于代码,热情源自每一个灵感闪现的夜晚。愿以开源之火,点亮前行之路。
希望大家多多支持,我们一起进步!
如果文章对你有帮助的话,欢迎 点赞 评论 收藏 ⭐️ 加关注+分享给更多人哦
在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节。今天我将分享一个基于Python和PySide6开发的Windows屏幕控制工具,它集成了一键息屏、亮度调节、自动息屏时间设置和全局快捷键等实用功能,并支持系统托盘运行和开机自启动。
本文将深入解析这个工具的实现原理、关键技术点和完整代码,适合有一定Python基础的开发者学习GUI开发、系统级操作和实用工具开发。
一键息屏功能
⏱️ 自动息屏时间设置
☀️ 屏幕亮度控制
⚙️ 实用附加功能
界面采用现代化设计,包含:
# 主要依赖库
import sys
import ctypes
import subprocess
import winreg
from PySide6.QtWidgets import (QApplication, QMainWindow, ...)
from PySide6.QtCore import Qt, QTimer, QSettings
亮度调节采用了三种备选方案,确保兼容性:
class BrightnessController:
def set_brightness(self, level):
# 方法1: WMI (Windows Management Instrumentation)
try:
import wmi
w = 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 sbc
sbc.set_brightness(level)
使用Windows API发送消息关闭显示器:
def turn_off_screen(self):
# 0x0112 = WM_SYSCOMMAND, 0xF170 = SC_MONITORPOWER, 2 = 关闭显示器
ctypes.windll.user32.SendMessageW(0xFFFF, 0x0112, 0xF170, 2)
通过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)])
使用QShortcut捕获全局快捷键:
def setup_global_shortcut(self, key_sequence):
self.global_shortcut = QShortcut(key_sequence, self)
self.global_shortcut.activated.connect(self.turn_off_screen)
通过修改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")
创建托盘图标和右键菜单:
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)
亮度控制模块采用了策略模式,依次尝试三种不同的亮度调节方法:
这种设计确保了在各种Windows环境和硬件配置下都能正常工作。
使用QSettings实现配置的自动保存和加载:
# 保存设置
self.settings.setValue("shortcut", self.shortcut_edit.keySequence().toString())
# 加载设置
shortcut_string = self.settings.value("shortcut", "", type=str)
关键系统操作需要管理员权限:
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).parent
else:
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_monitors
return [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 wmi
w = wmi.WMI(namespace='wmi')
methods = w.WmiMonitorBrightnessMethods()[0]
methods.WmiSetBrightness(level, 0)
return True
except 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 True
except subprocess.CalledProcessError:
# 方法3: 使用DDC/CI (需要显示器支持)
try:
if self.physical_monitors:
import screen_brightness_control as sbc
sbc.set_brightness(level)
return True
except 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 = None
self.brightness_shortcut = None
# 系统托盘
self.tray_icon = None
self.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)
# 标题 - 添加emoji
title_label = QLabel("️ Windows屏幕控制器")
title_font = QFont("Microsoft YaHei", 20, QFont.Bold)
title_label.setFont(title_font)
title_label.setAlig