Python:我的代码运行良好,但存在 GUI 冻结问题(使用 tkinter 和 sounddevice)
Python: my code works perfectly but there is a GUI freezing problem (using tkinter and sounddevice)
我有一个代码可以处理来自声音设备的音频数据。
我的代码通过 tkinter 构建 GUI,并在按下按钮时通过声音设备库处理音频数据。
当我 运行 代码时,它实际上工作得很好。但是,出现GUI冻结,无法点击按钮。
所以我尝试通过线程解决这个问题,但屡次失败
请检查我的代码并给我一些建议。
这是我的代码:
import sounddevice as sd
import numpy as np
import tkinter as tk
from tkinter import ttk
from threading import Thread
class Stream(Thread):
def __init__(self):
super().__init__()
self.input_device_index = 2
self.output_device_index = 4
self.BLOCK_SHIFT = 128
self.SAMPLING_RATE = 16000
self.BLOCK_LEN = 512
self.SOUND_DEVICE_LATENCY = 0.2
self.start_streaming()
def start_streaming(self):
try:
with sd.Stream(device=(self.input_device_index, self.output_device_index),
samplerate=self.SAMPLING_RATE, blocksize=self.BLOCK_SHIFT,
dtype=np.float32, latency=self.SOUND_DEVICE_LATENCY,
channels=1, callback=self.callback):
input()
except Exception as ex:
print(str(type(ex).__name__ + ': ' + str(ex)))
@staticmethod
def callback(indata, outdata, frames, time, status):
outdata[:] = indata
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Please Help Me")
self.geometry("400x300")
self.resizable(0, 0)
start_button = tk.Button(self, overrelief="solid", width=15,
command=lambda: Function.start_button_clicked(),
text="Start", repeatdelay=1000, repeatinterval=100)
start_button.grid(column=0, row=5)
class Function:
@staticmethod
def start_button_clicked():
stream = Stream()
stream.start()
if __name__ == "__main__":
app = App()
app.mainloop()
您以错误的方式使用了 Thread
继承。您应该覆盖 class 中的 run()
方法。因此,将 start_streaming()
更改为 run()
并删除 __init__()
:
中的调用 start_streaming()
class Stream(Thread):
def __init__(self):
...
# should not call start_streaming() here
#self.start_streaming()
# rename start_streaming() to run()
def run(self):
...
我有一个代码可以处理来自声音设备的音频数据。
我的代码通过 tkinter 构建 GUI,并在按下按钮时通过声音设备库处理音频数据。
当我 运行 代码时,它实际上工作得很好。但是,出现GUI冻结,无法点击按钮。
所以我尝试通过线程解决这个问题,但屡次失败
请检查我的代码并给我一些建议。
这是我的代码:
import sounddevice as sd
import numpy as np
import tkinter as tk
from tkinter import ttk
from threading import Thread
class Stream(Thread):
def __init__(self):
super().__init__()
self.input_device_index = 2
self.output_device_index = 4
self.BLOCK_SHIFT = 128
self.SAMPLING_RATE = 16000
self.BLOCK_LEN = 512
self.SOUND_DEVICE_LATENCY = 0.2
self.start_streaming()
def start_streaming(self):
try:
with sd.Stream(device=(self.input_device_index, self.output_device_index),
samplerate=self.SAMPLING_RATE, blocksize=self.BLOCK_SHIFT,
dtype=np.float32, latency=self.SOUND_DEVICE_LATENCY,
channels=1, callback=self.callback):
input()
except Exception as ex:
print(str(type(ex).__name__ + ': ' + str(ex)))
@staticmethod
def callback(indata, outdata, frames, time, status):
outdata[:] = indata
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Please Help Me")
self.geometry("400x300")
self.resizable(0, 0)
start_button = tk.Button(self, overrelief="solid", width=15,
command=lambda: Function.start_button_clicked(),
text="Start", repeatdelay=1000, repeatinterval=100)
start_button.grid(column=0, row=5)
class Function:
@staticmethod
def start_button_clicked():
stream = Stream()
stream.start()
if __name__ == "__main__":
app = App()
app.mainloop()
您以错误的方式使用了 Thread
继承。您应该覆盖 class 中的 run()
方法。因此,将 start_streaming()
更改为 run()
并删除 __init__()
:
start_streaming()
class Stream(Thread):
def __init__(self):
...
# should not call start_streaming() here
#self.start_streaming()
# rename start_streaming() to run()
def run(self):
...