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)
Другие вопросы по тегам