class CustomThread(QThread):
def __init__(self, target, args=()):
super().__init__()
self.__target = target
self.__args = args
def run(self):
self.__target(*self.__args)
class MyClass:
def target(self):
print("Hello world")
# Do something
def func(self):
thread = CustomThread(self.target)
thread.start()
在这种情况下,如果我调用MyClass的func(),则程序崩溃,表明qthread在运行时已被破坏。 (因为线程是局部变量) 因此,我将线程更改为self.thread,使其成为MyClass的成员变量,这样它就不会被破坏。
class CustomThread(QThread):
def __init__(self, target, args=()):
super().__init__()
self.__target = target
self.__args = args
def run(self):
self.__target(*self.__args)
class MyClass:
def target(self):
print("Hello world")
# Do something
def func(self):
self.thread = CustomThread(self.target)
self.thread.start()
但是,如果我两次或更多次调用func(),运行中的线程可能会被垃圾回收,并且程序将崩溃。 因此,我尝试通过添加列表并附加每个线程来解决此问题。
class CustomThread(QThread):
def __init__(self, target, args=()):
super().__init__()
self.__target = target
self.__args = args
def run(self):
self.__target(*self.__args)
class MyClass:
def __init__(self):
self.threads = []
def target(self):
print("Hello world")
# Do something
def func(self):
self.thread = CustomThread(self.target)
self.threads.append(self.thread)
self.thread.start()
这解决了问题,但看起来效率低下且不成熟。 另外,我必须弹出每个完成任务的线程。 (也许我必须用信号和插槽来实现它,当然看起来有些多余)
如何更好地解决这个问题?
答案 0 :(得分:1)
您的方法很好,但是由于线程需要定期检查以查看其是否完整,因此列表线程的维护可能很繁琐。幸运的是,QThread
有一个finished
信号,当线程完成时从Qt循环调用该信号。将您的线程列表更改为字典,然后使用唯一的线程ID标识退出的线程,将此信号连接到插槽以进行清理。
import time
class CustomThread(QThread):
def __init__(self, target, callback, args=()):
super().__init__()
self.callback = callback
self.__target = target
self.__args = args
self.finished.connect(lambda: self.callitback)
def run(self):
self.__target(*self.__args)
def callitback(self):
self.callback()
class MyClass:
def __init__(self):
self.threads = {}
def target(self):
print("Hello world")
# Do something
def threadFinished(self, threadId):
self.threads.pop(threadId, None)
def func(self):
threadId = time.time()
thread = CustomThread(self.target, lambda tid=threadId: self.threadFinished(tid))
self.threads[threadId] = thread
thread.start()