让我们慢慢开发一个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()
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)
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()
你会立即注意到,事情变得相当复杂。实际上这是为了帮助我们保持组织。我们将我们的窗口框架移到了它自己的类中,并定义了一些特征。我们请求一个菜单,并将菜单项绑定到关闭应用程序的
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)
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.')
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)
vbox.Add(btn)
vbox.Add(btn2)
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()
那已经好多了!现在让我们看看水平尺寸调整器是什么样子。
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)
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(btn)
hbox.Add(btn2)
panel.SetSizer(hbox)
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.')
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()
我们首先将按钮和文本小部件添加到水平尺寸器中,然后再添加到垂直尺寸器中。在wxPython中,使用尺寸器嵌套尺寸器是非常常见的做法。
__________________________
|__hbox1_|_______________| \
|_hbox2____|______|____|_| \___VBOX
|___hbox3______|_________| /
|_______|__hbox4_|_______| /
有点像这样。在每个hbox中,我们有许多小部件。您可以自行决定要使用多少个小部件。希望这能帮到你。
self
作为第一个关键字添加到框架中来添加面板。这与说(parent=self, id=-1)
是相同的。你可以做frame = wx.Frame(None, -1, 'My Frame')
和panel = wx.Panel(frame, -1)
以保持简单。我向你展示了创建wxPython应用程序的传统方法以及如何将各部分组合在一起。如果你想知道其原因/方法,可以参考API文档。我建议你开始编写简单的GUI程序,你会获得直观的感觉。很抱歉我不能提供更多帮助。 - pedram