带有图形和网格的 WxPython 布局

WxPython Layout with Graph and Grid

布局工作不正常。我希望屏幕分成相等的部分。最左边的按钮中间是一个 mathplotlib 图形,右边是一个网格。有两个问题mathplotlib图形没有出现居中和网格不在最右边。

我试过更改 sizer 并向它们添加一些标志。

import wx
import wx.grid as grid
from sympy import Symbol, sympify
from matplotlib.pyplot import plot, show, title, xlabel, ylabel
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np

h = float()
xi = float()
yi = float()
fx = Symbol('fx')
xistr = np.array([])
yistr = np.array([])
istr = np.array([])
hstr = np.array([])
state = float()


class MyPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        ###########
        main_sizer = wx.BoxSizer(wx.HORIZONTAL)
        left_sizer = wx.BoxSizer(wx.VERTICAL)
        center_sizer = wx.BoxSizer(wx.VERTICAL)
        right_sizer = wx.BoxSizer(wx.VERTICAL)
        main_sizer.Add(left_sizer, 1, wx.EXPAND)
        main_sizer.Add(center_sizer, 1, wx.EXPAND)
        main_sizer.Add(right_sizer, 1, wx.EXPAND)
        ###########
        self.runbn = wx.Button(self, label="Run", size=(60, 30))
        self.Bind(wx.EVT_BUTTON, self.Run, self.runbn)
        ############
        self.functionin = wx.TextCtrl(self, size=(150, 30), style=wx.TE_CENTER)
        self.STRfxbn = wx.Button(self, -1, label="STR", size=(60, 30))
        self.Bind(wx.EVT_BUTTON, self.STRfc, self.STRfxbn)
        ############
        self.yiin = wx.TextCtrl(self, size=(150, 30), style=wx.TE_CENTER)
        self.STRyibn = wx.Button(self, -1, label="STR", size=(60, 30))
        self.Bind(wx.EVT_BUTTON, self.STRyi, self.STRyibn)
        ############
        self.xiin = wx.TextCtrl(self, size=(150, 30), style=wx.TE_CENTER)
        self.STRxibn = wx.Button(self, -1, label="STR", size=(60, 30))
        self.Bind(wx.EVT_BUTTON, self.STRxi, self.STRxibn)
        ############
        self.hiin = wx.TextCtrl(self, size=(150, 30), style=wx.TE_CENTER)
        self.STRhibn = wx.Button(self, -1, label="STR", size=(60, 30))
        self.Bind(wx.EVT_BUTTON, self.STRhi, self.STRhibn)
        ###########
        self.resultbn = wx.Button(self, label="Results", size=(60, 30))
        self.Bind(wx.EVT_BUTTON, self.showresults, self.resultbn)
        ############

        left_sizer.Add(wx.StaticText(self, -1, "f(x) for ODE"))
        left_sizer.Add(self.functionin, 0)
        left_sizer.Add(self.STRfxbn, 0)

        left_sizer.Add(wx.StaticText(self, -1, "Initial y value"))
        left_sizer.Add(self.yiin, 0)
        left_sizer.Add(self.STRyibn, 0)

        left_sizer.Add(wx.StaticText(self, -1, "Initial x value"))
        left_sizer.Add(self.xiin)
        left_sizer.Add(self.STRxibn)

        left_sizer.Add(wx.StaticText(self, -1, "Initial step h"))
        left_sizer.Add(self.hiin)
        left_sizer.Add(self.STRhibn)

        left_sizer.Add(self.runbn, 0)
        left_sizer.Add(self.resultbn, 0)
        self.SetSizer(main_sizer)

    def showresults(self, event):
        global istr
        global xistr
        global yistr
        global hstr
        resultgr = grid.Grid(self)
        resultgr.CreateGrid(30, 4)
        resultgr.SetColLabelValue(0, "Iteration")
        resultgr.SetColLabelValue(1, "X Value")
        resultgr.SetColLabelValue(2, "Y Value")
        resultgr.SetColLabelValue(3, "Step Size")
        r = 0
        i = 0
        for i in range(30):
            resultgr.SetCellValue(r, 0, str(round(istr[r], 4)))
            r = r + 1
            i = i + 1
        r = 0
        i = 0
        for i in range(30):
            resultgr.SetCellValue(r, 1, str(round(xistr[r], 4)))
            r = r + 1
            i = i + 1
        r = 0
        i = 0
        for i in range(30):
            resultgr.SetCellValue(r, 2, str(round(yistr[r], 4)))
            r = r + 1
            i = i + 1
        r = 0
        i = 0
        for i in range(30):
            resultgr.SetCellValue(r, 3, str(round(hstr[r], 4)))
            r = r + 1
            i = i + 1
        self.figure = Figure(figsize=(5, 4), dpi=100)
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes.set_xlabel("x values")
        self.axes.set_ylabel("y values")
        self.axes.set_title("Prince-Dormand")
        self.axes.plot(xistr, yistr)
        main_sizer = wx.BoxSizer(wx.HORIZONTAL)
        left_sizer = wx.BoxSizer(wx.VERTICAL)
        center_sizer = wx.BoxSizer(wx.VERTICAL)
        right_sizer = wx.BoxSizer(wx.VERTICAL)
        main_sizer.Add(left_sizer, 2, wx.EXPAND)
        main_sizer.Add(center_sizer, 1, wx.EXPAND)
        main_sizer.Add(right_sizer, 1, wx.EXPAND)
        center_sizer.Add(self.canvas, 0, wx.LEFT, 200)
        right_sizer.Add(resultgr, 0, wx.RIGHT, 0)
        self.SetSizer(main_sizer)
        self.Fit()

