Ткинтер `после` странного поведения - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь написать программу настройки гитары на моем ПК. Основная цель - создать приложение, способное записывать звук с помощью микрофона, проводить некоторый анализ и выводить результаты пользователю, что позволяет ему настроить свой инструмент.

Я столкнулся со странной проблемой в одной из моих функций. Я пытаюсь изменить метку два раза - сначала, когда функция запускается, и позже, когда проходит 3 секунды. Однако метка обновляется только один раз (эффективно показывая только текст * recording...), в конце ожидания. Что я также заметил, весь мой графический интерфейс зависает, как только (я думаю) он начинает выполнять метку 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 голосов
/ 08 января 2019

Чтобы ответить на основную проблему в вашем вопросе, вам нужно использовать лямбду, чтобы решить эту конкретную проблему.

Изменение:

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!")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...