Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.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基金会_Python_Wxpython_Wxwidgets - Fatal编程技术网

wxPython基金会

wxPython基金会,python,wxpython,wxwidgets,Python,Wxpython,Wxwidgets,我试图理解wxPython,但是大多数文档只是以猴子见猴子的方式展示程序,没有解释库的基本原理 考虑以下代码片段: import wx class MyFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, (-1, -1), wx.Size(250, 50)) panel = wx.Panel(self, -1)

我试图理解wxPython,但是大多数文档只是以猴子见猴子的方式展示程序,没有解释库的基本原理

考虑以下代码片段:

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, (-1, -1), wx.Size(250, 50))
        panel = wx.Panel(self, -1)
        box = wx.BoxSizer(wx.HORIZONTAL)
        box.Add(wx.Button(panel, -1, 'Button1'), 1 )
        box.Add(wx.Button(panel, -1, 'Button2'), 1 )
        box.Add(wx.Button(panel, -1, 'Button3'), 1 )
        panel.SetSizer(box)
        self.Centre()

class MyApp(wx.App):
     def OnInit(self):
         frame = MyFrame(None, -1, 'wxboxsizer.py')
         frame.Show(True)
         return True

app = MyApp(0)
app.MainLoop()
我看到这里有三个集装箱- 框架、面板和盒子

还有三个按钮

import wx

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(Frame, self).__init__(*args, **kwargs)

        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quits application')
        menubar.Append(fileMenu, '&File')
        self.SetMenuBar(menubar)

        self.Bind(wx.EVT_MENU, self.OnQuit, fitem)

        panel = wx.Panel(self, -1)
        btn = wx.Button(panel, label='I am a closing button.') # Add a button
        btn.Bind(wx.EVT_BUTTON, self.OnQuit) # Bind the first button to quit
        btn2 = wx.Button(panel, label='I am a do nothing button.') # Add a second

        self.Show()

    def OnQuit(self, e):
        self.Close()

app = wx.App()
Frame(None, -1, 'A Frame', style=wx.RESIZE_BORDER 
    | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX)
