2017-06-29 72 views
1

在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開始:

  1. 蟒蛇./pyqt_freeze_testcase.py
  2. 移動GUI窗口,使其位於PowerShell的旁邊(不在其內部)理由是明顯低於
  3. 左鍵單擊lineedit並鍵入一些東西 - >說的東西顯示出來的lineedit,如預期
  4. 左鍵單擊按鈕 - 「真的嗎?」>的QMessageBox提示出現在任何地方
  5. 左鍵在PowerShell中 - > PowerShell的上升,這會掩蓋GUI應用程序,也就是上面
  6. 左單擊「是」或步驟2的原因「不」 - - >消息框關閉,但是在shell中沒有顯示輸出,並且GUI沒有響應(它很快得到了微調器/沙漏,橫幅上顯示'Dialog(Not Responding)'',你不能選擇lineedit鍵入更多的東西,然後點擊按鈕不做任何事,所有出場的GUI被凍結,但:
  7. 左鍵在PowerShell中
  8. 按任意鍵 任何地方 - >期望的響應(yep或nope)出現在shell中,並且GUI現在再次響應,即您可以從第3步開始重複所有這些;還要注意的是,你可以在凍結期間所做的任何其他類型將會出現在lineedit

回答

0

這是作爲評論可能更好,但我沒有信譽點這樣做,一些反饋可能是更好爲你而不是。

我測試了你在Windows 10機器上用python3和python2.7所做的工作,我無法複製你在問題中列出的情況。一切按預期工作,並立即出現「nope」和「yep」消息。您可以嘗試如下所示:PySide/Python GUI freezes但打印語句不應凍結您的GUI並且不能在控制檯中打印。你一定要檢查一下像你這樣的其他一些簡單的圖形用戶界面來查看凍結和不凍結的內容。我會盡快重啓你的電腦。如果這不會導致任何答案,也許嘗試重新安裝PyQt5。

+0

確實幫助我找到更直接的原因。我忘記了我使用了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上工作 - 並且觸發器它! –

+0

(續評) - 所以X-Mouse可能只是做同樣的註冊表項。沒有他們,就沒有凍結;跟他們;我得到了上述的凍結行爲。 –

+0

因此,如果有人能夠嘗試重現這一點,那將是非常棒的!無論如何,我會提出一個新的問題,因爲範圍發生了很大變化。謝謝! –

0

蠻力解決方案正在解決上述問題(PyQt5 GUI freeze caused by Windows focus-follows-mouse);完整的代碼發佈在那裏。

希望有人能提供更優化或更「正確」的解決方案?

基本上,禁用主窗口中的活動窗口跟蹤init並恢復到其在MainWindow closeEvent中的初始設置。也許有一個更優化的解決方案,但是,這個解決方案短而可靠。從https://joelpurra.com/projects/X-Mouse_Controls/的方法立即生效,而註冊表黑客直到重新啓動才生效。