Привязка вывода осциллятора Pyo к событию WX
Я строю простой генератор сигналов в Python на основе библиотек Pyo и WX.
Я пробежал простые уроки для каждого и успешно связал кнопки в функциях WX и WX. Сейчас я пытаюсь сгенерировать простую синусоидальную волну (при 440 Гц) в течение 1 секунды, нажимая кнопку с надписью "Осциллятор 1"; однако, когда выполняется функция main(), воспроизводится синусоидальный сигнал, и пока кнопка отображается в кадре wx, я не могу перезапустить синусоидальный сигнал. Оба эти симптома являются нежелательными.
Почему синусоидальный сигнал играет сразу при выполнении программы? Почему первая кнопка OSC, похоже, не работает?
import wx
from pyo import *
import time
pyoServer = Server().boot()
pyoServer.start()
class MainWindow(wx.Frame):
def __init__(self,parent,title):
wx.Frame.__init__(self,parent,title=title, size = (640,640))
self.CreateStatusBar() # A StatusBar in the bottom of the window
# Signal Generator controls
oscillator = SoundOutput()
firstOSC = wx.Button(self, wx.ID_YES,"Oscillator 1 " + str(oscillator.str_osc1State))
self.Bind(wx.EVT_BUTTON, oscillator.OnOff1(440), firstOSC)
#Menus
filemenu = wx.Menu()
menuExit = filemenu.Append(wx.ID_EXIT,"&Exit","Terminate the program")
menuBar = wx.MenuBar()
menuBar.Append(filemenu,"&File")
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
self.Show(True)
def OnExit(self,e):
self.Close(True)
class SoundOutput(object):
def __init__(self):
self.osc1State = False
self.str_osc1State = "Off"
self.a = Sine(440, 0, 0.1)
def OnOff1(self, frequency):
self.a.freq = frequency
self.a.out()
time.sleep(1)
self.osc1State = True
def Main():
app = wx.App(False)
frame = MainWindow(None,"Signal Generator")
app.MainLoop()
1 ответ
Я решил это, исследуя, как WX обрабатывает события. Оказывается, по какой-то причине вызов метода во вложенном или отдельном экземпляре класса вызвал воспроизведение тона во время выполнения, а не в событии. Я исправил это, сделав метод для класса MainWindow, который служит в качестве обработчика связанных событий для firstOSC. Затем этот метод вызывает необходимые методы для фактического класса осциллятора.
Вот новый код:
# Signal Generator controls
self.fOscillator = SoundOutput()
self.fOscillatorstatus = False
self.firstOSC = wx.Button(self, wx.ID_ANY,"Oscillator 1 On")
self.firstOSC.Bind(wx.EVT_BUTTON, self.OnFirstOSC)
def OnFirstOSC(self,e):
if not self.fOscillatorstatus:
self.fOscillator.OnOff1(440)
self.fOscillatorstatus = True
self.firstOSC.SetLabel("Oscillator 1 Off")
elif self.fOscillatorstatus:
self.fOscillator.OnOff1(0)
self.firstOSC.SetLabel("Oscillator 1 On")
self.fOscillatorstatus = False