PySide应用采用Fusion风格,PC休眠后调色板丢失如何修复?
修复Qt Fusion深色主题休眠后调色板丢失问题
问题根源
你当前监听的0x15事件并非系统电源状态变化的正确触发点,无法精准捕获休眠恢复的时机;同时仅刷新主窗口调色板的操作不够彻底——Fusion风格的调色板是全局生效的,必须确保应用级别的调色板重新覆盖并强制控件完成渲染刷新。
解决方案步骤
监听正确的电源广播事件
系统休眠恢复对应的Windows原生事件是WM_POWERBROADCAST(消息值0x0021),其中休眠自动恢复的事件代码为PBT_APMRESUMEAUTOMATIC(0x0012),这才是需要捕获的关键时机。全局重新应用调色板
不要仅给主窗口设置调色板,直接给QApplication实例重新设置自定义调色板,确保所有控件都能获取到正确的全局颜色配置。强制控件全量刷新
重新设置调色板后,调用repaint()和processEvents()方法,强制主窗口及所有子控件完成重新渲染。
修改后的代码示例
import ctypes from PyQt5 import QtCore, QtWidgets class WinEventFilter(QtCore.QAbstractNativeEventFilter): def __init__(self, app): super().__init__() self.app = app self.main_window = None def nativeEventFilter(self, event_type, message): if event_type == b"windows_generic_MSG": msg = ctypes.wintypes.MSG.from_address(message.__int__()) # 监听系统电源广播事件 if msg.message == 0x0021: event_code = ctypes.c_int(msg.wParam).value # 捕获休眠自动恢复的触发信号 if event_code == 0x0012 and self.main_window is not None: # 全局重新应用深色主题调色板 self.app.set_theme(apply=True) # 强制主窗口及子控件刷新渲染 self.main_window.repaint() self.app.processEvents() return False, 0 # 应用初始化时安装事件过滤器 app = QtWidgets.QApplication([]) win_event_filter = WinEventFilter(app) app.installNativeEventFilter(win_event_filter)
额外优化建议
- 自定义调色板时,使用
QPalette.setColorGroups()为所有颜色组(Active、Inactive、Disabled)设置一致的深色主题颜色,避免控件状态切换时出现默认灰色。 - 若
set_theme方法原本仅针对主窗口,修改该方法使其直接操作QApplication.instance().setPalette(custom_palette),确保全局生效。
内容的提问来源于stack exchange,提问作者danielhrisca
相关产品推荐
相关产品推荐

