我正在尝试理解wx
Python,但是大多数文档只是以猴子看猴子的方式呈现程序,而没有解释库的基础知识.
考虑这段代码:
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()
我在这里看到三个容器 –
框架,面板和盒子.
然后有三个按钮.
>有人可以解释哪个容器进入哪个容器?
>面板是否进入框架?如果是这样,它在哪里被添加到框架中?
>盒子怎么样?它会进入面板,还是面板进入面板?
>按钮去了吗?它进入了盒子吗?
>为什么panel.SetSizer()在一个地方使用而box.Add()在另一个地方使用?
最佳答案 让我们慢慢开发一个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的顶部(就像黑板靠在墙上).一旦我们有了一个面板,我们就可以开始添加sizer和小部件了.
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()
那已经好多了!让我们看一下水平sizer的样子.
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?让我们尝试将两者结合起来.我们还需要更多按钮,也许还需要一些TextCtrls.
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()
我们首先将按钮和文本小部件添加到水平测量器,然后再添加到垂直测量器.我们在sizer中有sizer,这是在wxPython中执行操作的一种非常常见的方式.
__________________________
|__hbox1_|_______________| \
|_hbox2____|______|____|_| \___VBOX
|___hbox3______|_________| /
|_______|__hbox4_|_______| /
有点像那样.在每个hbox中,我们都有许多小部件.由你决定你想要多少.希望这可以帮助.