由 Windows 焦点跟随鼠标引起的 PyQt5 GUI 冻结



当通过下面链接的两种方法之一启用Windows焦点跟随鼠标而不抬起窗口时,我总是得到PyQt5 GUI"冻结",您必须在运行python的终端中键入任何字符才能解冻GUI; 完整的描述和测试用例(Windows 10,Python 3.6.1,PyQt5(在这里: pyqt5 在终端中单击导致 GUI 冻结

若要启用焦点跟随鼠标而不抬起行为,请尝试以下任一操作 - 它们在 Windows 10 中都有效:

  • 可下载的程序("X-Mouse",尽管该名称被其他程序使用(: https://joelpurra.com/projects/X-Mouse_Controls/
  • 注册表黑客说明: https://sinewalker.wordpress.com/2010/03/10/ms-windows-focus-follows-mouse-registry-hacks/

所以 - 几个问题:

  1. 任何人都可以重现该问题吗? 对我来说,这似乎是 100% 可重现的,但如果能从其他人那里听到同样的话,那就太好了。
  2. 有没有办法更改 Python 代码以检测和规避焦点跟随鼠标,或者只是对它免疫,即也许通过确保 GUI 应用程序始终在您 - 例如 - 单击主 GUI 窗口拥有的对话框或 qmessagebox 时再次收回焦点,或通过其他方式? (对象层次结构是否以最佳方式设置,如果没有,也许这一切都可以通过纠正所有权结构来解决?

蛮力解决方案似乎有效,尽管我想保留这个问题,看看是否有人知道更优化的解决方案; 花了相当多的搜索才能找出正确的方法; 主要是通过查看X-Mouse的开源代码。 基本上,此方法会立即生效,而注册表黑客直到重新启动才会生效。

新版本的pyqt_freeze_testcase.py(来自引用的stackoverflow问题的文件(;这些更改只是添加,在哈希标记行之间注明:

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
####################### added begin:
import win32gui
import win32con
####################### added end
# import the UI file created with pyuic5
from minimal_ui import Ui_Dialog
class MyWindow(QDialog,Ui_Dialog):
def __init__(self,parent):
QDialog.__init__(self)
self.parent=parent
self.ui=Ui_Dialog()
self.ui.setupUi(self)
################################# added begin:
self.initialWindowTracking=False
try:
self.initialWindowTracking=win32gui.SystemParametersInfo(win32con.SPI_GETACTIVEWINDOWTRACKING)
except:
pass
if self.initialWindowTracking:
print("Window Tracking was initially enabled.  Disabling it for now; will re-enable on exit.")
win32gui.SystemParametersInfo(win32con.SPI_SETACTIVEWINDOWTRACKING,False)
################################# added end
def showMsg(self):
self.really1=QMessageBox(QMessageBox.Warning,"Really?","Really do stuff?",
QMessageBox.Yes|QMessageBox.No,self,Qt.WindowTitleHint|Qt.WindowCloseButtonHint|Qt.Dialog|Qt.MSWindowsFixedSizeDialogHint|Qt.WindowStaysOnTopHint)
self.really1.show()
self.really1.raise_()
if self.really1.exec_()==QMessageBox.No:
print("nope")
return
print("yep")
################################## added begin:
def closeEvent(self,event):
if self.initialWindowTracking:
print("restoring initial window tracking behavior ("+str(self.initialWindowTracking)+")")
win32gui.SystemParametersInfo(win32con.SPI_SETACTIVEWINDOWTRACKING,self.initialWindowTracking)
################################## added end
def main():
app = QApplication(sys.argv)
w = MyWindow(app)
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

最新更新