实战wxPython系列-028
从本文开始,我们将介绍GUI程序中常用的一些基本控件,如Button(按钮), CheckBox(复选框), RadioButton(单选按钮), Slider(滑块), ListBox(列表框)等等。
一、wx.Button
wx.Button是包含文本字符串的控件,是GUI中最常见的元素之一。它可以放置在对话框或者wx.Panel面板,以及几乎任何窗口上。
默认情况下,即如果没有指定对齐样式,则标签将水平和垂直居中。如果按钮同时有标签和位图,上面的对齐样式指定了组合了标签和位图的矩形的位置,如果位图位置由
wx.Button.SetBitmapPosition设置,则定义了位图相对于标签的相对位置(目前不是所有平台上都实现了非默认对齐组合)。
一个按钮可以在所有状态下使用一个图像,也可以在以下状态下使用不同的图像(在macOS下,所有状态都使用正常图像,目前不支持不同的图像):
- normal: 默认状态。
- disabled: 禁用按钮时显示的位图。
- pressed: 按下按钮时显示的位图(例如,当用户一直按下鼠标按钮时)。
- focus: 当按钮有键盘焦点时显示位图(但没有按下,因为在这种情况下按钮处于按下状态)。
- current: 当鼠标在按钮上时显示的位图(但它没有被按下,尽管它可能有焦点)。注意,如果没有指定当前位图,但当前平台UI为按钮使用悬停图像(如Windows或GTK+),那么焦点位图也用于悬停状态。这样只需设置焦点位图就可以在所有平台上获得合理的良好行为。
注:在设置位图时,所有的位图必须具有相同的大小,并且必须先设置normal位图(为有效的位图),然后再设置其他位图。此外,如果稍后改变了位图的大小,则需要在使用新图设置任何其他位图之前更改normal位图的大小(并且需要重置所有位图,因为当normal位图大小改变时,它们的原始值可能会丢失)。
使用SetBitmapPosition配置按钮内图像的位置。默认情况下,图像位于文本的左侧。
wx.Button支持以下样式:
- wx.BU_LEFT:标签左对齐(仅限Windows和GTK+)。
- wx.BU_TOP:标签按按钮顶部对齐(仅限Windows和GTK+)。
- wx.BU_RIGHT:标签右对齐(仅限Windows和GTK+)。
- wx.BU_BOTTOM:标签按按钮底部对齐(仅限Windows和GTK+)。
- 内容足够小,可以放入更小的尺寸中。这样做是为了保持一致性,因为大多数平台在本机对话框中使用相同大小的按钮,但可以通过指定此标志来覆盖。如果给出了该参数,则将按钮设置为刚好容纳其内容的大小。请注意,在MSW下,如果按钮的标签是非空的,即使使用这种样式,按钮仍然至少具有标准高度。
- wx.BU_NOTEXT:禁止显示按钮中的文本标签,即使它有一个或它的id是一个标准系统id。
- wx.BORDER_NONE:创建一个没有边框的按钮。
wx.Button发出的事件:
- EVT_BUTTON:当按钮被单击时,处理wx.EVT_BUTTON事件。
wx.Button常用方法:
- static GetDefaultSize(win=None):返回按钮的默认尺寸。
- GetLabel(self):返回按钮的标签信息。
- SetLabel(self, label):设置按钮的标签信息。
- SetDefault(self):将按钮设置为其顶层窗口(例如,包含它的面板或对话框)中的默认项。正常情况下,按return键会导致按下默认按钮。

图1:wx.Button类继承关系
二、wx.Button演示
以下代码演示如何使用wx.Button按钮:
#按钮(wx.Button)
import wx
class SampleButton(wx.Frame):
def __init__(self, *args, **kw):
super(SampleButton, self).__init__(*args, **kw)
self.InitUi()
def InitUi(self):
#设置标题
self.SetTitle("实战wxPython: Button按钮")
#设置窗口尺寸
self.SetSize(360, 240)
panel = wx.Panel(self)
btn_close = wx.Button(panel, label="关闭", pos=(20,20))
btn_close.Bind(wx.EVT_BUTTON, self.OnButtonClose)
self.Centre()
def OnButtonClose(self, e):
self.Close(True)
def main():
app = wx.App()
sample = SampleButton(None)
sample.Show()
app.MainLoop()
if __name__ == "__main__":
main()
运行上面的代码,在窗口中一个”关闭”按钮,点击该按钮,退出程序。

