【发布时间】:2023-10-15 06:21:01
【问题描述】:
我希望在 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对象会将文件预加载到内存中,因此它的性能应该更高。
标签: python multithreading pyqt5 qthread