关于python:pyqt:如何禁用QPushButton的多次单击?

pyqt: how to disable multiple clicks for QPushButton?

按下按钮时,将运行一些耗时的代码。在运行时,我要避免该按钮响应任何进一步的单击。代码完成后,可以重新启用该按钮,并应处理其他单击。

我正在尝试使用以下方法:

1
2
3
4
5
   self.btn.blockSignals(True)
   self.btn.setEnabled(False)
   ... code ...
   self.btn.blockSignals(True)
   self.btn.setEnabled(False)

但是,即使我快速单击此按钮10次,代码也将执行10次...

实际上,我会将耗时的代码移到另一个线程。 (编辑:,但问题仍然相同-我认为??。实际上可以解决。请参见已接受的答案。)

当某些内容正在运行时,如何阻止或忽略对按钮的点击?

这是我的代码的最低版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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_())


如果将长时间运行的代码放在线程中,则一旦线程启动,控件就可以返回到主事件循环,这将允许gui立即更新。

这是基于您的示例的基本演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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_())