pyqt:如何禁用 QPushButton 的多次点击?
pyqt: how to disable multiple clicks for QPushButton?
当我按下按钮时,会运行一些耗时的代码。虽然它是 运行,但我想避免按钮响应任何进一步的点击。代码完成后,可以重新启用该按钮并处理进一步的点击。
我正在尝试使用:
self.btn.blockSignals(True)
self.btn.setEnabled(False)
... code ...
self.btn.blockSignals(True)
self.btn.setEnabled(False)
但是,如果我快速点击这个按钮 10 次,代码将被执行 10 次...
实际上我会把耗时的代码移到另一个线程。 (编辑:但问题仍然相同 - 我认为??。 实际上解决了它。参见 。)
如何在 运行 时阻止或忽略对按钮的点击?
这是我的代码的最小版本:
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_())
如果将长时间运行的代码放在线程中,一旦线程启动,控制可以return到主事件循环,这将允许 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_())
当我按下按钮时,会运行一些耗时的代码。虽然它是 运行,但我想避免按钮响应任何进一步的点击。代码完成后,可以重新启用该按钮并处理进一步的点击。
我正在尝试使用:
self.btn.blockSignals(True)
self.btn.setEnabled(False)
... code ...
self.btn.blockSignals(True)
self.btn.setEnabled(False)
但是,如果我快速点击这个按钮 10 次,代码将被执行 10 次...
实际上我会把耗时的代码移到另一个线程。 (编辑:但问题仍然相同 - 我认为??。 实际上解决了它。参见
如何在 运行 时阻止或忽略对按钮的点击?
这是我的代码的最小版本:
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_())
如果将长时间运行的代码放在线程中,一旦线程启动,控制可以return到主事件循环,这将允许 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_())