Vamshi Surabhi
Vamshi Surabhi

Reputation: 537

How to suspend the execution of a QThread upon a QPushButton press?

I'm writing a simple GUI for the Lights Out Board (Wiki) using PyQt4. The GUI has a 'Solve' Button which uses Iterative Deepening Depth First Search. This being time consuming, I spawn a new QThread to solve for the puzzle and update the board when it finishes while the GUI remains responsive. This I'm able to do.

But, I also have a 'Stop' Button which should stop the Search thread if it is currently running and I'm unable to stop the QThread using the exit(). Here's the code for the three functions.

class LightsOut(QWidget):
    def __init__(self, parent=None):
        # Whole other initialization stuff
        self.pbStart.clicked.connect(self.puzzleSolver) # The 'Start' Button
        self.pbStop.clicked.connect(self.searchStop) # The 'Stop' Button

    def searchStop(self):
        if self.searchThread.isRunning():
            self.searchThread.exit() # This isn't working
            self.tbLogWindow.append('Stopped the search !') # This is being printed
        else:
            self.tbLogWindow.append('Search is not running')

    def searchFinish(self):
        self.loBoard.setBoard() # Redraw the lights out board with solution

    def puzzleSolver(self):
        maxDepth = self.sbMaxDepth.value() # Get the depth from Spin Box
        self.searchThread = SearchThread(self.loBoard, self.tbLogWindow, maxDepth)
        self.searchThread.finished.connect(self.searchFinish)
        self.tbLogWindow.append('Search started')
        self.searchThread.start()

When I click the 'Stop' Button, in the Log Window (QTextBrowser), I can see 'Stopped the search' message, but my CPU is still running at 100% and when the search finishes, the solution is being displayed (searchFinish is being called). Obviously, I'm missing something very simple, and I haven't used terminate() as it is frowned upon in the documentation.

Upvotes: 0

Views: 886

Answers (1)

lukad
lukad

Reputation: 17863

Use terminate() instead of quit and call wait(). wait() will block until the QThread has finished.

Another thing you could do is to set a quit condition outside the thread which you will check for inside the thread (Probably the best solution). Additionally you can connect a slot to the finished signal.

Upvotes: 1

Related Questions