PyQT: PushButton получает команды, пока отключен
Я столкнулся с этой проблемой и попытался разобрать ее до простейшего кода, который я мог себе представить: я создал графический интерфейс с использованием Qt Designer V4.8.7, который состоит только из одной кнопки со всеми настройками по умолчанию. Это называется "Test2.ui". Когда кнопка нажата, она должна быть отключена, распечатать что-то в терминале, а затем снова включается. Что происходит, так это то, что я могу нажать на отключенную кнопку, и она будет повторять всю печать столько раз, сколько я нажал. Это работает даже тогда, когда я устанавливаю кнопку невидимой, а не отключаю ее. Я обнаружил похожие проблемы в Интернете, но ни одно из решений, похоже, не работает для меня - это сводит меня с ума. У кого-нибудь есть идея?
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>
1 ответ
Ваш пример кода не будет работать, потому что тестовая функция блокирует графический интерфейс. Пока она блокируется, отключенное состояние кнопки не обновляется должным образом, и поэтому clicked
сигнал все еще может излучаться. Лучший способ избежать блокировки графического интерфейса - выполнить работу в отдельном потоке:
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)