我正在使用 QThread 运行一个长进程。在此过程中,我向插槽发送信号。我希望该插槽使用 setText() 更新 QLabel。我已确保我的 QThread 进程位于单独的线程上,并且我的 message_updater 函数位于主线程上。
setText() 正在更新标签的文本,但它没有显示在 GUI 上。我做错了什么?
主.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)
返回消息标签.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}')
我尝试使用以下方法更新 GUI:repaint()、update()、QApplication.ProcessEvents()。这些都不起作用
特别感谢@musicamante带领我走上了写作之路。以下是解决困境的方法:
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}')