Reputation: 123
I'm writing a GUI app using PySide6 and QThread. I've two different QThread objects that run two long time run jobs, they can't overlap so if one thread is running, the second must wait until the first ends, how can obtain this?
I try to write a simple code example:
from PySide6.QtCore import QThread
from MyJobs import LongJob
job_a = LongJob()
job_b = LongJob()
thread_a = QThread()
thread_b = QThread()
job_a.moveToThread(thread_a)
job_b.moveToThread(thread_b)
thread_a.start()
thread_b.start() # if thread_a is running, thread_b must wait until thread_a ends, then run and viceversa
Upvotes: 0
Views: 1855
Reputation: 244291
Threads are workspaces and you instead want to manage how jobs are executed. In that case, task B must be managed to execute when task A finishes, and vice versa using signals.
import random
import time
from PySide6.QtCore import QCoreApplication, QObject, QThread, QTimer, Qt, Signal, Slot
class LongJob(QObject):
started = Signal()
finished = Signal()
@Slot()
def run_task(self):
assert QThread.currentThread() != QCoreApplication.instance().thread()
self.started.emit()
self.long_task()
self.finished.emit()
def long_task(self):
t = random.randint(4, 10)
print(f'identifier: {self.property("identifier")}, delay: {t} seconds')
for i in range(t):
time.sleep(1)
print(f"{i+1} seconds")
if __name__ == "__main__":
import sys
app = QCoreApplication(sys.argv)
job_a = LongJob()
job_a.setProperty("identifier", "job_a")
job_b = LongJob()
job_b.setProperty("identifier", "job_b")
thread_a = QThread()
thread_a.start()
job_a.moveToThread(thread_a)
thread_b = QThread()
thread_b.start()
job_b.moveToThread(thread_b)
job_a.finished.connect(job_b.run_task, Qt.QueuedConnection)
job_b.finished.connect(job_a.run_task, Qt.QueuedConnection)
# start task
QTimer.singleShot(0, job_a.run_task)
sys.exit(app.exec())
Upvotes: 2