总目录:wxPython 教程目录 本节内容:wxPython widgets 部件 本节译自:zetcode 上一篇:wxpython 教程 (六): 对话框 下一篇:wxPython 教程 (八): wxPython 高级 widgets
在本节中,我们将介绍基本的 wxPython widgets。每一个 widget 将会有一个小例子介绍。Widgets 是 应用的基本单元,wxPython 有很多基本 widgets:按钮、选择框、滑动器、列表框等。
本节将介绍以下 wxPython widgets,点击列表项可跳转至相关介绍:
- wx.Button
- wx.ToggleButton
- wx.StaticLine
- wx.StaticText
- wx.StaticBox
- wx.ComboBox
- wx.CheckBox
- wx.StatusBar
- wx.RadioButton
- wx.Gauge
- wx.Slider
- wx.SpinCtrl
wx.Button
wx.Button 是一个简单的 widget,仅包含一个文本字符串,用来触发某个动作。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) cbtn = wx.Button(pnl, label='Close', pos=(20, 30)) cbtn.Bind(wx.EVT_BUTTON, self.OnClose) self.SetSize((250, 200)) self.SetTitle('wx.Button') self.Centre() self.Show(True) def OnClose(self, e): self.Close(True) def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
在样例中,我们创建了一个 Close 按键,点击 Close 即可关闭应用。
cbtn = wx.Button(pnl, label='Close', pos=(20, 30))
在按钮的构造函数中,我们提供了按钮的文本标签以及它在 panel 上的位置。
cbtn.Bind(wx.EVT_BUTTON, self.OnClose)
当点击按钮时 wx.EVT_BUTTON 事件会被触发,我们定义了 OnClose() 方法来处理该事件。
def OnClose(self, e): self.Close(True)
在 OnClose() 函数中,我们调用了 Close() 函数来关闭应用。
图:wx.Button
wx.ToggleButton
wx.ToggleButton 也是一种按钮,但它有两个状态:点击和非点击状态。通过点击按键可以在两种状态中切换。在特定场景中,这一功能将非常适用。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) self.col = wx.Colour(0, 0, 0) rtb = wx.ToggleButton(pnl, label='red', pos=(20, 25)) gtb = wx.ToggleButton(pnl, label='green', pos=(20, 60)) btb = wx.ToggleButton(pnl, label='blue', pos=(20, 100)) self.cpnl = wx.Panel(pnl, pos=(150, 20), size=(110, 110)) self.cpnl.SetBackgroundColour(self.col) rtb.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleRed) gtb.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleGreen) btb.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleBlue) self.SetSize((300, 200)) self.SetTitle('Toggle buttons') self.Centre() self.Show(True) def ToggleRed(self, e): obj = e.GetEventObject() isPressed = obj.GetValue() green = self.col.Green() blue = self.col.Blue() if isPressed: self.col.Set(255, green, blue) else: self.col.Set(0, green, blue) self.cpnl.SetBackgroundColour(self.col) self.cpnl.Refresh() def ToggleGreen(self, e): obj = e.GetEventObject() isPressed = obj.GetValue() red = self.col.Red() blue = self.col.Blue() if isPressed: self.col.Set(red, 255, blue) else: self.col.Set(red, 0, blue) self.cpnl.SetBackgroundColour(self.col) self.cpnl.Refresh() def ToggleBlue(self, e): obj = e.GetEventObject() isPressed = obj.GetValue() red = self.col.Red() green = self.col.Green() if isPressed: self.col.Set(red, green, 255) else: self.col.Set(red, green, 0) self.cpnl.SetBackgroundColour(self.col) self.cpnl.Refresh() def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
我们创建了红色、绿色和蓝色的 Toggle button 和一个 Panel。点击 toggle button的时候,可以改变 panel 的颜色。
rtb = wx.ToggleButton(pnl, label='red', pos=(20, 25))
上面的代码创建了一个 wx.ToggleButton 部件。
self.cpnl = wx.Panel(pnl, pos=(150, 20), size=(110, 110)) self.cpnl.SetBackgroundColour(self.col)
新建了一个 Panel,颜色设置为 self.col。
rtb.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleRed)
当我们点击 rtb 这个触发 button 的时候 ToggleRed() 会被调用。
def ToggleRed(self, e): obj = e.GetEventObject() isPressed = obj.GetValue() green = self.col.Green() blue = self.col.Blue() if isPressed: self.col.Set(255, green, blue) else: self.col.Set(0, green, blue) self.cpnl.SetBackgroundColour(self.col)
在 ToogleRed() 函数里,我们对 rtb 按钮是否被按下做出反应,来改变特定 panel 的颜色。
图:触发按钮
wx.StaticLine
这个 widget 在窗口上展示一个简单的直线,可以是竖直或水平的。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD) heading = wx.StaticText(self, label='The Central Europe', pos=(130, 15)) heading.SetFont(font) wx.StaticLine(self, pos=(25, 50), size=(300,1)) wx.StaticText(self, label='Slovakia', pos=(25, 80)) wx.StaticText(self, label='Hungary', pos=(25, 100)) wx.StaticText(self, label='Poland', pos=(25, 120)) wx.StaticText(self, label='Czech Republic', pos=(25, 140)) wx.StaticText(self, label='Germany', pos=(25, 160)) wx.StaticText(self, label='Slovenia', pos=(25, 180)) wx.StaticText(self, label='Austria', pos=(25, 200)) wx.StaticText(self, label='Switzerland', pos=(25, 220)) wx.StaticText(self, label='5 445 000', pos=(250, 80)) wx.StaticText(self, label='10 014 000', pos=(250, 100)) wx.StaticText(self, label='38 186 000', pos=(250, 120)) wx.StaticText(self, label='10 562 000', pos=(250, 140)) wx.StaticText(self, label='81 799 000', pos=(250, 160)) wx.StaticText(self, label='2 050 000', pos=(250, 180)) wx.StaticText(self, label='8 414 000', pos=(250, 200)) wx.StaticText(self, label='7 866 000', pos=(250, 220)) wx.StaticLine(self, pos=(25, 260), size=(300,1)) tsum = wx.StaticText(self, label='164 336 000', pos=(240, 280)) sum_font = tsum.GetFont() sum_font.SetWeight(wx.BOLD) tsum.SetFont(sum_font) btn = wx.Button(self, label='Close', pos=(140, 310)) btn.Bind(wx.EVT_BUTTON, self.OnClose) self.SetSize((360, 380)) self.SetTitle('wx.StaticLine') self.Centre() self.Show(True) def OnClose(self, e): self.Close(True) def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
上面的脚本展示了中欧的国家和他们的人口, wx.StaticLine 让界面更加美观。
wx.StaticLine(self, pos=(25, 50), size=(300,1))
上面是 wx.StaticLine 的构造函数。
图:wx.StaticLine
wx.StaticText
wx.StaticText 展示一行或多行的只读文本。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): txt1 = '''I'm giving up the ghost of love in the shadows cast on devotion She is the one that I adore creed of my silent suffocation Break this bittersweet spell on me lost in the arms of destiny''' txt2 = '''There is something in the way You're always somewhere else Feelings have deserted me To a point of no return I don't believe in God But I pray for you''' pnl = wx.Panel(self) vbox = wx.BoxSizer(wx.VERTICAL) st1 = wx.StaticText(pnl, label=txt1, style=wx.ALIGN_CENTRE) st2 = wx.StaticText(pnl, label=txt2, style=wx.ALIGN_CENTRE) vbox.Add(st1, flag=wx.ALL, border=5) vbox.Add(st2, flag=wx.ALL, border=5) pnl.SetSizer(vbox) self.SetSize((250, 260)) self.SetTitle('Bittersweet') self.Centre() self.Show(True) def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
在上面的例子中,我们展示了一首 Bittersweet 歌曲的两节歌词。
txt1 = '''I'm giving up the ghost of love in the shadows cast on devotion She is the one that I adore creed of my silent suffocation Break this bittersweet spell on me lost in the arms of destiny'''
上面是要在 wx.StaticText 展示的字符串。
st1 = wx.StaticText(pnl, label=txt1, style=wx.ALIGN_CENTRE)
我们创建了 wx.StaticText 部件,文字被居中展示。
图:wx.StaticText
wx.StaticBox
这是一个装饰部件,被用来逻辑上将一组部件包括起来。需要注意的是,该部件必须在它所包含的部件创建之前创建,且那些被包含的部件是 wx.StaticBox 的兄弟部件而非子部件。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) wx.StaticBox(pnl, label='Personal Info', pos=(5, 5), size=(240, 170)) wx.CheckBox(pnl, label='Male', pos=(15, 30)) wx.CheckBox(pnl, label='Married', pos=(15, 55)) wx.StaticText(pnl, label='Age', pos=(15, 95)) wx.SpinCtrl(pnl, value='1', pos=(55, 90), size=(60, -1), min=1, max=120) btn = wx.Button(pnl, label='Ok', pos=(90, 185), size=(60, -1)) btn.Bind(wx.EVT_BUTTON, self.OnClose) self.SetSize((270, 250)) self.SetTitle('Static box') self.Centre() self.Show(True) def OnClose(self, e): self.Close(True) def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
上面的例子中,我们创建了一个 wx.StaticBox,它装饰了其他的 4 个部件。
图:Static box
wx.ComboBox
wx.ComboBox 是由一行文本域、一个带有下拉箭头图标的按钮和一个列表框所构成的部件。当你按下按钮时,将出现一个列表框,用户只可选择其中的一个选项。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) distros = ['Ubuntu', 'Arch', 'Fedora', 'Debian', 'Mint'] cb = wx.ComboBox(pnl, pos=(50, 30), choices=distros, style=wx.CB_READONLY) self.st = wx.StaticText(pnl, label='', pos=(50, 140)) cb.Bind(wx.EVT_COMBOBOX, self.OnSelect) self.SetSize((250, 230)) self.SetTitle('wx.ComboBox') self.Centre() self.Show(True) def OnSelect(self, e): i = e.GetString() self.st.SetLabel(i) def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
被选择的选项将会显示在文本标签上。
distros = ['Ubuntu', 'Arch', 'Fedora', 'Debian', 'Mint']
单选框将包含以上列表的字符串。
cb = wx.ComboBox(pnl, pos=(50, 30), choices=distros, style=wx.CB_READONLY)
上面代表新建了 wx.ComboBox,通过 choices 参数传入一个字符串列表, wx.CB_READONLY 使得列表的字符串只读,即不可编辑。
cb.Bind(wx.EVT_COMBOBOX, self.OnSelect)
当从单选框选择一个选项时, wx.EVT_COMBOBOX 事件将被触发。我们绑定了 OnSelect() 来处理该事件。
def OnSelect(self, e): i = e.GetString() self.st.SetLabel(i)
从单选框选择一个条目并设置标签文本。
图:wx.ComboBox
wx.CheckBox
wx.CheckBox 只有两个状态:打开或关闭。它有一个框和文本标签组成,文本标签可以设置为放在框的左边或者右边。当 wx.CheckBox 被选择之后,框里将出现一个对号√。
在上面的例子中,我们通过一个 wx.CheckBox 部件来决定是否显示或隐藏窗口的标题。
cb = wx.CheckBox(pnl, label='Show title', pos=(20, 20))
上面是 wx.CheckBox 部件的构造函数。
cb.SetValue(True)
由于窗口的标题应该是被默认显示的,所以我们通过 SetValue() 方法默认选择 wx.CheckBox。
cb.Bind(wx.EVT_CHECKBOX, self.ShowOrHideTitle)
当点击 wx.CheckBox 部件时,wx.EVT_CHECKBOX 事件将被触发,我们将其绑定至事件处理器 ShowOrHideTitle() 函数。
def ShowOrHideTitle(self, e): sender = e.GetEventObject() isChecked = sender.GetValue() if isChecked: self.SetTitle('wx.CheckBox') else: self.SetTitle('')
在 ShowOrHideTitle() 方法中,我们通过 wx.CheckBox 的状态来决定是否隐藏或显示窗口的标题。
图:wx.CheckBox
wx.StatusBar
wx.StatusBar 用来展示应用的状态信息,可以被分成不同的部分来展示不同的信息。我们也可以把其他 widgets 插入到 wx.StatusBar 中。它可以作为 dialog 的替代选择,因为现在 dialog 被滥用,很多用户都不喜欢。我们可以通过两种方式新建 wx.StatusBar。可以直接创建 wx.StatusBar 然后调用 SetStatusBar() 函数,也可以简单的调用 CreateStatusBar() 函数即可,第二种方法创建了一个默认的 wx.StatusBar。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) button = wx.Button(pnl, label='Button', pos=(20, 20)) text = wx.CheckBox(pnl, label='CheckBox', pos=(20, 90)) combo = wx.ComboBox(pnl, pos=(120, 22), choices=['Python', 'Ruby']) slider = wx.Slider(pnl, 5, 6, 1, 10, (120, 90), (110, -1)) pnl.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter) button.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter) text.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter) combo.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter) slider.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter) self.sb = self.CreateStatusBar() self.SetSize((250, 230)) self.SetTitle('wx.Statusbar') self.Centre() self.Show(True) def OnWidgetEnter(self, e): name = e.GetEventObject().GetClassName() self.sb.SetStatusText(name + ' widget') e.Skip() def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
在上面的例子中,我们新建了 wx.Frame 和 5 个其他的 widgets。如果我们把鼠标悬停在 widget 上面,它的名字将会被显示在 wx.StatusBar 上。
pnl.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
当我们的鼠标进入到 widget 的区域时, EVT_ENTER_WINDOW 事件将被触发。
def OnWidgetEnter(self, e): name = e.GetEventObject().GetClassName() self.sb.SetStatusText(name + ' widget') e.Skip()
在 OnWidgetEnter() 函数中,我们得到鼠标进入的 widget 的名字,然后使用 SetStatusText() 方法设置了状态栏的文字。
图:wx.StatusBar
wx.RadioButton
wx.RadioButton 允许用户从一组选项中排他的选择一个唯一选项。通过对第一个 radio 按钮设置 wx.RB_GROUP 样式标记,可以将紧随其后的其他 radio 按钮囊括为一组。随后的 radio 按钮如果也被设置了 wx.RB_GROUP 样式标记,那表明将开始新的一组选择框。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) self.rb1 = wx.RadioButton(pnl, label='Value A', pos=(10, 10), style=wx.RB_GROUP) self.rb2 = wx.RadioButton(pnl, label='Value B', pos=(10, 30)) self.rb3 = wx.RadioButton(pnl, label='Value C', pos=(10, 50)) self.rb1.Bind(wx.EVT_RADIOBUTTON, self.SetVal) self.rb2.Bind(wx.EVT_RADIOBUTTON, self.SetVal) self.rb3.Bind(wx.EVT_RADIOBUTTON, self.SetVal) self.sb = self.CreateStatusBar(3) self.sb.SetStatusText("True", 0) self.sb.SetStatusText("False", 1) self.sb.SetStatusText("False", 2) self.SetSize((210, 210)) self.SetTitle('wx.RadioButton') self.Centre() self.Show(True) def SetVal(self, e): state1 = str(self.rb1.GetValue()) state2 = str(self.rb2.GetValue()) state3 = str(self.rb3.GetValue()) self.sb.SetStatusText(state1, 0) self.sb.SetStatusText(state2, 1) self.sb.SetStatusText(state3, 2) def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
我们创建了一组 3 个 radio 按钮,每个按钮的状态被显示在 statusBar 上。
self.rb1 = wx.RadioButton(pnl, label='Value A', pos=(10, 10), style=wx.RB_GROUP) self.rb2 = wx.RadioButton(pnl, label='Value B', pos=(10, 30)) self.rb3 = wx.RadioButton(pnl, label='Value C', pos=(10, 50))
上面的代码新建了 3 个 radio 按钮,其中第一个被设置了 wx.RB_GROUP 样式,表明接下来的 radio 都将是同一组。
self.rb1.Bind(wx.EVT_RADIOBUTTON, self.SetVal)
我们将 wx.EVT_RADIOBUTTON 事件绑定至 SetVal() 时间处理函数上。
self.sb = self.CreateStatusBar(3) self.sb.SetStatusText("True", 0) self.sb.SetStatusText("False", 1) self.sb.SetStatusText("False", 2)
我们创建了分三部分的 statusbar,并根据对应 radio 的状态设置了初始文字。
def SetVal(self, e): state1 = str(self.rb1.GetValue()) state2 = str(self.rb2.GetValue()) state3 = str(self.rb3.GetValue()) self.sb.SetStatusText(state1, 0) self.sb.SetStatusText(state2, 1) self.sb.SetStatusText(state3, 2)
在 SetVal() 函数中,我们对状态栏的文本进行了更新。
图:wx.RadioButton
wx.Gauge
wx.Gauge 主要用在时间较长的任务场景,用来显示当前任务的状态。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx TASK_RANGE = 50 class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): self.timer = wx.Timer(self, 1) self.count = 0 self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) pnl = wx.Panel(self) vbox = wx.BoxSizer(wx.VERTICAL) hbox1 = wx.BoxSizer(wx.HORIZONTAL) hbox2 = wx.BoxSizer(wx.HORIZONTAL) hbox3 = wx.BoxSizer(wx.HORIZONTAL) self.gauge = wx.Gauge(pnl, range=TASK_RANGE, size=(250, 25)) self.btn1 = wx.Button(pnl, wx.ID_OK) self.btn2 = wx.Button(pnl, wx.ID_STOP) self.text = wx.StaticText(pnl, label='Task to be done') self.Bind(wx.EVT_BUTTON, self.OnOk, self.btn1) self.Bind(wx.EVT_BUTTON, self.OnStop, self.btn2) hbox1.Add(self.gauge, proportion=1, flag=wx.ALIGN_CENTRE) hbox2.Add(self.btn1, proportion=1, flag=wx.RIGHT, border=10) hbox2.Add(self.btn2, proportion=1) hbox3.Add(self.text, proportion=1) vbox.Add((0, 30)) vbox.Add(hbox1, flag=wx.ALIGN_CENTRE) vbox.Add((0, 20)) vbox.Add(hbox2, proportion=1, flag=wx.ALIGN_CENTRE) vbox.Add(hbox3, proportion=1, flag=wx.ALIGN_CENTRE) pnl.SetSizer(vbox) self.SetSize((300, 200)) self.SetTitle('wx.Gauge') self.Centre() self.Show(True) def OnOk(self, e): if self.count >= TASK_RANGE: return self.timer.Start(100) self.text.SetLabel('Task in Progress') def OnStop(self, e): if self.count == 0 or self.count >= TASK_RANGE or not self.timer.IsRunning(): return self.timer.Stop() self.text.SetLabel('Task Interrupted') def OnTimer(self, e): self.count = self.count + 1 self.gauge.SetValue(self.count) if self.count == TASK_RANGE: self.timer.Stop() self.text.SetLabel('Task Completed') def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
我们创建了一个 进度条(gauge)和两个按钮。一个按钮开始走进度条,一个按钮停止走进度条。
self.timer = wx.Timer(self, 1) self.count = 0
我们使用了 wx.Timer 来在特定的时间区间来执行代码,我们将在定义好的时间来更新进度条。 count 变量用来决定目前任务已经完成的比例。
self.gauge = wx.Gauge(pnl, range=TASK_RANGE, size=(250, 25))
上面是 wx.Gauge 部件的构造函数, range 参数定义了该部件最大的整数区间。
def OnOk(self, e): if self.count >= TASK_RANGE: return self.timer.Start(100) self.text.SetLabel('Task in Progress')
当我们点击 OK 按钮时,OnOK() 方法将被调用。首先我们检查 count 变量是否还在任务的整数区间内。如果不在,我们直接返回。如果还在,表明任务还在继续,我们开始 timer 定时器并更新静态文本。
def OnStop(self, e): if self.count == 0 or self.count >= TASK_RANGE or not self.timer.IsRunning(): return self.timer.Stop() self.text.SetLabel('Task Interrupted')
当我们点击 Stop 按钮时,OnStop() 函数将被调用。我们检查了各种条件,符合的话我们停止定时器并更新静态文本。
def OnTimer(self, e): self.count = self.count + 1 self.gauge.SetValue(self.count) if self.count == TASK_RANGE: self.timer.Stop() self.text.SetLabel('Task Completed')
OnTimer() 方法在 timer 开始后被周期调用。在该方法内,我们更新 count 参数和进度条部件。如果 count 等于 TASK_RANGE,我们停止 timer 并更新静态文本。
图:wx.Gauge
wx.Slider
wx.Slider 部件有一个简单的操作柄,可以向前或向后滑动。我们可以使用它完成特定的任务。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) sld = wx.Slider(pnl, value=200, minValue=150, maxValue=500, pos=(20, 20), size=(250, -1), style=wx.SL_HORIZONTAL) sld.Bind(wx.EVT_SCROLL, self.OnSliderScroll) self.txt = wx.StaticText(pnl, label='200', pos=(20, 90)) self.SetSize((290, 200)) self.SetTitle('wx.Slider') self.Centre() self.Show(True) def OnSliderScroll(self, e): obj = e.GetEventObject() val = obj.GetValue() self.txt.SetLabel(str(val)) def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
在 slider 中选择的值将被显示在下面的静态文本中。
sld = wx.Slider(pnl, value=200, minValue=150, maxValue=500, pos=(20, 20), size=(250, -1), style=wx.SL_HORIZONTAL)
上面的代码创建了 wx.Slider。在构造函数中,我们提供了它的初始位置,以及最大、最小的滑动位置,还有设定了它的水平方向。
sld.Bind(wx.EVT_SCROLL, self.OnSliderScroll)
当 wx.EVT_SCROLL 时间被触发的时候,将调用 OnSliderScroll() 函数。
self.txt = wx.StaticText(pnl, label='200', pos=(20, 90))
当前 slider 的值将被显示在下方的静态文本中。
def OnSliderScroll(self, e): obj = e.GetEventObject() val = obj.GetValue() self.txt.SetLabel(str(val))
在 OnSliderScroll() 方法中,我们得到了事件的发送者并得到其当前被选择的值,然后将其设置到静态文本中。
图:wx.Slider
wx.SpinCtrl
wx.SpinCtrl 可以让我们对一个值进行增加或减少,它有两个按钮,一个带向上箭头,一个带向下箭头。用户可以直接输入数值,也可以通过两个箭头来对数值进行上下增减。
#!/usr/bin/python # -*- coding: utf-8 -*- import wx class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): pnl = wx.Panel(self) wx.StaticText(self, label='Convert Fahrenheit temperature to Celsius', pos=(20,20)) wx.StaticText(self, label='Fahrenheit: ', pos=(20, 80)) wx.StaticText(self, label='Celsius: ', pos=(20, 150)) self.celsius = wx.StaticText(self, label='', pos=(150, 150)) self.sc = wx.SpinCtrl(self, value='0', pos=(150, 75), size=(60, -1)) self.sc.SetRange(-459, 1000) btn = wx.Button(self, label='Compute', pos=(70, 230)) btn.SetFocus() cbtn = wx.Button(self, label='Close', pos=(185, 230)) btn.Bind(wx.EVT_BUTTON, self.OnCompute) cbtn.Bind(wx.EVT_BUTTON, self.OnClose) self.SetSize((350, 310)) self.SetTitle('wx.SpinCtrl') self.Centre() self.Show(True) def OnClose(self, e): self.Close(True) def OnCompute(self, e): fahr = self.sc.GetValue() cels = round((fahr - 32) * 5 / 9.0, 2) self.celsius.SetLabel(str(cels)) def main(): ex = wx.App() Example(None) ex.MainLoop() if __name__ == '__main__': main()
上面的脚本将华氏温度转变为摄氏度。我们使用 wx.SpinCtrl 部件供用户来选择华氏温度的值。
self.sc = wx.SpinCtrl(self, value='0', pos=(150, 75), size=(60, -1)) self.sc.SetRange(-459, 1000)
在上面代码中,我们创建了一个初始值为 0 的 wx.SpinCtrl 部件,并通过 SetRange() 方法设置了该部件的取值范围。
def OnCompute(self, e): fahr = self.sc.GetValue() cels = round((fahr - 32) * 5 / 9.0, 2) self.celsius.SetLabel(str(cels))
当我们点击 compute 按钮时,将会调用 OnCompute() 函数。在该函数中,我们获取用户设定的华氏温度值,并计算对应的摄氏温度值,将其更新在静态文本上。
图:wx.SpinCtrl
在本节中,我们主要讲解了各种核心 wxPython 部件。
上一篇:wxpython 教程 (六): 对话框 下一篇:wxPython 教程 (八): wxPython 高级 widgets
您好,我想实现一个功能,就是做一个GUI界面,界面上两个输入框和一个运行按钮。输入框可以输入文本,也可以输入数字。点击运行按钮,运行一个自定义函数,请问有什么好的教程推荐的呢