完成后如何自动退出PyQT QThread?
Posted
技术标签:
【中文标题】完成后如何自动退出PyQT QThread?【英文标题】:How to quit PyQT QThread automatically when it is done? 【发布时间】:2019-11-08 15:38:20 【问题描述】:我希望在 PyQT5 中单击按钮时播放声音。
播放声音似乎是一个阻塞操作,因此 GUI 没有响应。因此,我想以非阻塞方式启动一个新线程、播放声音和删除线程。
我创建了一个线程类
class playSoundThread(QtCore.QThread):
def __init__(self, soundpath):
QtCore.QThread.__init__(self)
self.soundpath = soundpath
def __del__(self):
self.wait()
print("Thread exited")
def run(self):
playsound(self.soundpath)
然后运行如下
class MainClass(...):
...
def playsound(self, soundKey):
self.thisSoundThread = playSoundThread(self.sounds[soundKey])
self.thisSoundThread.start()
一切正常且无阻塞。唯一的问题是当声音停止播放时线程不会被删除。我试过打电话给del self.thisSoundThread
,但是这个操作似乎是阻塞的,打不过。
以非阻塞方式完成后退出线程的正确方法是什么?
【问题讨论】:
您应该添加稍后运行的代码:self.thisSound.wait(); self.thisSound = None;
另外,您的类中不要有 __del__(self):
方法。
使用QSound。它非常简单,而且不需要多线程。
@ekhumoro 我可能会听从你的建议。我目前使用的pydub
似乎也有中途终止声音的问题,即使在我尝试删除线程后它们也会继续。尽管如此,它还是很欣赏了解线程的一点
@ekhumoro,抱歉回复晚了,我终于要试试了。 QSound 实际上似乎比多线程执行得更差,因为它在调用 QSound.play() 和实际结果之间至少有 1 秒的延迟,这很烦人。不知道如何解决它,关于这个主题的最新答案来自 2011 年。现在要坚持使用线程
@AleksejsFomins 对我来说(在 arch linux 上)声音会立即播放,没有明显的延迟。文档说创建QSound
对象并调用play()
插槽在某些系统上可能比使用静态函数更直接。然而,对我来说,它们都可以立即播放(即使是 40Mb 的 wav 文件)。我想在对大文件使用静态函数时,速度较慢的设备(例如网络驱动器或旧硬盘)可能会引入轻微的延迟。使用QSound
对象会将文件预加载到内存中,因此它的性能应该更高。
【参考方案1】:
为什么要删除它?我没有看到任何“del”调用,并且您将其分配给实例,因此 GC 也没有,因为仍然存在引用。
如果你想删除它,你必须这样做:
class MainClass(...):
...
def playsound(self, soundKey):
self.thisSoundThread = playSoundThread(self.sounds[soundKey])
self.thisSoundThread.finished.connect(self.threadfinished)
self.thisSoundThread.start()
def threadfinished(self)
del self.thisSoundThread
# or set it to None
【讨论】:
正如我所说,我确实尝试了del self.thisSoundThread
,但它被阻止了。我不知道finished
事件,它的话。所以谢谢:)以上是关于完成后如何自动退出PyQT QThread?的主要内容,如果未能解决你的问题,请参考以下文章