在Windows 10中,如果我從命令行('python ./pyqt_freeze_testcase.py')運行以下測試用例GUI應用程序,我會看到以下完全可重複的GUI凍結/掛起/無響應行爲;每次GUI變得無法響應時,我都可以通過在shell中鍵入任何鍵來「恢復原狀」。pyqt5 click in terminal會導致GUI凍結
更新:這似乎是觸發(並治癒)通過切換焦點 - 跟隨鼠標沒有提高窗口行爲;現在這個問題就變成了如何在focus-follow-mouse-without-raising被啓用時防止凍結。我爲該主題發佈了一個新問題:PyQt5 GUI freeze caused by Windows focus-follows-mouse
行爲與內置shell('cmd')和PowerShell相同。詳細的動作腳本和反應來說明凍結是在這篇文章的底部。如何防止凍結/確保GUI應用程序保持響應?
pyqt_freeze_testcase.py:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
# 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)
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")
def main():
app = QApplication(sys.argv)
w = MyWindow(app)
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
該GUI僅僅是一個具有lineedit和一個按鈕(與信號/槽)的對話框。
伴隨UI文件minimal_ui.py(從Qt設計和pyuic5):
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'minimal.ui'
#
# Created by: PyQt5 UI code generator 5.8.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.lineEdit = QtWidgets.QLineEdit(Dialog)
self.lineEdit.setGeometry(QtCore.QRect(120, 90, 113, 22))
self.lineEdit.setObjectName("lineEdit")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(130, 150, 93, 28))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Dialog)
self.pushButton.clicked.connect(Dialog.showMsg)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "PushButton"))
的具體行動和響應,從一個新的PowerShell開始:
- 蟒蛇./pyqt_freeze_testcase.py
- 移動GUI窗口,使其位於PowerShell的旁邊(不在其內部)理由是明顯低於
- 左鍵單擊lineedit並鍵入一些東西 - >說的東西顯示出來的lineedit,如預期
- 左鍵單擊按鈕 - 「真的嗎?」>的QMessageBox提示出現在任何地方
- 左鍵在PowerShell中 - > PowerShell的上升,這會掩蓋GUI應用程序,也就是上面
- 左單擊「是」或步驟2的原因「不」 - - >消息框關閉,但是在shell中沒有顯示輸出,並且GUI沒有響應(它很快得到了微調器/沙漏,橫幅上顯示'Dialog(Not Responding)'',你不能選擇lineedit鍵入更多的東西,然後點擊按鈕不做任何事,所有出場的GUI被凍結,但:
- 左鍵在PowerShell中
- 按任意鍵 任何地方 - >期望的響應(yep或nope)出現在shell中,並且GUI現在再次響應,即您可以從第3步開始重複所有這些;還要注意的是,你可以在凍結期間所做的任何其他類型將會出現在lineedit
確實幫助我找到更直接的原因。我忘記了我使用了X-Mouse來模仿linux焦點 - 跟隨 - 鼠標 - 沒有提高窗口行爲(有幾個不同的東西叫做X-Mouse--這是來自https:// joelpurra的東西的.com /項目/ X-Mouse_Controls /)。把它關掉固定它,即凍結行爲消失,點擊終端不會改變任何東西。所以我嘗試了https://sinewalker.wordpress.com/2010/03/10/ms-windows-focus-follows-mouse-registry-hacks/中類似的註冊表模塊 - 他們仍然在Windows 10上工作 - 並且觸發器它! –
(續評) - 所以X-Mouse可能只是做同樣的註冊表項。沒有他們,就沒有凍結;跟他們;我得到了上述的凍結行爲。 –
因此,如果有人能夠嘗試重現這一點,那將是非常棒的!無論如何,我會提出一個新的問題,因爲範圍發生了很大變化。謝謝! –