app.MainLoop()
  • 有人能解释一下哪个容器放在哪个容器里吗
  • 面板是否进入框架?如果是,它将添加到框架的何处
  • 盒子呢?它进入面板还是面板进入面板
  • 按钮是怎么开的?它在盒子里吗
  • 为什么panel.SetSizer()在一个地方使用,box.Add()在另一个地方使用
    wxPython很复杂,但其他GUI工具包也很复杂。让我们把它分解一下。要回答第一个问题,wxPython GUI的常规布局如下所示:

    frame -> panel -> sizer -> widgets
    frame -> sizer -> panel -> sizer -> widgets
    
    我通常和第一个一起去。如果布局复杂,我可能会嵌套尺寸器,因此我最终会得到如下结果:

    frame -> panel -> sizer -> sizer1 -> widgets
                            -> sizer2 -> widgets
    
    2) 第一个面板应始终作为其唯一小部件添加到框架中:

    wx.Frame.__init__(self, None, title="Test")
    panel = wx.Panel(self)
    
    3) boxSizer通常进入面板。我通常会给面板一个顶级的boxSizer,然后在面板内部创建嵌套的Sizer


    4) 按钮和其他小部件会同时出现在面板和sizer中!您将按钮的父级设置为面板,然后要在面板中布局小部件,您将它们放置在面板的sizer对象中。如果将按钮的父项设置为帧,则会出现混乱

    5) SetSizer用于告诉wxPython sizer属于哪个小部件。在代码中,为面板提供了box sizer实例。sizer对象的Add()方法用于将小部件(和sizer)添加到sizer本身


    我希望这能回答你所有的问题。您可能还会发现下面的文章很有用,因为它链接到了我用于wx的大多数文档:

    让我们慢慢开发一个wxPython应用程序,看看它是如何工作的

    这是创建wxPython应用程序所需的最少代码量。它包含一个wx.Frame(您可以将其理解为一个窗口)。窗户里什么也没有。app.MainLoop()是捕获任何事件(如鼠标单击、关闭或最小化窗口)的循环

    import wx
    
    app = wx.App()
    
    frame = wx.Frame(None, -1, 'A Frame')
    frame.Show()
    
    app.MainLoop()
    
    窗口本身不是很有趣,但仍然相当强大。我们可以添加诸如菜单项和标题之类的内容,甚至可以选择诸如无最大化按钮之类的样式。让我们做所有这些

    import wx
    
    class Frame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super(Frame, self).__init__(*args, **kwargs)
    
            menubar = wx.MenuBar() # Create a menubar
            fileMenu = wx.Menu() # Create the file menu
            fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quits application') # Add a quit line
            menubar.Append(fileMenu, '&File') # Add the File menu to the Menubar
            self.SetMenuBar(menubar) # Set the menubar as THE menu bar
    
            self.Bind(wx.EVT_MENU, self.OnQuit, fitem) # Bind the quit line
    
            self.Show() # Show the frame
    
        def OnQuit(self, e):
            self.Close()
    
    app = wx.App()
    Frame(None, -1, 'A Frame', style=wx.RESIZE_BORDER 
        | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX) # Some styles
    app.MainLoop()
    
    你会发现事情很快就变得复杂了。这实际上是为了帮助我们保持组织性。我们将框架移动到它自己的类中,并定义了一些特征。我们需要一个菜单,将菜单项绑定到关闭应用程序的
    OnQuit()
    方法。这是最基本的一层

    让我们添加一个面板。面板就像黑板。它位于wx.Frame的顶部(就像一块黑板靠在墙上)。一旦我们有了一个面板,我们就可以开始添加大小器和小部件

    import wx
    
    class Frame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super(Frame, self).__init__(*args, **kwargs)
    
            menubar = wx.MenuBar()
            fileMenu = wx.Menu()
            fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quits application')
            menubar.Append(fileMenu, '&File')
            self.SetMenuBar(menubar)
    
            self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
    
            panel = wx.Panel(self, -1) # Added a panel!
    
            self.Show()
    
        def OnQuit(self, e):
            self.Close()
    
    app = wx.App()
    Frame(None, -1, 'A Frame', style=wx.RESIZE_BORDER 
        | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX)
    app.MainLoop()
    
    您会注意到,根据平台的不同,会有细微的差异。窗口现在已填充,颜色较浅。那是我们的小组。现在让我们添加一些按钮

    import wx
    
    class Frame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super(Frame, self).__init__(*args, **kwargs)
    
            menubar = wx.MenuBar()
            fileMenu = wx.Menu()
            fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quits application')
            menubar.Append(fileMenu, '&File')
            self.SetMenuBar(menubar)
    
            self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
    
            panel = wx.Panel(self, -1)
            btn = wx.Button(panel, label='I am a closing button.') # Add a button
            btn.Bind(wx.EVT_BUTTON, self.OnQuit) # Bind the first button to quit
            btn2 = wx.Button(panel, label='I am a do nothing button.') # Add a second
    
            self.Show()
    
        def OnQuit(self, e):
            self.Close()
    
    app = wx.App()
    Frame(None, -1, 'A Frame', style=wx.RESIZE_BORDER 
        | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX)
    app.MainLoop()
    
    现在我们有了面板上的按钮。但它们看起来很糟糕。他们一个接一个地被卡住了。我们可以使用pos=(x,y)属性手动定位它们,但这非常繁琐。让我们叫我们的朋友boxsizer来

    import wx
    
    class Frame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super(Frame, self).__init__(*args, **kwargs)
    
            menubar = wx.MenuBar()
            fileMenu = wx.Menu()
            fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quits application')
            menubar.Append(fileMenu, '&File')
            self.SetMenuBar(menubar)
    
            self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
    
            panel = wx.Panel(self, -1)
            btn = wx.Button(panel, label='I am a closing button.')
            btn.Bind(wx.EVT_BUTTON, self.OnQuit)
            btn2 = wx.Button(panel, label='I am a do nothing button.')
    
            vbox = wx.BoxSizer(wx.VERTICAL) # Create a vertical boxsizer
            vbox.Add(btn) # Add button 1 to the sizer
            vbox.Add(btn2) # Add button 2 to the sizer
    
            panel.SetSizer(vbox) # Tell the panel to use this sizer as its sizer. 
    
            self.Show()
    
        def OnQuit(self, e):
            self.Close()
    
    app = wx.App()
    Frame(None, -1, 'A Frame', style=wx.RESIZE_BORDER 
        | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX)
    app.MainLoop()
    
    那已经好多了!让我们看看水平测径仪是什么样子

    import wx
    
    class Frame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super(Frame, self).__init__(*args, **kwargs)
    
            menubar = wx.MenuBar()
            fileMenu = wx.Menu()
            fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quits application')
            menubar.Append(fileMenu, '&File')
            self.SetMenuBar(menubar)
    
            self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
    
            panel = wx.Panel(self, -1)
            btn = wx.Button(panel, label='I am a closing button.')
            btn.Bind(wx.EVT_BUTTON, self.OnQuit)
            btn2 = wx.Button(panel, label='I am a do nothing button.')
    
            vbox = wx.BoxSizer(wx.VERTICAL) # A vertical sizer
            hbox = wx.BoxSizer(wx.HORIZONTAL) # And a horizontal one?? but why?
            hbox.Add(btn) # Let's add the buttons first
            hbox.Add(btn2)
    
            panel.SetSizer(hbox) # see why we need to tell the panel which sizer to use? We might have two!
    
            self.Show()
    
        def OnQuit(self, e):
            self.Close()
    
    app = wx.App()
    Frame(None, -1, 'A Frame', style=wx.RESIZE_BORDER 
        | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX)
    app.MainLoop()
    
    有趣!注意到我是如何保存我们的vbox的吗?让我们试着把两者结合起来。我们需要更多的按钮,也许还需要一些文本控件

    import wx
    
    class Frame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super(Frame, self).__init__(*args, **kwargs)
    
            menubar = wx.MenuBar()
            fileMenu = wx.Menu()
            fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quits application')
            menubar.Append(fileMenu, '&File')
            self.SetMenuBar(menubar)
    
            self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
    
            panel = wx.Panel(self, -1)
            btn = wx.Button(panel, label='I am a closing button.')
            btn.Bind(wx.EVT_BUTTON, self.OnQuit)
            btn2 = wx.Button(panel, label='I am a do nothing button.')
            txt1 = wx.TextCtrl(panel, size=(140,-1))
            txt2 = wx.TextCtrl(panel, size=(140,-1))
            txt3 = wx.TextCtrl(panel, size=(140,-1))
            btn3 = wx.Button(panel, label='I am a happy button.')
            btn4 = wx.Button(panel, label='I am a bacon button.')
            btn5 = wx.Button(panel, label='I am a python button.')
    
    
            # So many sizers! 
            vbox = wx.BoxSizer(wx.VERTICAL) 
            hbox1 = wx.BoxSizer(wx.HORIZONTAL)
            hbox2 = wx.BoxSizer(wx.HORIZONTAL)
            hbox3 = wx.BoxSizer(wx.HORIZONTAL)
            hbox4 = wx.BoxSizer(wx.HORIZONTAL)
            hbox1.Add(btn)
            hbox1.Add(btn2)
            hbox1.Add(txt1)
            hbox2.Add(txt2)
            hbox2.Add(txt3)
            hbox2.Add(btn3)
            hbox3.Add(btn4)
            hbox4.Add(btn5)
            vbox.Add(hbox1)
            vbox.Add(hbox2)
            vbox.Add(hbox3)
            vbox.Add(hbox4)
    
            panel.SetSizer(vbox)
    
            self.Show()
    
        def OnQuit(self, e):
            self.Close()
    
    app = wx.App()
    Frame(None, -1, 'A Frame', style=wx.RESIZE_BORDER 
        | wx.SYSTEM_MENU | wx.CAPTION |  wx.CLOSE_BOX)
    app.MainLoop()
    
    我们首先将按钮和文本小部件添加到水平尺寸器,然后再添加到垂直尺寸器。我们在sizers中有sizers,这是wxPython中一种非常常见的操作方式

    __________________________
    |__hbox1_|_______________|  \
    |_hbox2____|______|____|_|   \___VBOX
    |___hbox3______|_________|   /
    |_______|__hbox4_|_______|  /
    

    有点像这样。在每个hbox中,我们都有许多小部件。取决于你想要多少。希望这有帮助

    我强烈建议你拿一本诺埃尔·拉平和罗宾·邓恩的《哈利·波特》。由于Robin是wxPython的主要作者/架构师之一,您将获得非常好的见解和清晰的解释


    N.B.在任何人问我之前,我绝对与这本书、作者或出版商没有商业联系。

    “按钮和其他小部件都在面板和大小器中”-你能解释一下这是什么意思吗?什么是sizer?它不是一个容器吗?sizer就像一个看不见的容器,它定位和调整它包含的小部件,它就像父部件和子部件之间的粘合剂。是的。面板是父级,但大小调整器控制小部件的定位方式以及是否拉伸。如果你没有将小部件放在面板上,那么标签可能无法正常工作。干得好!我应该在我的答案上花更多的时间。我为你写的代码,不是复制粘贴的。面板通过提供
    self
    作为第一个关键字添加到框架中。这等同于说
    (parent=self,id=-1)
    。您可以执行
    frame=wx.frame(无,-1,“我的框架”)
    panel=wx.panel(frame,-1)
    来保持简单。我将向您展示创建wxPython应用程序的传统方法,以及这些应用程序是如何组合在一起的。如果您想知道原因/方式,可以参考API文档。我的建议是开始编写简单的GUI程序,这样您将对工作方式有一个直观的了解。对不起,我帮不上什么忙。如果你真的写了那么多代码,我道歉。它看起来和我读过的另一篇教程非常相似。你可能指的是Zetcode的网站,这是我学习wxPython的地方。从那以后我一直在使用他的基本模板。创建wxFrame的基本方法相当通用。我知道Mike的应用程序有一个稍微不同的模板,(我不认为他使用*args,**kwargs),但我怀疑有什么真正的区别,我相信他的模板会适合你需要做的任何事情。wxpythonwiki