PySide6中QMessageBox在循环中引发界面假死问题求助
问题分析
你的程序出现假死的核心原因有两个:
hotkey方法中的while True死循环完全阻塞了Qt的事件循环,导致界面无法处理任何用户交互(包括QMessageBox的显示和响应)。- 使用第三方
keyboard库的轮询方式(keyboard.is_pressed)与Qt的事件驱动模型冲突,进一步加剧了界面阻塞。
另外代码里还有两处小bug:
self.Hotkey == True是比较操作而非赋值,应改为self.Hotkey = Trueposition_list和Hotkey是类属性,会被所有实例共享,应改为实例属性
修复后的代码
from PySide6.QtWidgets import * from PySide6.QtGui import * from PySide6.QtCore import * import pyautogui import sys class Window_controller(QWidget): def __init__(self): super().__init__() self.Hotkey = False # 改为实例属性 self.position_list = [] # 改为实例属性 self.layout = QVBoxLayout(self) self.label = QLabel("123") self.label.setFont(QFont("", 20)) self.layout.addWidget(self.label) # 注册Qt原生快捷键,替代第三方keyboard库 self.register_shortcuts() def register_shortcuts(self): # F11 切换热键激活状态 QShortcut(QKeySequence(Qt.Key_F11), self, self.toggle_hotkey_mode) # 注册F1-F4快捷键,默认禁用 self.f1_shortcut = QShortcut(QKeySequence(Qt.Key_F1), self, self.F1) self.f2_shortcut = QShortcut(QKeySequence(Qt.Key_F2), self, self.F2) self.f3_shortcut = QShortcut(QKeySequence(Qt.Key_F3), self, self.F3) self.f4_shortcut = QShortcut(QKeySequence(Qt.Key_F4), self, self.F4) self.toggle_hotkey_shortcuts(False) def toggle_hotkey_mode(self): self.Hotkey = not self.Hotkey if self.Hotkey: self.label.setText("Activated") self.toggle_hotkey_shortcuts(True) else: self.label.setText("") self.toggle_hotkey_shortcuts(False) def toggle_hotkey_shortcuts(self, enabled): self.f1_shortcut.setEnabled(enabled) self.f2_shortcut.setEnabled(enabled) self.f3_shortcut.setEnabled(enabled) self.f4_shortcut.setEnabled(enabled) def F1(self): if len(self.position_list) >= 2: pyautogui.moveTo(x=self.position_list[0], y=self.position_list[1]) else: self.set_position() def F2(self): if len(self.position_list) >= 4: pyautogui.moveTo(x=self.position_list[2], y=self.position_list[3]) else: self.set_position() def F3(self): if len(self.position_list) >= 6: pyautogui.moveTo(x=self.position_list[4], y=self.position_list[5]) else: self.set_position() def F4(self): if len(self.position_list) >= 8: pyautogui.moveTo(x=self.position_list[6], y=self.position_list[7]) else: self.set_position() def set_position(self): self.position_list.clear() for key in ["F1", "F2", "F3", "F4"]: # 模态对话框由Qt事件循环管理,不会阻塞界面 QMessageBox.information( self, f"设置{key}位置", "请将鼠标移动到目标位置,然后点击确定" ) pos = pyautogui.position() self.position_list.append(pos.x) self.position_list.append(pos.y) print("已保存位置:", self.position_list) if __name__ == "__main__": app = QApplication(sys.argv) win = Window_controller() win.show() sys.exit(app.exec())
关键修复点
- 移除死循环与第三方库依赖:改用Qt原生
QShortcut处理热键,完全适配Qt事件驱动模型,彻底解决界面阻塞问题。 - 分离热键激活状态:通过
toggle_hotkey_mode方法切换热键的启用/禁用状态,无需轮询检测。 - 修正属性作用域:将
Hotkey和position_list改为实例属性,避免多实例共享数据的问题。 - 优化位置设置逻辑:清空旧位置后重新设置,确保列表长度准确;模态对话框由Qt自动管理事件循环,不会导致假死。
内容的提问来源于stack exchange,提问作者Dylan
相关产品推荐
相关产品推荐

