2016-09-09 23 views
2

我遇到了這個問題,並試圖將其分解爲我能想象到的最簡單的代碼:我使用Qt Designer V4.8.7創建了一個GUI,它只包含一個具有所有默認設置的pushButton 。它被稱爲'Test2.ui'。按下該按鈕時,應該禁用該按鈕,在終端中打印某些內容,然後再次啓用。會發生什麼,我可以點擊禁用的pushButton,它會重複所有打印次數。當我將按鈕設置爲不可見而不是禁用它時,這甚至可以工作。我在網上發現了類似的問題,但沒有一個解決方案似乎適用於我 - 這讓我很生氣。任何人有想法?PyQT:PushButton在禁用時接收命令

from __future__ import division, print_function 
import sys 
from PyQt4 import QtCore, QtGui, uic 
from PyQt4.QtCore import QTimer 
from time import sleep 

qtCreatorFile = "Test2.ui" # Enter file here. 

Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile) 


class MyApp(QtGui.QMainWindow, Ui_MainWindow): 

    def __init__(self): 
     QtGui.QMainWindow.__init__(self) 
     Ui_MainWindow.__init__(self) 
     self.setupUi(self) 
     self.pushButton.pressed.connect(self.Test_Function) 


    def Test_Function(self): 
     self.pushButton.setEnabled(False) 
     QtGui.QApplication.processEvents() 
     print('Test 1') 
     sleep(1) 
     print('Test 2') 
     sleep(1) 
     self.pushButton.setEnabled(True) 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    window = MyApp() 
    window.show() 
    sys.exit(app.exec_()) 

這裏是「Test2.ui」

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>MainWindow</class> 
<widget class="QMainWindow" name="MainWindow"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>445</width> 
    <height>393</height> 
    </rect> 
    </property> 
    <property name="mouseTracking"> 
    <bool>false</bool> 
    </property> 
    <property name="focusPolicy"> 
    <enum>Qt::ClickFocus</enum> 
    </property> 
    <property name="acceptDrops"> 
    <bool>false</bool> 
    </property> 
    <property name="windowTitle"> 
    <string>MainWindow</string> 
    </property> 
    <widget class="QWidget" name="centralwidget"> 
    <widget class="QPushButton" name="pushButton"> 
    <property name="enabled"> 
    <bool>true</bool> 
    </property> 
    <property name="geometry"> 
    <rect> 
     <x>160</x> 
     <y>150</y> 
     <width>75</width> 
     <height>23</height> 
    </rect> 
    </property> 
    <property name="text"> 
    <string>Test</string> 
    </property> 
    </widget> 
    </widget> 
    <widget class="QMenuBar" name="menubar"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>445</width> 
    <height>22</height> 
    </rect> 
    </property> 
    </widget> 
    <widget class="QStatusBar" name="statusbar"/> 
</widget> 
<resources/> 
<connections/> 
</ui> 
+0

這可能不是python:但是在C++中Qt這是故意的:http://doc.qt.io/qt- 5/qabstractbutton.html啓用的按鈕仍然會收到鼠標事件。你應該檢查python文檔。似乎你需要檢查按鈕是否在你的點擊處理程序中啓用。 – Hayt

+0

您能否提供'Test2.ui'的代碼?這將使測試更容易。 – Ian

+0

我添加了.ui文件的代碼。使用.setDown替換.setEnabled命令導致相同的問題。 – Delf

回答

1

你的示例代碼將無法工作,因爲測試的功能塊的圖形用戶界面的代碼。當它被阻塞時,按鈕的禁用狀態沒有被正確更新,因此clicked信號仍然可以被髮射。避免阻塞gui的最好方法是在單獨的線程中完成這項工作:

class Worker(QtCore.QObject): 
    finished = QtCore.pyqtSignal() 

    def run(self): 
     print('Test 1') 
     sleep(1) 
     print('Test 2') 
     sleep(1) 
     self.finished.emit() 

class MyApp(QtGui.QMainWindow, Ui_MainWindow): 
    def __init__(self): 
     ... 

     self.pushButton.pressed.connect(self.handleButton) 

     self.thread = QtCore.QThread(self) 
     self.worker = Worker() 
     self.worker.moveToThread(self.thread) 
     self.worker.finished.connect(self.handleFinished) 
     self.thread.started.connect(self.worker.run) 

    def handleButton(self): 
     self.pushButton.setEnabled(False) 
     self.thread.start() 

    def handleFinished(self): 
     self.thread.quit() 
     self.thread.wait() 
     self.pushButton.setEnabled(True) 
+0

非常感謝。我無法在兩天內弄清楚這一點! – Delf

+0

倒數第二行'self.thread.wait()'有什麼意義? – Delf

+0

@Delf。調用'quit()'告訴線程退出它的事件循環,但只有在沒有任何阻塞的情況下才會發生。所以有必要「wait()」,直到控制權返回到事件循環中,以確定線程已經完成。不要因爲在這個例子中似乎沒有任何作用而被誘惑離開它 - 總的來說,它總是需要的。 – ekhumoro