... Following are button functions and main function which calculates values that go into graph and grid

class MainFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title='Prince-Dormand Method', size=(1300, 600))
        panel = MyPanel(self)
        self.Show()


if __name__ == '__main__':
    app = wx.App(False)
    resultgr = grid.Grid()
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

应该发生的是每个元素都在其屏幕部分。

您可以在下面找到一个工作示例,其中包含您想要的小部件分布。 下面的代码应该是您根据应用需要添加所有其他小部件和方法的良好起点。

import wx
import wx.grid as grid
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure

class MainFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title='Prince-Dormand Method', size=(800, 600))

        ####---- Widgets
        self.panel = wx.Panel(self)
        # Left Sizer Widgets here
        self.runbn = wx.Button(self.panel, label="Run", size=(60, 30))
        # Matplotlib plot here
        self.figure = Figure(figsize=(5, 4), dpi=100)
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self.panel, -1, self.figure)
        self.axes.set_xlabel("x values")
        self.axes.set_ylabel("y values")
        self.axes.set_title("Prince-Dormand")
        # Grid here
        self.resultgr = grid.Grid(self)
        self.resultgr.CreateGrid(30, 4)
        self.resultgr.SetColLabelValue(0, "Iteration")
        self.resultgr.SetColLabelValue(1, "X Value")
        self.resultgr.SetColLabelValue(2, "Y Value")
        self.resultgr.SetColLabelValue(3, "Step Size")
        ####---- Sizers
        main_sizer = wx.BoxSizer(wx.HORIZONTAL)
        left_sizer = wx.BoxSizer(wx.VERTICAL)
        center_sizer = wx.BoxSizer(wx.VERTICAL)
        right_sizer = wx.BoxSizer(wx.VERTICAL)

        left_sizer.Add(self.runbn, 1, wx.ALIGN_CENTER)
        center_sizer.Add(self.canvas, 1, wx.EXPAND)
        right_sizer.Add(self.resultgr, 1, wx.EXPAND)

        main_sizer.Add(left_sizer, 1, wx.EXPAND)
        main_sizer.Add(center_sizer, 1, wx.EXPAND)
        main_sizer.Add(right_sizer, 1, wx.EXPAND)

        self.panel.SetSizer(main_sizer)
        main_sizer.Fit(self.panel)
    #---
#---

if __name__ == '__main__':
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()