I am making a simple gui for a signal generator with wx. I want to display a small plot of say a sine wave when the option "Sine" is chosen, and a plot of a square wave when "Square" is chosen from the menu. I am a newbie in python, and therefore the classes and inheritance of these is difficult for me.
In the (much stripped down) code i have a variable 'wave' inside the class 'ServelPanel' that holds which wavetype is chosen. However, when I try and plot the waveform in the MainFrame class, I cannot for the life of me retrieve the 'wave'-variable. I have tried to inherit classes, set the 'wave'-variable global, and am out of ideas.
import wx, random, math, os
from pyo import *
from numpy import arange, sin, pi, sign
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
class BasePanel(wx.Panel):
def __init__(self, parent, title):
wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
self.SetMaxSize((230,150))
self.sliders = []
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.titleSizer = wx.BoxSizer(wx.HORIZONTAL)
self.close = wx.StaticText(self, id=-1, label="X")
self.close.Bind(wx.EVT_LEFT_DOWN, self.MouseDown)
self.titleSizer.Add(self.close, 0, wx.LEFT, 5)
self.title = wx.StaticText(self, id=-1, label=title)
off = (210 - self.title.GetSize()[0]) / 2
self.titleSizer.Add(self.title, 0, wx.LEFT, off)
self.sizer.Add(self.titleSizer, 0, wx.BOTTOM|wx.TOP, 4)
class ServerPanel(wx.Panel):
def __init__(self, parent, colour="#DDDDE7"):
wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
self.SetBackgroundColour(colour)
self.SetMinSize((230,250))
self.fileformat = self.wavetype = 0
self.title = wx.StaticText(self, id=-1, label="--- Simple Wave
Generator ---", pos=(40,5))
font, psize = self.title.GetFont(),
self.title.GetFont().GetPointSize()
font.SetPointSize(psize-2)
self.waveText =
wx.StaticText(self,id=-1,label="Waveform",pos(15,60))
self.popupWave = wx.Choice(self, id=wx.ID_ANY, pos=(13,70),
size(70,20), choices=["Sine","Square"])
self.popupWave.Bind(wx.EVT_CHOICE, self.changeWave)
objs = [self.waveText]
for obj in objs:
obj.SetFont(font)
def changeWave(self, evt):
global wave
wave = evt.GetInt()
if wave == 1: wave = 2
self.wavetype = wave
class MainFrame(wx.Frame,ServerPanel):
def __init__(self, parent=None, title=u"Sine Test", size=(250,300)):
wx.Frame.__init__(self, parent, id=-1, title=title, size=size)
self.server = Server().boot()
self.sizer = wx.FlexGridSizer(4,4,0,0)
self.panel = wx.Panel(self)
self.serverPanel = ServerPanel(self.panel)
self.sizer.Add(self.serverPanel)
self.panel.SetSizer(self.sizer)
pan = CanvasPanel(self.panel)
pan.draw()
self.Show()
class CanvasPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, id=-1, pos=wx.Point(100,60),
size=wx.Size(80, 50))
figsize = (80*1.0/80, 50*1.0/80)
self.figure = Figure(figsize, dpi=80)
self.axes = self.figure.add_subplot(111)
self.axes.set_axis_off()
self.canvas = FigureCanvas(self, -1, self.figure)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas,1,wx.LEFT | wx.TOP | wx.GROW)
self.SetSizer(self.sizer)
self.Fit()
def draw(self):
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
self.axes.plot(t, s)
def drawSqr(self):
t = arange(0.0, 3.0, 0.01)
s = sign(sin(2 * pi * t))
self.axes.plot(t, s)
mainFrame = MainFrame()
app.MainLoop()
Ps: I know the "minimal working example" is not really minimal, but it's what I could get working for the moment. Please excuse a novice.
In the example I have hard coded a drawing to show in the MainFrame class, so you see where the drawing should be.
If we boil your code down a bit, remove un-needed classes, use sizers
rather than mixing sizers and positional statements, clean up the indentation issues, remove undeclared items and unused imports.
We get something along these lines.
import wx
from numpy import arange, sin, pi, sign
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
class MainFrame(wx.Frame):
def __init__(self, parent=None, title=u"Sine Test", size=(250,300)):
wx.Frame.__init__(self, parent, id=-1, title=title, size=size)
self.panel = wx.Panel(self,-1,style=wx.SUNKEN_BORDER)
self.panel.SetBackgroundColour("#DDDDE7")
self.panel.SetMinSize((230,250))
self.wavetype = 0
self.title = wx.StaticText(self.panel, id=-1, label="--- Simple Wave Generator ---")
font, psize = self.title.GetFont(), self.title.GetFont().GetPointSize()
font.SetPointSize(psize-2)
self.waveText = wx.StaticText(self.panel,id=-1,label="Waveform")
self.popupWave = wx.Choice(self.panel, id=wx.ID_ANY, size=(70,30), choices=["Sine","Square"])
self.popupWave.Bind(wx.EVT_CHOICE, self.changeWave)
self.pan = CanvasPanel(self)
self.sizer = wx.GridBagSizer(hgap=5,vgap=5)
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.title, pos=(0,0), span=(1,4), flag = wx.ALL|wx.ALIGN_CENTER)
self.sizer.Add(self.waveText, pos=(2,0), flag = wx.ALL)
self.sizer.Add(self.popupWave, pos=(3,0), flag = wx.ALL)
self.sizer.Add(self.pan, pos=(3,1), span=(3,3), flag = wx.ALL|wx.EXPAND)
self.panel.SetSizer(self.sizer)
self.main_sizer.Add(self.panel,1,wx.EXPAND)
self.SetSizer(self.main_sizer)
self.popupWave.SetSelection(0)
self.pan.wavetype = self.popupWave.GetSelection()
self.pan.draw()
self.Show()
def changeWave(self, evt):
wave = evt.GetSelection()
self.pan.wavetype = wave
self.pan.draw()
class CanvasPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, id=-1, size=wx.Size(80, 50))
figsize = (80*1.0/80, 50*1.0/80)
self.figure = Figure(figsize, dpi=80)
self.wavetype = parent.wavetype
self.axes = self.figure.add_subplot(111)
self.axes.set_axis_off()
self.canvas = FigureCanvas(self, -1, self.figure)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas,1,wx.LEFT | wx.TOP | wx.GROW)
self.SetSizer(self.sizer)
self.Fit()
def draw(self):
#Clear any previous data
self.axes.clear()
self.axes.set_axis_off()
#Plot new wave
if self.wavetype == 0:
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
self.axes.plot(t, s)
else:
t = arange(0.0, 3.0, 0.01)
s = sign(sin(2 * pi * t))
self.axes.plot(t, s)
self.Layout()
app=wx.App()
mainFrame = MainFrame()
app.MainLoop()
It may not be exactly what you are after, so feel free to play with it!