Остановите чтение заметок, созданных с помощью fluidsynth, с помощью кнопки в tkinter
Я на Python2-7 Я хочу получить кнопку в tkinter, которая останавливает чтение заметок, созданных с помощью Fluidsynth.
Я обнаружил, что общим решением является использование time.after как здесь: Как создать кнопку остановки Tkinter GUI, чтобы разорвать бесконечный цикл?
Но в моем случае я не могу использовать его, потому что мне нужно время между запиской и запиской, чтобы указать продолжительность для моих заметок. Более того, я хочу играть ноты, ТОЛЬКО если я нажму на начало (а не в начале, как решение в ссылке).
Поэтому я создал этот код, но он не работает, потому что var_start всегда инициализируется как int:
from tkinter import*
import fluidsynth
import time
fs=fluidsynth.Synth()
fs.start(driver='alsa', midi_driver='alsa_seq')
org_charge = fs.sfload("organ.sf2")
fs.program_select(0,org_charge, 0, 0)
time.sleep(1)
var_start=int
def start():
global var_start
var_start=1
def stop():
global var_start
var_start=0
root=Tk()
if var_start==1:
fs.noteon(0,67,127)
time.sleep(1)
fs.noteoff(0,67)
fs.noteon(0,71,127)
time.sleep(1)
fs.noteoff(0,71)
fs.noteon(0,74,127)
time.sleep(1)
fs.noteoff(0,74)
Button(root, text='start', command= start).pack(padx=10, pady=10)
Button(root, text='stop', command= stop).pack(padx=10, pady=10)
root.mainloop()
У меня нет другой идеи, чтобы изменить мой код... Кто-то может мне помочь?
Спасибо
1 ответ
Вы инициировали var_start
в int
в заявлении var_start=int
и поэтому блок кода в if var_start==1:
никогда не будет казнен. И ваш start()
функция просто меняет var_start
1 и никогда не начинайте играть на нотах, поэтому ничего не произойдет.
Никогда не звони time.sleep()
в основном потоке, так как он заблокирует tkinter
основной цикл Ты можешь использовать .after(...)
для имитации цикла воспроизведения и ниже приведен пример кода блока:
playing = False
def play_notes(notes, index, noteoff):
global playing
if noteoff:
fs.noteoff(0, notes[index])
index += 1 # next note
if playing and index < len(notes):
fs.noteon(0, notes[index], 127)
# call noteoff one second later
root.after(1000, play_notes, notes, index, True)
else:
# either stopped or no more note to play
playing = False
print('done playing')
def start_playing():
global playing
if not playing:
print('start playing')
playing = True
notes = [67, 71, 74, 88, 80, 91]
play_notes(notes, 0, False)
else:
print('already playing')
def stop_playing():
global playing
if playing:
playing = False
print('stop playing')
else:
print('nothing playing')
Button(root, text='Start', command=start_playing).pack(padx=10, pady=10)
Button(root, text='Stop', command=stop_playing).pack(padx=10, pady=10)
Это всего лишь пример, который вы можете изменить в соответствии со своими потребностями.