2017-10-18 167 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