图2. wx.Button 演示
三、wx.ToggleButton
wx.ToggleButton是用户单击时保持按下状态的按钮。换句话说,它类似于wx.CheckBox的功能,但看起来像一个wx.Button。
wx.ToggleButton是一个有两种状态的按钮:按下和未按下。可以通过单击它在这两种状态之间切换。
wx. ToggleButton发出的事件:
- EVT_TOGGLEBUTTON:当按钮被单击时,处理wx.EVT_TOGGLEBUTTON事件。
wx.Button常用方法:
- GetValue(self):获取开关按钮的状态。
- SetValue(self, state):将开关按钮设置为给定状态。这里修改状态不会导致触发EVT_TOGGLEBUTTON事件。

图3:wx.ToggleButton类继承关系
四、wx.ToggleButton演示
以下代码演示如何使用wx.ToggleButton。
#切换按钮(wx.ToggleButton)
import wx
class SampleToggleButton(wx.Frame):
def __init__(self, *args, **kw):
super(SampleToggleButton, self).__init__(*args, **kw)
self.InitUi()
def InitUi(self):
#设置标题
self.SetTitle("实战wxPython: ToggleButton切换按钮")
#设置窗口尺寸
self.SetSize(360, 240)
panel = wx.Panel(self)
self.color = wx.Colour(0, 0, 0)
btn_red = wx.ToggleButton(panel, label="红色", pos = (20, 20))
btn_green = wx.ToggleButton(panel, label="绿色", pos = (20, 60))
btn_blue = wx.ToggleButton(panel, label="蓝色", pos = (20, 100))
self.colorPanel = wx.Panel(panel, pos=(150, 20), size=(110, 110))
self.colorPanel.SetBackgroundColour(self.color)
btn_red.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggleRed)
btn_green.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggleGreen)
btn_blue.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggleBlue)
self.Centre()
def OnToggleRed(self, e):
obj = e.GetEventObject()
isPressed = obj.GetValue()
green = self.color.Green()
blue = self.color.Blue()
if isPressed:
self.color.Set(255, green, blue)
else:
self.color.Set(0, green, blue)
self.colorPanel.SetBackgroundColour(self.color)
self.colorPanel.Refresh()
def OnToggleGreen(self, e):
obj = e.GetEventObject()
isPressed = obj.GetValue()
red = self.color.Red()
blue = self.color.Blue()
if isPressed:
self.color.Set(red, 255, blue)
else:
self.color.Set(red, 0, blue)
self.colorPanel.SetBackgroundColour(self.color)
self.colorPanel.Refresh()
def OnToggleBlue(self, e):
obj = e.GetEventObject()
isPressed = obj.GetValue()
red = self.color.Red()
green = self.color.Green()
if isPressed:
self.color.Set(red, green, 255)
else:
self.color.Set(red, green, 0)
self.colorPanel.SetBackgroundColour(self.color)
self.colorPanel.Refresh()
def main():
app = wx.App()
sample = SampleToggleButton(None)
sample.Show()
app.MainLoop()
if __name__ == "__main__":
main()
运行上述代码,点击”红色”,”绿色”,”蓝色”按钮就可以实现多种颜色显示,图4显示在”红色”和”蓝色”按钮按下的状态下,则显示出粉色。

图4. wx.ToggleButton演示
五、wx.BitmapButton
wx.BitmapButton继承自wx.Button,是一个包含位图的控件。其位图位置支持以下几种样式:
- wx.BU_LEFT:位图左对齐。
- wx.BU_TOP:位图与按钮顶端对齐。
- wx.BU_RIGHT:位图右对齐。
- wx.BU_BOTTOM:位图与按钮底端对齐。

图5:wx.BitmapButton类继承关系
六、wx.BitmapButton演示
下面的代码演示如何使用wx.BitmapButton。
#位图按钮(wx.BitmapButton)
import wx
import os
class Sample(wx.Frame):
def __init__(self, *args, **kw):
super(Sample, self).__init__(*args, **kw)
self.InitUi()
def InitUi(self):
#设置标题
self.SetTitle("实战wxPython: Sample")
#设置窗口尺寸
self.SetSize(360, 240)
panel = wx.Panel(self)
#加载位图
bmp = wx.Image(os.path.dirname(__file__) + "/wxpython.bmp", wx.BITMAP_TYPE_BMP).ConvertToBitmap()
#位图按钮, 默认风格
btnBmp1 = wx.BitmapButton(panel, wx.ID_ANY, bmp, pos = (50, 30))
btnBmp1.Bind(wx.EVT_BUTTON, self.OnClose)
btnBmp1.SetDefault()
self.Centre()
def OnClose(self, e):
self.Close()
def main():
app = wx.App()
sample = Sample(None)
sample.Show()
app.MainLoop()
if __name__ == "__main__":
main()
运行上面的代码,窗口中显示一个位图按钮,点击该按钮,关闭应用。

图6. wx.BitmapButton演示
七、本文知识点
- 了解和使用wx.Button。
- 了解和使用wx.ToggleButton。
- 了解和使用wx.BitmapButton。