Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
wxPython:sizers,grids快把我逼疯了_Python_User Interface_Wxpython - Fatal编程技术网

wxPython:sizers,grids快把我逼疯了

wxPython:sizers,grids快把我逼疯了,python,user-interface,wxpython,Python,User Interface,Wxpython,我正在学习wxPython,我正在尝试编写一个学生信息管理器。我已经编写CLI程序很多年了,所以我没有多少制作GUI的经验 首先,我为我的UI绘制了一个蓝图。 然后,我试图在wxPython取得成功,但施胶机真的让我抓狂。我以前从未用过任何一种浆纱机!(VisualBasic是我学的第一门语言) 最后,我写了以下代码: import wx from wx.lib import sheet class Sheet(sheet.CSheet): def __init__(self, p

我正在学习wxPython,我正在尝试编写一个学生信息管理器。我已经编写CLI程序很多年了,所以我没有多少制作GUI的经验

首先,我为我的UI绘制了一个蓝图。

然后,我试图在wxPython取得成功,但施胶机真的让我抓狂。我以前从未用过任何一种浆纱机!(VisualBasic是我学的第一门语言)

最后,我写了以下代码:

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()
但这个程序既丑陋又有缺陷。有人能教我如何用智能的方式使用测码器,并帮我修改代码吗


非常感谢

首先,我必须删除您的
addgrowtablecolumn()
addgrowtablerow()
行,因为它们给了我错误。我阅读了这些函数的示例,我认为您不想调用它们(但只有您知道您希望UI的外观)

实际上,你似乎对浆纱机有很好的理解。问题是
MainPanel
不知道
MainFrame
的大小,因此部分用户界面被切断。解决这个问题非常简单,您有两个选择

选项1
大型机中,将
面板放置在一个测码器内。这将允许sizer根据
大型机的大小设置
面板的大小。目前,它们的大小之间没有联系。更改如下所示:

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()
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()
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()
选项2
大型机
中只有一个对象,一个
主面板
。那么,为什么不将这两个类合并为一个呢?只需将
MainPane1
中的所有代码添加到
MainPanel
中,然后删除
MainPanel
。重要的部分是
MainPanel.\uuu init\uuu()
调用
SetSizer()
。如果您将代码移动到大型机中。\uuuu init\uuuu()
,那么您仍然完全按照我在选项1中的建议执行,但是您少了一个类。看起来是这样的:

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()
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()
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()
最后,我不喜欢使用
wx.GridBagSizer
。我更喜欢使用嵌套的
wx.BoxSizer
对象。我发现我得到了更多的控制,它允许我从代码中直观地看到我的UI将是什么样子,因为我正在将UI分解成更小的块。但是,这是个人偏好的问题,您应该使用您理解并熟悉的任何方法。看你的蓝图,我看到有两列。所以首先我们需要一个sizer来处理这些列。然后,每列可以分成两行。按钮还需要一个浆纱器来固定。。代码如下所示:

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()
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()
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()

我知道你的感受,所以现在很多人都明白你的沮丧。。。为了理解sizers,我试着阅读了很多关于sizers的文档,但我最终还是把它当成了HTML中的CSS,所以读了这篇文章和后面的页面,我发现它非常好地解释了CSS,它与sizers的布局模型是一样的。。。。我不敢相信我记得那个链接已经有一段时间了,我读过了,猜它表明它是一个很好的营销。谢谢。但我仍然有两个问题:1。当用户调整窗口大小时,我希望小部件更改其大小。2.框架中的三个按钮占用了太多的空间,我希望它们看起来像我的蓝图一样简单。然后你需要把按钮变小。创建按钮时,必须设置按钮的大小。除此之外,
wx.EXPAND
标志应该意味着其他所有内容都会随窗口调整大小。谢谢。嵌套大小器非常有用@比尔盖子 刚开始的时候它们有点难,但一旦你学会了如何使用它们,定径器就会非常强大。你也应该读书。太好了。我还把WxPython带到阿克顿。