In my application QPushButton
starts calculation which takes variable time to finish (from few milliseconds to few seconds). The same QPushButton
can be used to stop calculation.
QPushButton
is checkable. When QPushButton
is pressed the QPushButton
state is checked and when calculation finish the QPushButton
automatically switches state to unchecked.
But when calculation takes few milliseconds QPushButton
stays in checked state after calculation is finished. When calculation takes more than 100 milliseconds everything works as expected.
I suspect that there is race condition between events but couldn't figure it out.
Minimal reproducible example (the sleep represents duration of calculation):
import sys
import threading
from time import sleep
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtCore import QThread
from PyQt5.QtCore import pyqtSignal
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.button = QPushButton("Run")
self.button.setCheckable(True)
self.setCentralWidget(self.button)
self.calculation_status = CalculationStatus()
self.button.pressed.connect(self.button_clicked)
self.calculation_status.finished.connect(self.on_calculation_finished)
def button_clicked(self):
if self.button.isChecked():
self.button.setText('Run')
else:
self.button.setText('Stop running')
threading.Thread(target=self.run, daemon=True).start()
def run(self):
sleep(0.001)
self.calculation_status.finished.emit()
def on_calculation_finished(self):
self.button.setChecked(False)
self.button.setText('Run')
class CalculationStatus(QThread):
finished = pyqtSignal()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())