Skip to main content
 首页 » 编程设计

python之与 PyQt 中的 QLabel 并发

2025年05月04日8sharpest

我有一个 python 应用程序,它使用 PyQt GUI。它的应用程序有一些 I/O 操作,我想在单独的线程中运行。 当每个 线程启动时,它应该将消息写入应用程序主窗口状态栏,当最后一个 线程完成时,状态栏消息应该被清除。 我如何通过 QThread 处理线程数?

代码示例:

import sys, time 
from PyQt4 import QtCore, QtGui 
from functools import partial 
 
 
def io_emulator(sleep_seconds): 
    print 'We will sleep for %s seconds' % str(sleep_seconds) 
    time.sleep(sleep_seconds) 
 
 
class IOThread(QtCore.QThread): 
    def __init__(self, func): 
        QtCore.QThread.__init__(self) 
        self.io_func = func 
 
    def run(self): 
        self.io_func() 
 
 
class m_Window(QtGui.QWidget): 
    def __init__(self): 
        super(m_Window, self).__init__() 
 
        self.initUI() 
 
    def initUI(self): 
        self.thread_button = QtGui.QPushButton("Thread", self) 
        self.thread_button.move(30, 10) 
        self.spinbox = QtGui.QSpinBox(self) 
        self.spinbox.move(30, 50) 
        self.stat_label = QtGui.QLabel("", self) 
        self.stat_label.setGeometry(QtCore.QRect(200, 200, 150, 14)) 
        self.stat_label.move(30,90) 
 
        self.setWindowTitle('Threads') 
        self.show() 
 
        self.thread_button.clicked.connect(self._sleeper) 
 
    def _sleeper(self): 
        seconds = int(self.spinbox.text()) 
        stat_str = 'Sleeping %s seconds' % str(seconds) 
 
        io_func = partial(io_emulator, seconds) 
        set_status_f = partial(self.set_status_msg, stat_str) 
 
        self.thread =  IOThread(io_func) 
        self.thread.started.connect(set_status_f) 
        self.thread.finished.connect(self.clear_status_msg) 
 
        self.thread.start() 
 
    def set_status_msg(self, msg): 
        self.stat_label.setText(msg) 
 
    def clear_status_msg(self): 
        self.stat_label.clear() 
 
 
def main(): 
    app = QtGui.QApplication(sys.argv) 
    m = m_Window() 
    sys.exit(app.exec_()) 
 
 
if __name__ == '__main__': 
    main() 

我想,只有在最后一个线程结束时才会清除该消息。

请您参考如下方法:

除主线程外,您不能从任何线程调用 QWidget 函数。如果你想让另一个线程触发 GUI 操作,那么它们应该通过发射连接到你的主线程的信号来通信:

def someFunc(): 
    return "message" 
 
class IOThread(QtCore.QThread): 
 
    statusUpdate = QtCore.pyqtSignal(str) 
 
    def __init__(self, func): 
        QtCore.QThread.__init__(self) 
        self.io_func = func 
 
    def run(self): 
        msg = self.io_func() 
        self.statusUpdate.emit(msg) 

然后在您的主线程中,将 io 线程连接到状态标签或某个中间处理程序:

io_thread = IOThread(someFunc) 
io_thread.statusUpdate.connect(self.status_label.setText) 

这将创建一个排队连接,将调用放入主线程的事件循环中执行。