2013-01-07 47 views
2

我有我的python應用程序,它使用PyQt GUI。它的應用程序有一些I/O操作,我想在單獨的線程中運行。 當各自線程啓動時,它應該將消息寫入應用程序主窗口狀態欄,並且當線程完成時,狀態欄消息應該被清除。 我如何處理通過QThread的線程數量?並行QLabel在PyQt

這裏是例子的代碼:

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() 

我想,只有當最後一個線程結束該消息被清除。

回答

1

您不能從除主線程之外的任何線程調用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) 

這將創建一個排隊連接,該連接將調用放入主線程的事件循環中以供執行。

+0

如果最後一個線程結束了,我該如何處理?我的程序版本,第一個線程可以清除最後一個線程的消息。 –

+0

線程有一個「完成()」信號。將它們全部連接到使用計數器的插槽,以瞭解最後一次完成的時間。你的線程應該沒有彼此的知識,或者使用qwidget調用 – jdi