如何从python中的GUI停止线程?

时间:2015-02-22 02:15:19

标签: python multithreading user-interface selenium-webdriver pyqt

gui有一个启动按钮,可以在一个线程中启动一个刮刀,以便gui可以更新其结果。如何让我的停止按钮停止刮线?

class Scrape:
    def __init__(self):
        #commence scraping the web

class Gui:

    def __init__(self):
        super(Gui, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        #events
        self.ui.start.clicked.connect(self.start_scraper)
        self.ui.stop.clicked.connect(self.stop_scraper)

    def start_scraper(self):
        self.browse = threading.Thread(target=Scrape)

    def stop_bot(self) -> None:
        raise SystemExit

1 个答案:

答案 0 :(得分:0)

对于我自己,我更喜欢以下方式,使用Queue作为跨线程通信的通道,它是线程安全且易于使用的。这都是异步通信。

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from Queue import Queue
from datetime import datetime


class MyThread(QThread):

    STOP_JOB_FLAG = None

    signal_thread_stop = pyqtSignal()

    def __init__(self, parent=None):
        super(MyThread, self).__init__(parent)
        self.mQueue = Queue()

    def startRun(self):
        if not self.isRunning():
            self.start()
            self.mQueue.put(datetime.now())
        else:
            self.mQueue.put(datetime.now())
            return

    def stopRun(self):
        if not self.isRunning():
            return
        else:
            self.mQueue.put(MyThread.STOP_JOB_FLAG)

    def run(self):
        while True:
            job = self.mQueue.get()
            if not job:
                qDebug("Thread run got None flag, will quit")
                self.signal_thread_stop.emit()
                break
            else:
                print "run " + str(job)
            self.mQueue.task_done()


class MyWidget(QWidget):
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)
        self.mLayout = QHBoxLayout(self)
        self.mStartBtn = QToolButton(self)
        self.mStopBtn = QToolButton(self)
        self.mStartBtn.setText("start")
        self.mStopBtn.setText("stop")
        self.setLayout(self.mLayout)
        self.mLayout.addWidget(self.mStartBtn)
        self.mLayout.addWidget(self.mStopBtn)
        self.mWorkerThread = MyThread()
        self.mStartBtn.released.connect(self.mWorkerThread.startRun)
        self.mStopBtn.released.connect(self.mWorkerThread.stopRun)
        self.mWorkerThread.signal_thread_stop.connect(self.handleRunFinished)

    def handleRunFinished(self):
        qDebug("handleRunFinished thread finished")

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    w = MyWidget()
    w.show()
    app.exec_()