我正在学习wxPython,我正在努力写一个学生信息管理员。我已经编写了多年的CLI程序,所以我没有太多制作GUI的经验。
首先,我为我的UI绘制了蓝图。
然后,我试图在wxPython中制作它,但是sizer真的让我发疯了。我之前从未使用任何类型的sizer! (Visual Basic是我学过的第一种语言^ __ ^)
最后,我写了这些代码:
import wx
from wx.lib import sheet
class Sheet(sheet.CSheet):
def __init__(self, parent, row, col):
sheet.CSheet.__init__(self, parent)
self.row = self.col = 0
self.SetNumberRows(row)
self.SetNumberCols(col)
for i in range(row):
self.SetRowSize(i, 20)
class ChartPanel(wx.Panel):
'''This is the panel for the chart, but the still working on it. '''
def __init__(self, parent):
wx.Panel.__init__(self, parent)
class MainPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.GridBagSizer(5, 5)
# However, just put the chart into main frame.
chart = ChartPanel(self)
chart.SetBackgroundColour("blue")
Students = Sheet(self, 5, 2)
History = Sheet(self, 2, 2)
button1 = wx.Button(self, label="Button #1")
button2 = wx.Button(self, label="Button #2")
button3 = wx.Button(self, label="Button #3")
sizer.Add(Students, pos=(0, 0), span=(5, 2), flag=wx.EXPAND)
sizer.Add(History, pos=(0, 2), span=(2, 2), flag=wx.EXPAND)
sizer.Add(chart, pos=(2, 2), span=(3, 2), flag=wx.EXPAND)
sizer.Add(button1, pos=(5, 0), span=(1, 1))
sizer.Add(button2, pos=(5, 1), span=(1, 1))
sizer.Add(button3, pos=(5, 2), span=(1, 1))
sizer.AddGrowableCol(5)
sizer.AddGrowableRow(5)
self.SetSizer(sizer)
self.Fit()
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="BoxSizer Example")
panel = MainPanel(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
app.MainLoop()
但是这个程序很丑陋而且有缺陷。有人可以教我如何以聪明的方式使用sizer,并帮我修改我的代码吗?
非常感谢!
答案 0 :(得分:2)
首先,我必须删除您的AddGrowableColumn()
和AddGrowableRow()
行,因为它们给了我错误。我为这些功能阅读documentation,我认为你不想打电话给他们(但只有你知道你希望你的UI看起来如何)。
你似乎对sizer有很好的把握。问题是MainPanel
不知道MainFrame
的大小,因此部分UI被截断。修复此问题非常简单,您有两种选择。
选项1
在MainFrame.__init__()
中,将panel
放在sizer中。这将允许sizer根据panel
的大小设置MainFrame
的大小。现在他们的尺寸之间没有联系。变化将如下所示:
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="BoxSizer Example")
panel = MainPanel(self)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(panel)
self.SetSizer(sizer) #this allows panel and MainFrame to influence each other's sizes
self.Show()
self.Fit()
选项2
MainFrame
只有一个对象,MainPanel
。那么为什么不将这两个类合二为一呢?只需将MainPane1
中的所有代码添加到MainFrame
,然后删除MainPanel
即可。重要的是MainPanel.__init__()
调用SetSizer()
。如果您将该代码移动到MainFrame.__init__()
,那么您仍然可以完全按照我在选项1中的建议进行操作,但是您只需要少一个类。这看起来像这样:
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="BoxSizer Example")
sizer = wx.GridBagSizer(5, 5)
# However, just put the chart into main frame.
chart = ChartPanel(self)
chart.SetBackgroundColour("blue")
Students = Sheet(self, 5, 2)
History = Sheet(self, 2, 2)
button1 = wx.Button(self, label="Button #1")
button2 = wx.Button(self, label="Button #2")
button3 = wx.Button(self, label="Button #3")
sizer.Add(Students, pos=(0, 0), span=(5, 2), flag=wx.EXPAND)
sizer.Add(History, pos=(0, 2), span=(2, 2), flag=wx.EXPAND)
sizer.Add(chart, pos=(2, 2), span=(3, 2), flag=wx.EXPAND)
sizer.Add(button1, pos=(5, 0), span=(1, 1))
sizer.Add(button2, pos=(5, 1), span=(1, 1))
sizer.Add(button3, pos=(5, 2), span=(1, 1))
#I removed these lines because they gave me errors and I don't understand why you needed them
#sizer.AddGrowableCol(5)
#sizer.AddGrowableRow(5)
self.SetSizer(sizer)
self.Fit()
self.Show()
最后,我不喜欢使用wx.GridBagSizer
。我更喜欢使用嵌套的wx.BoxSizer
对象。我发现我得到了更多的控制权,它允许我从代码中可视化我的UI看起来像是因为我将UI分解成更小的块。但是,这是个人偏好的问题,你应该使用你理解的任何方法并且习惯。看看你的蓝图,我看到有两列。所以首先我们需要一个sizer来处理这些列。然后,每列可以分成两行。按钮需要一个sizer来保存它们。代码看起来像这样:
def __init__(self, parent):
wx.Panel.__init__(self, parent)
mainSizer = wx.BoxSizer(wx.HORIZONTAL) #this will make the columns
rightSizer = wx.BoxSizer(wx.VERTICAL) #this will be the rows on the right
# However, just put the chart into main frame.
chart = ChartPanel(self)
chart.SetBackgroundColour("blue")
History = Sheet(self, 2, 2)
rightSizer.Add(History, 1, wx.EXPAND)
rightSizer.Add(chart, 1, wx.EXPAND)
leftSizer = wx.BoxSizer(wx.VERTICAL) #this will be the rows on the left
Students = Sheet(self, 5, 2)
buttonSizer = wx.BoxSizer(wx.HORIZONTAL) #this will organize the buttons
button1 = wx.Button(self, label="Button #1")
button2 = wx.Button(self, label="Button #2")
button3 = wx.Button(self, label="Button #3")
buttonSizer.Add(button1)
buttonSizer.Add(button2)
buttonSizer.Add(button3)
leftSizer.Add(Students, 1, wx.EXPAND)
leftSizer.Add(buttonSizer)
mainSizer.Add(leftSizer, 1, wx.EXPAND)
mainSizer.Add(rightSizer, 1, wx.EXPAND)
self.SetSizer(mainSizer)
self.Fit()