wx中不同弹出选项的不同matlibplots

Different matlibplots for different popup choices in wx

我正在用 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.我是python的新手,因此classes和继承这些对我来说很难。

在(大量精简的)代码中,我在 class 'ServelPanel' 中有一个变量 'wave',用于保存选择的波型。但是,当我尝试在 MainFrame class 中绘制波形时,我终生无法检索 'wave' 变量。我试图继承 classes,设置 'wave'-变量全局,但我没有想法。

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:我知道 "minimal working example" 并不是真正的最小值,但这是我目前可以开始工作的。新手请见谅。

在这个例子中,我硬编码了一个绘图以在 MainFrame 中显示 class,所以你可以看到绘图应该在哪里。

如果我们稍微简化您的代码,删除 un-needed 类,使用 sizers 而不是混合大小调整器和位置语句,清理缩进问题,删除未声明的项目和未使用的导入。
我们从这些方面得到了一些东西。

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()

这可能不是您想要的,请随意使用它!