Reputation: 17
I am running a long process with QThread. In this process I send a signal to a slot. I want that slot to update a QLabel with setText(). I have ensured that my QThread process is on a separate thread and my message_updater function is on Main thread.
setText() is updating the text of the label, but it is not showing on the GUI. What am I doing wrong?
main.py
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from run_worker_thread import RunWorkerThread
from return_message_label import ReturnMessage
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PaGWIS")
self.setMinimumSize(800, 400)
layout = QVBoxLayout()
widgets = [
RunWorkerThread,
ReturnMessage
]
for w in widgets:
layout.addWidget(w())
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
worker_thread.py
from PySide6.QtCore import QThread, Signal
import time
import threading
class WorkerThread(QThread):
update_progress = Signal(str)
def run(self):
count = 0
while count < 10000:
count += 1
print(f'worker: {count}')
self.update_progress.emit(f'{count}')
print(f'worker thread: {threading.current_thread()}')
time.sleep(1)
run_worker_thread.py
from PySide6.QtWidgets import QWidget, QHBoxLayout, QPushButton
from worker_thread import WorkerThread
from return_message_label import ReturnMessage
class RunWorkerThread(QWidget):
def __init__(self):
super(RunWorkerThread, self).__init__()
self.rm = ReturnMessage()
self.worker = WorkerThread()
self.layout = QHBoxLayout()
self.layout.setContentsMargins(10, 10, 10, 10)
self.layout.setSpacing(20)
btn = QPushButton('Process Data')
btn.clicked.connect(self.processData)
self.layout.addWidget(btn)
self.setLayout(self.layout)
def processData(self):
self.worker.start()
self.worker.update_progress.connect(self.rm.message_updater)
return_message_label.py
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel
from PySide6.QtCore import Slot
import threading
class ReturnMessage(QWidget):
def __init__(self):
super(ReturnMessage, self).__init__()
self.initUI()
def initUI(self):
self.layout = QVBoxLayout()
self.layout.setContentsMargins(10, 10, 10, 10)
self.layout.setSpacing(10)
self.label1 = QLabel("python")
self.layout.addWidget(self.label1)
self.setLayout(self.layout)
@Slot(str)
def message_updater(self, msg):
print(f'return msg thread: {threading.current_thread()}')
print(f'msg_updater: {msg}')
self.label1.setText(f'{msg}')
I've attempted to update the GUI the problem with: repaint(), update(), QApplication.ProcessEvents(). none of these worked
Upvotes: 0
Views: 133
Reputation: 17
Special thanks to @musicamante who led me in the write path. Below is the solution to the dilemma:
main.py:
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLabel, QPushButton
from PySide6.QtCore import Slot
from return_message_label import ReturnMessage
from worker_thread import WorkerThread
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.worker = WorkerThread()
self.rm = ReturnMessage()
self.setWindowTitle("Title")
self.setMinimumSize(800, 400)
self.layout = QVBoxLayout()
self.layout.setContentsMargins(10, 10, 10, 10)
self.layout.setSpacing(20)
self.btn = QPushButton('Process Data')
self.btn.clicked.connect(self.processData)
self.layout.addWidget(self.btn)
self.layout.addWidget(self.rm)
widget = QWidget()
widget.setLayout(self.layout)
self.setCentralWidget(widget)
def processData(self):
self.worker.start()
self.worker.update_progress.connect(self.rm.message_updater)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
worker_thread.py:
from PySide6.QtCore import QThread, Signal
import time
import threading
class WorkerThread(QThread):
update_progress = Signal(str)
def run(self):
count = 0
while count < 10000:
count += 1
print(f'worker: {count}')
self.update_progress.emit(f'{count}')
print(f'worker thread: {threading.current_thread()}')
time.sleep(1)
return_message_label.py:
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel
from PySide6.QtCore import Slot
import threading
class ReturnMessage(QWidget):
def __init__(self):
super(ReturnMessage, self).__init__()
self.initUI()
def initUI(self):
self.layout = QVBoxLayout()
self.layout.setContentsMargins(10, 10, 10, 10)
self.layout.setSpacing(10)
self.label1 = QLabel("python")
self.layout.addWidget(self.label1)
self.setLayout(self.layout)
@Slot(str)
def message_updater(self, msg):
print(f'return msg thread: {threading.current_thread()}')
print(f'msg_updater: {msg}')
self.label1.setText(f'{msg}')
Upvotes: 0