The layout is not working correctly. I want the screen split in equal parts. To the far left buttons in the middle a mathplotlib graph and to the right a grid. There are two problems mathplotlib graph does not appear centered and the grid is not to the far right.
I have tried changing the sizers and adding some flags to them.
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()
What should happen would be that each of the elements would be in its portion of the screen.
You can find below a working example having the widget distribution that you want. The code below should be a good starting point for you to add all other widgets and methods as needed by your app.
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()