I am a beginner at UI development using PySide6, but due to certain circumstances, I have to design a UI for a program that I have created. In one of the windows of this UI, I have a QObject called worker, which executes a long-running process. I defined the UI for the worker separately in a class called CLD. Here is my init:
class CLD(QWidget):
back_signal = Signal()
def __init__(self, question,threshold = 0.85, verbose = True):
super(CLD, self).__init__()
self.question = question
self.threshold = threshold
self.verbose = verbose
self.setWindowTitle("CLD Generator")
self.input_area = QTextEdit(self)
self.input_area.setMinimumHeight(50)
self.input_area.setMaximumHeight(100)
self.input_area.setReadOnly(True)
self.display_area = QTextEdit(self)
self.display_area.setMinimumHeight(200)
self.display_area.setReadOnly(True)
self.user_input = ""
self.init_ui()
self.worker = Worker(self, self.question, self.threshold, self.verbose)
self.thread = QThread()
self.worker.moveToThread(self.thread)
self.worker.finished.connect(self.on_finished)
self.worker.update_text.connect(self.display_area.append)
self.worker.get_choice.connect(self.enter_choice)
self.thread.started.connect(self.worker.generate)
self.mutex = QMutex()
self.condition = QWaitCondition()
As you can see, I'm moving the worker to a QThread that I am defining in the CLD class itself. The long-running process is a function in the worker class called generate(). I want to define a "Back" button in the CLD class which when pressed, will abort the execution of the long-running process, and return to the previous window. To that end, I have defined a function like this:
@Slot(str)
def on_finished(self, response):
self.display_area.append(response)
self.run_button.setEnabled(True)
self.thread.quit()
self.thread.wait()
The issue is, when I try to quit(), the thread/long-running process doesn't actually quit. When I use thread.wait(), the UI freezes completely, and no matter how long I wait, it stays the same. When I close the UI by force, I get this error "QThread: Destroyed while thread is still running" which clearly means that the thread wasn't quitting at all. I am thinking that I am doing something wrong here. Maybe the QThread is connected to the main UI so that when I call quit() it doesn't actually quit because the UI is still running? Any advice would be highly appreciated.
Currently in the code, back_signal (which is supposed to be emitted when back button is pressed) is not connected to on_finished(), because I was testing out several things, but under normal circumstances it is connected to on_finished()
I solved this issue by abandoning QThreads altogether. I instead used
threadingmodule from python to raise an exception in the worker thread. I ensured that I used a separate thread (let's call it monitor thread) to raise the exception. As soon as the Back button is clicked, it emits a signal to the monitor thread which immediately raises an exception in the worker thread. I then callthread.join()to wait for it to terminate. This process is significantly faster than simply callingQThreads.quit()andQThreads.wait(). I am not sure why this is so. If anyone can elaborate on this and validate my approach I would be grateful!