由Windows焦点跟随鼠标

时间:2017-06-30 04:11:07

标签: pyqt focus freeze

当Windows焦点跟随 - 鼠标 - 没有提升 - 窗口通过链接到下面的两种方法之一启用时,我一直得到PyQt5 GUI'冻结'你必须在你运行python的终端中键入任何字符才能解冻GUI;完整的描述和测试用例(Windows 10,Python 3.6.1,PyQt5)在这里:pyqt5 click in terminal causes GUI freeze

要启用focus-follow-mouse-without-raise行为,请尝试其中任何一种 - 它们都适用于Windows 10:

所以 - 几个问题:

  1. 任何人都可以重现这个问题吗?对我来说,这似乎是100%可重复的,但是从其他人那里听到同样的信息会很棒。
  2. 有没有办法改变python代码以检测并绕过焦点跟随鼠标,或者只是为了免疫它,即可能确保GUI应用程序总是在你重新聚焦时 - 例如 - 单击主GUI窗口拥有的对话框或qmessagebox,还是通过其他方式? (对象层次结构是否设置为最佳,如果不是,可能通过更正所有权结构来解决这个问题?)

1 个答案:

答案 0 :(得分:0)

蛮力解决方案似乎有效,但我想留下这个问题,看看是否有人知道更优化的解决方案;需要花费大量的时间来找出正确的方法;主要是看一下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()