带有 BoxSizer 的多个面板
Multiple panels with BoxSizer
我正在尝试将一个面板分成两个面板。
所以 Button1 应该在一个面板中 abd Button 2 , 3, 4 应该在另一个面板中。
这是我的可运行代码,它没有正确显示面板。
import wx
from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
class Frame1(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, None,
pos=wx.Point(0, 0),size=wx.Size(800, 200),
style=wx.DEFAULT_FRAME_STYLE | wx.MAXIMIZE )
self.panel1 = wx.Panel(self)
self.panel2 = wx.Panel(self)
#self.panel1.SetBackgroundColour('blue')
self.panel3 = wx.Panel(self)
self.panel4 = wx.Panel(self)
self.panel3.SetBackgroundColour('red')
sizer1 = wx.BoxSizer(wx.VERTICAL)
sizer1.Add(self.panel4, 1, wx.EXPAND)
sizer1.Add(self.panel1, 1, wx.EXPAND)
self.SetSizer(sizer1)
sizer1.Fit(self)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(sizer1, 1, wx.EXPAND)
sizer.Add(self.panel2, 1, wx.EXPAND)
sizer.Add(self.panel3, 1, wx.EXPAND)
self.SetSizer(sizer)
#sizer.Fit(self)
self.log = wx.TextCtrl(self.panel3, style=wx.TE_RICH|wx.TE_MULTILINE)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.log, 1, wx.EXPAND|wx.ALL, 15)
self.panel3.SetSizer(sizer)
emptycell = (0,0)
self.button1 = wx.Button(self.panel4, -1, "Button1", size=wx.Size(150, 70))
self.button2 = wx.Button(self.panel1, -1, "Button2")
self.button3 = wx.Button(self.panel1, -1, "Button3")
self.button4 = wx.Button(self.panel1, -1, "Button4")
sizer = wx.GridSizer(8,3,0,0)
sizer.Add(emptycell, 0, wx.EXPAND)
sizer.Add(self.button1, 0, wx.ALIGN_CENTER|wx.LEFT, 10)
sizer.Add(emptycell, 0, wx.EXPAND)
sizer.Add(self.button2, 0, wx.ALIGN_CENTER)
sizer.Add(self.button3, 0, wx.ALIGN_CENTER)
sizer.Add(self.button4, 0, wx.ALIGN_CENTER)
self.panel1.SetSizer(sizer)
self.figure = Figure()
self.axes = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self.panel2, -1, self.figure)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.canvas, 0, wx.EXPAND)
self.panel2.SetSizer(sizer)
#self.panel2.Fit()
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
self.axes.plot(t, s)
#self.Center()
#Every wxWidgets application must have a class derived from wxApp
class MyApp(wx.App):
# wxWidgets calls this method to initialize the application
def OnInit(self):
# Create an instance of our customized Frame class
self.frame = Frame1(None)
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == '__main__':
application = MyApp(0)
application.MainLoop()
想要的结果
实际结果
哎呀,其中一些面板和 sizer 变量名称很难理解。
在处理 wx 时,很好地跟踪 windows(因此,面板、按钮等)将位于其他 windows 中的内容可能会有所帮助,并且请注意您如何声明每个 parent。
例如,如果您有一个包含多个元素的面板(比如 panel1
),那么当您实例化这些元素时,将它们的 parent 全部设置为 panel1
.例如,当您创建 self.button1
时,将其 parent 设置为 panel1
(与其他按钮相同),因为您将所有按钮都放入 panel1
.
这是因为 wx 自然会尝试将 windows 放入他们的 parent 中。当一个 window 有一个 parent 那是一个元素,但一个 sizer 试图把它放在另一个元素中时,事情就变得很棘手了。很难完全理解,但我想这就是你的问题所在。
使您的代码 (a) 更易于 read/follow/debug 和 (b) 更好地工作的另一件事是:不要害怕实例化多个 sizer 变量。更好的是,给他们起的名字要与他们正在组织的小组相匹配!
我发现将 __init__
函数分为三个部分很有帮助(这可能对您也适用):(1) 实例化您需要的所有 windows/objects,从 "top level" 向下,分配给他们正确的 parent windows; (2) 实例化所有的 sizer,每个 windows 包含其他元素一个; (3) 从 "bottom level" 向上,将 windows 添加到它们的 parent sizer,在每个 parent 面板上调用 SetSizer
,并一直工作直到设置top-level window.
的主要 sizer
如果这不适合您,请随时给我发消息,我们将看看是否可以解析出 wx 无法正常工作的原因。
我不得不对它进行一些破解,但尝试为每个面板提供一个自己的 sizer,并在最后将它们组合在一起。还有,用描述性的名字,不然很快就变成一坨屎,很难跟得上。
import wx
from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
class Frame1(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, None,
pos=wx.Point(0, 0),size=wx.Size(800, 200),
style=wx.DEFAULT_FRAME_STYLE | wx.MAXIMIZE )
self.panel1_1 = wx.Panel(self)
self.panel1_2 = wx.Panel(self)
self.panel2 = wx.Panel(self)
self.panel3 = wx.Panel(self)
self.panel3.SetBackgroundColour('red')
self.panel1_1.SetBackgroundColour('green')
self.panel1_2.SetBackgroundColour('blue')
self.log = wx.TextCtrl(self.panel3, style=wx.TE_RICH|wx.TE_MULTILINE)
log_sizer = wx.BoxSizer(wx.HORIZONTAL)
log_sizer.Add(self.log, 1, wx.EXPAND|wx.ALL, 15)
self.panel3.SetSizer(log_sizer)
self.button1 = wx.Button(self.panel1_1, -1, "Button1", size=wx.Size(150, 70))
button_sizer1 = wx.GridSizer(1,3,0,0)
button_sizer1.Add((0,0), 0, wx.ALL, 10)
button_sizer1.Add(self.button1, 0, wx.ALL, 10)
button_sizer1.Add((0,0), 0, wx.ALL, 10)
self.panel1_1.SetSizer(button_sizer1)
self.button2 = wx.Button(self.panel1_2, -1, "Button2")
self.button3 = wx.Button(self.panel1_2, -1, "Button3")
self.button4 = wx.Button(self.panel1_2, -1, "Button4")
button_sizer2 = wx.GridSizer(1,3,0,0)
button_sizer2.Add(self.button2, 0, wx.ALL|wx.ALIGN_LEFT, 10)
button_sizer2.Add(self.button3, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10)
button_sizer2.Add(self.button4, 0, wx.ALL|wx.ALIGN_RIGHT, 10)
self.panel1_2.SetSizer(button_sizer2)
main_button_sizer = wx.BoxSizer(wx.VERTICAL)
main_button_sizer.Add(self.panel1_1)
main_button_sizer.Add(self.panel1_2, 1, wx.EXPAND)
self.figure = Figure()
self.axes = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self.panel2, -1, self.figure)
fig_sizer = wx.BoxSizer(wx.HORIZONTAL)
fig_sizer.Add(self.canvas, 0, wx.EXPAND)
self.panel2.SetSizer(fig_sizer)
main_sizer = wx.BoxSizer(wx.HORIZONTAL)
main_sizer.Add(main_button_sizer, 1, wx.EXPAND)
main_sizer.Add(self.panel2, 1, wx.EXPAND)
main_sizer.Add(self.panel3, 1, wx.EXPAND)
self.SetSizer(main_sizer)
self.Layout()
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
self.axes.plot(t, s)
#Every wxWidgets application must have a class derived from wxApp
class MyApp(wx.App):
# wxWidgets calls this method to initialize the application
def OnInit(self):
# Create an instance of our customized Frame class
self.frame = Frame1(None)
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == '__main__':
application = MyApp(0)
application.MainLoop()
我正在尝试将一个面板分成两个面板。 所以 Button1 应该在一个面板中 abd Button 2 , 3, 4 应该在另一个面板中。
这是我的可运行代码,它没有正确显示面板。
import wx
from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
class Frame1(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, None,
pos=wx.Point(0, 0),size=wx.Size(800, 200),
style=wx.DEFAULT_FRAME_STYLE | wx.MAXIMIZE )
self.panel1 = wx.Panel(self)
self.panel2 = wx.Panel(self)
#self.panel1.SetBackgroundColour('blue')
self.panel3 = wx.Panel(self)
self.panel4 = wx.Panel(self)
self.panel3.SetBackgroundColour('red')
sizer1 = wx.BoxSizer(wx.VERTICAL)
sizer1.Add(self.panel4, 1, wx.EXPAND)
sizer1.Add(self.panel1, 1, wx.EXPAND)
self.SetSizer(sizer1)
sizer1.Fit(self)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(sizer1, 1, wx.EXPAND)
sizer.Add(self.panel2, 1, wx.EXPAND)
sizer.Add(self.panel3, 1, wx.EXPAND)
self.SetSizer(sizer)
#sizer.Fit(self)
self.log = wx.TextCtrl(self.panel3, style=wx.TE_RICH|wx.TE_MULTILINE)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.log, 1, wx.EXPAND|wx.ALL, 15)
self.panel3.SetSizer(sizer)
emptycell = (0,0)
self.button1 = wx.Button(self.panel4, -1, "Button1", size=wx.Size(150, 70))
self.button2 = wx.Button(self.panel1, -1, "Button2")
self.button3 = wx.Button(self.panel1, -1, "Button3")
self.button4 = wx.Button(self.panel1, -1, "Button4")
sizer = wx.GridSizer(8,3,0,0)
sizer.Add(emptycell, 0, wx.EXPAND)
sizer.Add(self.button1, 0, wx.ALIGN_CENTER|wx.LEFT, 10)
sizer.Add(emptycell, 0, wx.EXPAND)
sizer.Add(self.button2, 0, wx.ALIGN_CENTER)
sizer.Add(self.button3, 0, wx.ALIGN_CENTER)
sizer.Add(self.button4, 0, wx.ALIGN_CENTER)
self.panel1.SetSizer(sizer)
self.figure = Figure()
self.axes = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self.panel2, -1, self.figure)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.canvas, 0, wx.EXPAND)
self.panel2.SetSizer(sizer)
#self.panel2.Fit()
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
self.axes.plot(t, s)
#self.Center()
#Every wxWidgets application must have a class derived from wxApp
class MyApp(wx.App):
# wxWidgets calls this method to initialize the application
def OnInit(self):
# Create an instance of our customized Frame class
self.frame = Frame1(None)
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == '__main__':
application = MyApp(0)
application.MainLoop()
想要的结果
实际结果
哎呀,其中一些面板和 sizer 变量名称很难理解。
在处理 wx 时,很好地跟踪 windows(因此,面板、按钮等)将位于其他 windows 中的内容可能会有所帮助,并且请注意您如何声明每个 parent。
例如,如果您有一个包含多个元素的面板(比如 panel1
),那么当您实例化这些元素时,将它们的 parent 全部设置为 panel1
.例如,当您创建 self.button1
时,将其 parent 设置为 panel1
(与其他按钮相同),因为您将所有按钮都放入 panel1
.
这是因为 wx 自然会尝试将 windows 放入他们的 parent 中。当一个 window 有一个 parent 那是一个元素,但一个 sizer 试图把它放在另一个元素中时,事情就变得很棘手了。很难完全理解,但我想这就是你的问题所在。
使您的代码 (a) 更易于 read/follow/debug 和 (b) 更好地工作的另一件事是:不要害怕实例化多个 sizer 变量。更好的是,给他们起的名字要与他们正在组织的小组相匹配!
我发现将 __init__
函数分为三个部分很有帮助(这可能对您也适用):(1) 实例化您需要的所有 windows/objects,从 "top level" 向下,分配给他们正确的 parent windows; (2) 实例化所有的 sizer,每个 windows 包含其他元素一个; (3) 从 "bottom level" 向上,将 windows 添加到它们的 parent sizer,在每个 parent 面板上调用 SetSizer
,并一直工作直到设置top-level window.
如果这不适合您,请随时给我发消息,我们将看看是否可以解析出 wx 无法正常工作的原因。
我不得不对它进行一些破解,但尝试为每个面板提供一个自己的 sizer,并在最后将它们组合在一起。还有,用描述性的名字,不然很快就变成一坨屎,很难跟得上。
import wx
from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
class Frame1(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, None,
pos=wx.Point(0, 0),size=wx.Size(800, 200),
style=wx.DEFAULT_FRAME_STYLE | wx.MAXIMIZE )
self.panel1_1 = wx.Panel(self)
self.panel1_2 = wx.Panel(self)
self.panel2 = wx.Panel(self)
self.panel3 = wx.Panel(self)
self.panel3.SetBackgroundColour('red')
self.panel1_1.SetBackgroundColour('green')
self.panel1_2.SetBackgroundColour('blue')
self.log = wx.TextCtrl(self.panel3, style=wx.TE_RICH|wx.TE_MULTILINE)
log_sizer = wx.BoxSizer(wx.HORIZONTAL)
log_sizer.Add(self.log, 1, wx.EXPAND|wx.ALL, 15)
self.panel3.SetSizer(log_sizer)
self.button1 = wx.Button(self.panel1_1, -1, "Button1", size=wx.Size(150, 70))
button_sizer1 = wx.GridSizer(1,3,0,0)
button_sizer1.Add((0,0), 0, wx.ALL, 10)
button_sizer1.Add(self.button1, 0, wx.ALL, 10)
button_sizer1.Add((0,0), 0, wx.ALL, 10)
self.panel1_1.SetSizer(button_sizer1)
self.button2 = wx.Button(self.panel1_2, -1, "Button2")
self.button3 = wx.Button(self.panel1_2, -1, "Button3")
self.button4 = wx.Button(self.panel1_2, -1, "Button4")
button_sizer2 = wx.GridSizer(1,3,0,0)
button_sizer2.Add(self.button2, 0, wx.ALL|wx.ALIGN_LEFT, 10)
button_sizer2.Add(self.button3, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10)
button_sizer2.Add(self.button4, 0, wx.ALL|wx.ALIGN_RIGHT, 10)
self.panel1_2.SetSizer(button_sizer2)
main_button_sizer = wx.BoxSizer(wx.VERTICAL)
main_button_sizer.Add(self.panel1_1)
main_button_sizer.Add(self.panel1_2, 1, wx.EXPAND)
self.figure = Figure()
self.axes = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self.panel2, -1, self.figure)
fig_sizer = wx.BoxSizer(wx.HORIZONTAL)
fig_sizer.Add(self.canvas, 0, wx.EXPAND)
self.panel2.SetSizer(fig_sizer)
main_sizer = wx.BoxSizer(wx.HORIZONTAL)
main_sizer.Add(main_button_sizer, 1, wx.EXPAND)
main_sizer.Add(self.panel2, 1, wx.EXPAND)
main_sizer.Add(self.panel3, 1, wx.EXPAND)
self.SetSizer(main_sizer)
self.Layout()
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
self.axes.plot(t, s)
#Every wxWidgets application must have a class derived from wxApp
class MyApp(wx.App):
# wxWidgets calls this method to initialize the application
def OnInit(self):
# Create an instance of our customized Frame class
self.frame = Frame1(None)
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == '__main__':
application = MyApp(0)
application.MainLoop()