I'm creating an application with PyQt5, which has a very simple user interface. There is a dropdown list from which a value can be chosen, and then there is a button which can be clicked on and an action will be performed based on a current value in the dropdown list.
Currently if I run the code below, I can get a value from the dropdown list and it will be emitted to worker thread before myaction.myaction(customer_name)
is run. The code also runs fine, but the GUI is not working the way I want it to work while the function in worker thread runs. When I click on the start button, it should emit a signal to the GUI to disable the button, change its label and color, but that never happens. When the function finishes, it should be changed back to its original form.
Is the problem how I handle signals, or am I having redundant functions in my classes? What is the correct way to send that dropdown list value to worker thread everytime the button is clicked, so I can simply use it as a variable there?
Every possible solution to this I find online gets me excited but none of them have been working for me yet, or some of them have been too confusing for me to understand.
Here's some answers I've already gone through
#!/usr/bin/env python3
import sys
#import myaction
import time
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton, QComboBox, QLabel
from PyQt5 import QtCore
class ConfWorker(QtCore.QThread):
updated_button = QtCore.pyqtSignal(list)
updated_label = QtCore.pyqtSignal(str)
updated_error = QtCore.pyqtSignal(str)
request_signal = QtCore.pyqtSignal()
customer = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(ConfWorker, self).__init__(parent)
self.customer.connect(self.getcustomer)
def run(self):
self.request_signal.emit()
def getcustomer(self, text):
self.configure(text)
def configure(self, customer_name):
self.updated_button.emit(["In progress...", False])
self.updated_label.emit(customer_name)
time.sleep(5) # During this time you should be able to see color change etc.
#myaction.myaction(customer_name)# TAKES ~20 SECONDS TO FINISH
self.updated_button.emit(["Start", True])
class ConfGUI(QWidget):
def __init__(self, parent=None):
super(ConfGUI, self).__init__()
self.worker = ConfWorker(self)
self.worker.updated_button.connect(self.updateButton)
self.worker.updated_label.connect(self.updateLabel)
self.worker.updated_error.connect(self.updateError)
self.worker.request_signal.connect(self.sendCustomer)
self.targetBtn = QPushButton('Start Configuration', self)
self.targetBtn.setStyleSheet("QPushButton { background-color: green; color: white }"
"QPushButton:disabled { background-color: red; color: white }")
self.targetBtn.clicked.connect(self.worker.start)
self.targetBtn.setGeometry(100, 400, 200, 50)
self.setGeometry(800, 300, 400, 550)
self.setFixedSize(400, 550)
self.customerlist = QComboBox(self)
self.customerlist.setGeometry(100, 50, 200, 50)
self.customerlist.setObjectName("customer")
self.customerlist.addItem("testcustomer1")
self.customerlist.addItem("testcustomer2")
self.customerlist.addItem("testcustomer3")
self.label = QLabel(self)
self.label.setText("")
self.label.setStyleSheet('font-size: 30pt; font-family: Courier; color: green;')
self.label.setGeometry(70,250,400,50)
self.error_label = QLabel(self)
self.error_label.setText("")
self.error_label.setStyleSheet('font-size: 30pt; font-family: Courier; color: red;')
self.error_label.setGeometry(70,350,400,50)
self.show()
def sendCustomer(self):
self.worker.customer.emit(self.customerlist.currentText())
def updateButton(self, button_list):
self.targetBtn.setText(button_list[0])
self.targetBtn.setEnabled(button_list[1])
def updateLabel(self, label_text):
self.label.setText(label_text)
def updateError(self, error_text):
self.error_label.setText(error_text)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = ConfGUI()
sys.exit(app.exec_())