使用QTimer和QThread调度多线程任务

时间:2015-11-27 12:17:22

标签: python multithreading pyqt pyside qtimer

我正在使用PySide,需要定期安排特定任务。该任务将启动Popen子进程以在多个线程中调用非python可执行文件。我想检查这些线程是否正在运行,并在完成或终止任务后重复该任务。

class ControlMainWindow(QMainWindow):
def __init__(self):
    super(ControlMainWindow, self).__init__()
    self.systemTrayIcon = QSystemTrayIcon(self)
    self.systemTrayIcon.setIcon(QIcon("lib/data/icon.png"))
    self.systemTrayIcon.setVisible(True)
    self.systemTrayIcon.activated.connect(self.on_systemTrayIcon_activated)
    self.ui = Ui_Dialog()
    self.ui.setupUi(self)
    self.ui.pushButton.clicked.connect(self.start_thread)
    self.ui.pushButton_2.clicked.connect(self.stop_thread)


@Slot(QSystemTrayIcon.ActivationReason)
def on_systemTrayIcon_activated(self, reason):
    if reason == QSystemTrayIcon.DoubleClick:
        if self.isHidden():
            self.show()
        else:
            self.hide()

@Slot(str)
def append_text(self,text):
    ##self.ui.textedit.setHtml( text )
    self.ui.textedit.moveCursor(QTextCursor.End)
    self.ui.textedit.insertHtml( text )

def timerTask(self):
    try:
        stillWaiting = False
        for t in self.threads:    ## check if threads are running
            if t.isRunning:
                stillWaiting = True
                print t.currentThreadId()+' is running',
        if not stillWaiting:    ## if there are threads running, do nothing
            for i in range(self.n):    ## I need to run multiple threads in parallel
                self.threads.append(QThread())
                self.searches.append(LongRunningThing(self.argu1,self.argu2,self.n,i))
                self.searches[i].moveToThread(self.threads[i])
                self.threads[i].started.connect(self.searches[i].run)
                self.threads[i].setTerminationEnabled(True)
                self.threads[i].start()
    finally:    ## wait and check again
        QTimer.singleShot(15*1000, self.timerTask)

def start_thread(self):
    self.ui.pushButton.setEnabled(False)
    self.timerTask()

@Slot()
def stop_thread(self):
    for t in self.threads:
        t.terminate()

    print("Stop all threads.<br>")
    self.threads=[]
    self.searches=[]
    self.ui.pushButton.setEnabled(True)
    self.killAllProc()

def killAllProc(self):
    PROCNAME = "pythonw.exe"
    for proc in psutil.process_iter():
        if proc.name() == PROCNAME:
            proc.kill()

## ---------------- end of QMainWindow class

class LongRunningThing(QObject):
    def __init__(self,argu1,argu2,n,k,*args,**kwargs):
        QObject.__init__(self,*args,**kwargs)
        self.argu1= argu1
        self.argu1= argu2
        self.n = n
        self.k = k
    @Slot()
    def run(self):
        cmd = ## process with arguments
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

## --------------------- end of LongRunning class
if __name__ == '__main__':

app = QApplication(sys.argv)
win = ControlMainWindow()
win.show()

在调用singleShot以检查线程状态后,任务可以启动并崩溃。

崩溃信息:

Problem signature:
Problem Event Name: APPCRASH
Application Name:   pythonw.exe
Application Version:    0.0.0.0
Application Timestamp:  5560ad99
Fault Module Name:  python27.dll
Fault Module Version:   2.7.10150.1013
Fault Module Timestamp: 5560ad81
Exception Code: c0000005
Exception Offset:   0007b16f
OS Version: 6.1.7601.2.1.0.256.48
Locale ID:  1033

任何建议或提示都表示赞赏。

0 个答案:

没有答案