2017-10-18 165 views
0

當我按下按鈕時,會耗費一些耗時的代碼。在運行時,我想避免該按鈕響應任何進一步的點擊。代碼完成後,該按鈕可以重新啓用,並且應該處理更多的點擊。pyqt:如何禁用QPushButton的多次點擊?

我試圖做到這一點使用:

self.btn.blockSignals(True) 
    self.btn.setEnabled(False) 
    ... code ... 
    self.btn.blockSignals(True) 
    self.btn.setEnabled(False) 

但儘管如此,如果我迅速點擊該按鈕10次,該代碼就會被執行10次......

在現實中我d將耗時的代碼移動到另一個線程。 (編輯:但仍是問題是相同的 - 我想??在現實中,解決它,請參閱accepted answer。)

如何封鎖或忽略一些點擊按鈕的時候,某個正在運行?

這裏是我的代碼最低版本:

import time 
import sys 
from PyQt4 import QtGui 

class Example(QtGui.QWidget): 

    def __init__(self): 
     super(Example, self).__init__() 
     self.initUI() 

    def initUI(self): 
     grid = QtGui.QGridLayout() 
     self.setLayout(grid) 
     self.btn = QtGui.QPushButton('Count') 
     grid.addWidget(self.btn, 1, 1) 
     self.txt1 = QtGui.QTextEdit() 
     grid.addWidget(self.txt1, 1, 2) 
     self.btn.clicked.connect(self.click) 
     self.count = 0 
     self.show() 

    def click(self): 
     # Here I want to block any further click in the button, but it is 
     # not working - clicking it 10 times quickly will run this 10 times... 
     self.btn.blockSignals(True) 
     self.btn.setEnabled(False) 
     time.sleep(2) # time consuming code... 
     self.count += 1 
     self.txt1.append(str(self.count)) 
     self.repaint() 
     self.btn.setEnabled(True) 
     self.btn.blockSignals(False) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 
+0

我不熟悉PyQt的,但我發現下面的鏈接: [鏈接](https://stackoverflow.com/questions/14087066/disabling -qpushbutton-before-a-task) 也許你必須在'self.btn.setEnabled(False)'下添加'QCoreApplication :: processEvents()'。 – Spezi94

+0

在我的系統上,'processEvents'不起作用,但是一個線程可以。 – ekhumoro

+0

@ekhumoro你的意思是將代碼移動到一個新的線程?那麼應該將blockSignals(False)移到該線程呢? – Raf

回答

1

如果你把長捉迷藏代碼在一個線程,一旦線程啓動控制可以返回到主事件循環,這將使gui立即更新。

這是基於你的例子一個基本的演示:

import sys 
from PyQt4 import QtGui, QtCore 

class Thread(QtCore.QThread): 
    def run(self): 
     QtCore.QThread.sleep(2) 

class Example(QtGui.QWidget): 
    def __init__(self): 
     super(Example, self).__init__() 
     self.initUI() 

    def initUI(self): 
     grid = QtGui.QGridLayout() 
     self.setLayout(grid) 
     self.btn = QtGui.QPushButton('Count') 
     grid.addWidget(self.btn, 1, 1) 
     self.txt1 = QtGui.QTextEdit() 
     grid.addWidget(self.txt1, 1, 2) 
     self.btn.clicked.connect(self.click) 
     self.thread = Thread() 
     self.thread.finished.connect(lambda: self.btn.setEnabled(True)) 
     self.show() 

    def click(self): 
     self.txt1.append('click') 
     if not self.thread.isRunning(): 
      self.btn.setEnabled(False) 
      self.thread.start() 

if __name__ == '__main__': 

    app = QtGui.QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 
+0

輝煌,謝謝!我錯過了這個重要的概念:不要用耗時的任務阻塞主事件循環。 – Raf