Tkinter的“奇怪行为之后”

时间:2019-01-08 13:05:02

标签: python tkinter

我正在尝试在PC上编写吉他调音程序。主要目标是创建一个应用程序,该应用程序能够使用麦克风捕获音频,进行一些分析并将结果输出给用户,从而使他们能够调整乐器。

我在其中一项职能中遇到了一个奇怪的问题。我试图两次更改标签-首先是在函数启动时,然后是3秒钟后。但是,在等待结束时,标签仅更新一次(仅显示* recording...文本)。我还注意到,我的整个GUI冻结了一次(我想)是它开始执行stateL标签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使用是否正确,还是应该以其他任何方式进行此操作。

1 个答案:

答案 0 :(得分:2)

要回答问题中的主要问题,您需要使用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!")