python-3.x - wxPython 分层布局似乎没有正确调整大小
问题描述
我无法弄清楚为什么我的分层布局没有像我在 wxPython 中所期望的那样做。
基本思路如下:
+- Win1 ------+ +- Win2 -----+ +- Win3 ----------+
| | | | | |
+-------------+ +------------+ +-----------------+
+- Win4 ----------+ +- Win5 ---------------------+
| | | |
+-----------------+ +----------------------------+
+- Win6 -----------------------------------------+
| |
+------------------------------------------------+
我正在创建一个垂直框布局来处理三个区域{1/2/3, 4/5, 6}
。在这些区域中的每一个内部都有另一个(水平)框布局来处理(例如在第一个区域中){1, 2, 3}
子区域。
然后,在这些子区域中的每一个内,我都有一个静态 box sizer 给我一个多行、非用户可编辑的文本控件的边框。
现在,下面的代码已简化为两行,第一行两列,第二行一列。只有第一行中的第一列是绘制漂亮边框控件的尝试,其他只是静态文本控件。
import wx
class MyFrame(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title, pos=(150,50), size=(1720,930))
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.topPanel = wx.Panel(self, wx.ID_ANY)
self.screenPanel = wx.Panel(self.topPanel, wx.ID_ANY)
self.spacer0 = wx.StaticText(self.topPanel, wx.ID_ANY, "")
self.dummy1 = wx.StaticText(self.topPanel, wx.ID_ANY, "dummy1")
self.dummy2 = wx.StaticText(self.topPanel, wx.ID_ANY, "dummy2")
self.topSizer = wx.BoxSizer(wx.VERTICAL)
self.row1Sizer = wx.BoxSizer(wx.HORIZONTAL)
self.row2Sizer = wx.BoxSizer(wx.HORIZONTAL)
self.screenSizer = wx.StaticBoxSizer(wx.HORIZONTAL,
self.screenPanel, "Screen")
self.screen = wx.TextCtrl(self.screenPanel, wx.ID_ANY,
"This is the first line\nXYZZY\nPLUGH",
wx.DefaultPosition, wx.DefaultSize,
wx.TE_MULTILINE | wx.TE_READONLY)
self.row1Sizer.Add(self.screenSizer, 0, wx.ALL, 5)
self.row1Sizer.Add(self.spacer0, 1, wx.ALL, 5)
self.row1Sizer.Add(self.dummy1, 0, wx.ALL, 5)
self.row2Sizer.Add(self.dummy2, 0, wx.ALL, 5)
self.topSizer.Add(self.row1Sizer, 0, wx.ALL | wx.EXPAND, 5)
self.topSizer.Add(self.row2Sizer, 0, wx.ALL | wx.EXPAND, 5)
self.screenPanel.SetSizer(self.screenSizer)
self.topPanel.SetSizer(self.topSizer)
self.topPanel.Layout()
def OnClose(self, event):
self.Destroy()
app = wx.App()
top = MyFrame("My")
top.Show()
app.MainLoop()
但是,似乎存在一些问题,我认为这可能是由于我对 sizers 或 non-sizer 是否应该拥有被控制的资源感到困惑,但我无法让它发挥作用。目前的代码给了我:
如您所见,第一个控件周围似乎缺少静态框,并且大小似乎搞砸了。我会认为大小将根据布局计算,以便它至少足够大以容纳内部控件和边框。
谁能让我知道我对这段代码做错了什么?
它也在退出时崩溃,这可能是相关的。如果没有,我可以将其作为一个单独的问题处理。
解决方案
静态框可以单独创建,也可以为方便起见,sizer 可以自己创建。在任何情况下,sizer 都拥有 wx.StaticBox 控件,并将在 wx.StaticBoxSizer 析构函数中将其删除。
请注意,从 wxWidgets 2.9.1 开始,鼓励您创建添加到 wx.StaticBoxSizer 作为 wx.StaticBox 子级的窗口
所以是这样的:
import wx
class MyFrame(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title, pos=(150,50), size=(500,400))
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.SetMinSize((500,400))
self.topPanel = wx.Panel(self, wx.ID_ANY)
box1 = wx.StaticBox(self.topPanel, wx.ID_ANY, "Win1")
box1.SetForegroundColour('#000000')
self.textCtrl1 = wx.TextCtrl(box1, wx.ID_ANY,
"This is the first line\nXYZZY\nPLUGH",
wx.DefaultPosition, size = (200,100), style = wx.TE_MULTILINE | wx.TE_READONLY)
self.dummy4 = wx.StaticText(box1, wx.ID_ANY, "Text below textctrl 1")
boxSizer1 = wx.StaticBoxSizer(box1, wx.VERTICAL)
boxSizer1.Add(self.textCtrl1, proportion = 0, flag=wx.ALIGN_CENTER|wx.EXPAND)
boxSizer1.Add(self.dummy4, proportion = 0, flag=wx.ALIGN_CENTER|wx.EXPAND)
box2 = wx.StaticBox(self.topPanel, wx.ID_ANY, "Win2")
box2.SetForegroundColour('#000000')
self.spacer = wx.StaticText(box2, wx.ID_ANY, "A spacer")
boxSizer2 = wx.StaticBoxSizer(box2, wx.VERTICAL)
boxSizer2.Add(self.spacer, proportion = 0, flag=wx.ALIGN_CENTER|wx.EXPAND)
box3 = wx.StaticBox(self.topPanel, wx.ID_ANY, "Win3")
box3.SetForegroundColour('#000000')
self.dummy1 = wx.StaticText(box3, wx.ID_ANY, "dummy text 1")
boxSizer3 = wx.StaticBoxSizer(box3, wx.VERTICAL)
boxSizer3.Add(self.dummy1, proportion = 0, flag=wx.ALIGN_CENTER|wx.EXPAND)
box4 = wx.StaticBox(self.topPanel, wx.ID_ANY, "Win4")
box4.SetForegroundColour('#000000')
self.textCtrl2 = wx.TextCtrl(box4, wx.ID_ANY,
"This is the second line\nXYZZY\nPLUGH",
wx.DefaultPosition, size = (200,100), style = wx.TE_MULTILINE | wx.TE_READONLY)
boxSizer4 = wx.StaticBoxSizer(box4, wx.VERTICAL)
boxSizer4.Add(self.textCtrl2, proportion = 0, flag=wx.ALIGN_CENTER|wx.EXPAND)
box5 = wx.StaticBox(self.topPanel, wx.ID_ANY, "Win5")
box5.SetForegroundColour('#000000')
self.dummy2 = wx.StaticText(box5, wx.ID_ANY, "dummy text 2")
boxSizer5 = wx.StaticBoxSizer(box5, wx.VERTICAL)
boxSizer5.Add(self.dummy2, proportion = 0, flag=wx.ALIGN_CENTER|wx.EXPAND)
box6 = wx.StaticBox(self.topPanel, wx.ID_ANY, "Win6")
box6.SetForegroundColour('#000000')
self.dummy3 = wx.StaticText(box6, wx.ID_ANY, "dummy text 3")
boxSizer6 = wx.StaticBoxSizer(box6, wx.VERTICAL)
boxSizer6.Add(self.dummy3, proportion = 0, flag=wx.ALIGN_CENTER|wx.EXPAND)
self.topSizer = wx.BoxSizer(wx.VERTICAL)
self.row1Sizer = wx.BoxSizer(wx.HORIZONTAL)
self.row2Sizer = wx.BoxSizer(wx.HORIZONTAL)
self.row3Sizer = wx.BoxSizer(wx.HORIZONTAL)
self.row1Sizer.Add(boxSizer1, 0, wx.ALL, 5)
self.row1Sizer.Add(boxSizer2, 1, wx.ALL|wx.EXPAND, 5) #Matches size of box1
self.row1Sizer.Add(boxSizer3, 0, wx.ALL|wx.EXPAND, 5) #Matches size of box1
self.row2Sizer.Add(boxSizer4, 0, wx.ALL, 5)
self.row2Sizer.Add(boxSizer5, 1, wx.ALL, 5) # Does not match size of box4
self.row3Sizer.Add(boxSizer6, 1, wx.ALL, 5)
self.topSizer.Add(self.row1Sizer, 0, wx.ALL | wx.EXPAND, 5)
self.topSizer.Add(self.row2Sizer, 0, wx.ALL | wx.EXPAND, 5)
self.topSizer.Add(self.row3Sizer, 0, wx.ALL | wx.EXPAND, 5)
self.topPanel.SetSizer(self.topSizer)
self.topPanel.Layout()
def OnClose(self, event):
self.Destroy()
app = wx.App()
top = MyFrame("My Window Layout")
top.Show()
app.MainLoop()
但是,请注意,有时您的操作系统桌面上的主题无法处理盒子,所以它不是给定的!
具体来说,Linux Mint 上的 Mint-X 惨遭失败,与主题 Mint-X 相同的代码看起来像这样。
推荐阅读
- python - 熊猫扩展数据框在应用时返回多个值
- python - 如何使用 python 和 selenium 控制 firefox 多帐户容器?
- javascript - 如何在 useEffect 中调用 prop 函数?
- php - PHP Session 随机死亡
- c++ - 无法将 bind_front_handler 返回值存储在变量中
- android - Android在存储库模式中注入带有刀柄的firebase firestore
- html - Html 数据属性未正确转换为 HtmlHelper 中“jquery.get()”的“成功”部分
- javascript - 反应可点击的下拉菜单
- python - VSCODE 不再检测 python 虚拟环境
- python - 当我尝试使用机器人向不和谐频道发送消息时,出现此错误:RuntimeError: Timeout context manager should be used inside a task