python - Tkinter`after`奇怪的行为
问题描述
我正在尝试在我的 PC 上编写吉他调音程序。主要目标是创建一个应用程序,该应用程序能够使用麦克风捕获音频,进行一些分析并将结果输出给用户,让他们调整他们的乐器。
我在我的一个函数中遇到了一个奇怪的问题。我试图更改标签两次 - 首先是在函数启动时,然后是 3 秒后。* recording...
但是,标签仅在等待结束时更新一次(实际上只显示文本)。我还注意到,我的整个 GUI 冻结一次(我猜)它开始执行stateL
label after
。
代码片段(不要关心 pyAudio 部分,它还没有改变):
def gather_input(self):
self.stateL.configure(text="Starting recording in 3 sec. Prepare!")
self.stateL.after(3000, self.stateL.configure(text="* recording..."))
# p = pyaudio.PyAudio()
#
# stream = p.open(format=self.FORMAT,
# channels=self.CHANNELS,
# rate=self.RATE,
# input=True,
# frames_per_buffer=self.CHUNK)
#
# frames = []
#
# for i in range(0, int(self.RATE / self.CHUNK * self.RECORD_SECONDS)):
# data = stream.read(self.CHUNK)
# frames.append(data)
#
# stream.stop_stream()
# stream.close()
# p.terminate()
#
# self.stateL.configure(text="Done recording!")
#
# return frames
我的其他功能中的按钮行:
self.recButton = ttk.Button(self.mainLF, text="Start rec.", command=self.gather_input)
等待 3 秒后,我的目标是使用该功能,保存声音样本并做一些其他事情(例如,在录音结束时再次更改标签,就像#
这里一样)。另外,我什至不确定self.stateL.configure
在after
零件中使用是否正确,或者我应该以其他方式这样做。
解决方案
要回答您问题中的主要问题,您需要使用 lambda 来解决该特定问题。
改变:
self.after(3000, self.stateL.configure(text="* recording..."))
至:
self.after(3000, lambda: self.stateL.configure(text="* recording..."))
要处理评论中提到的问题,您可能需要尝试以下操作。
你需要设置一些方法来让事情按照你想要的方式工作。您还需要将一些变量更改为类属性。
试试这个,让我知道它是否有帮助。
def gather_input(self):
self.stateL.configure(text="Starting recording in 3 sec. Prepare!")
self.after(3000, self.start_recording)
def start_recording(self):
self.stateL.configure(text="* recording...")
self.p = pyaudio.PyAudio()
self.stream = self.p.open(format=self.FORMAT,
channels=self.CHANNELS,
rate=self.RATE,
input=True,
frames_per_buffer=self.CHUNK)
self.after(3000, self.stop_recording)
def stop_recording(self):
self.frames = []
for i in range(0, int(self.RATE / self.CHUNK * self.RECORD_SECONDS)):
data = self.stream.read(self.CHUNK)
self.frames.append(data)
self.stream.stop_stream()
self.stream.close()
self.p.terminate()
self.stateL.configure(text="Done recording!")