转自:http://thisis.yorven.site/blog/index.php/2017/09/23/wxpython-jiaocheng-widgets/#wxButton 在本节中,我们将介绍基本的 wxPython widgets。每一个 widget 将会有一个小例子介绍。Widgets 是 应用的基本单元,wxPython 有很多基本 widgets:按钮、选择框、滑动器、列表框等。
wx.Button 是一个简单的 widget,仅包含一个文本字符串,用来触发某个动作。
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.ToggleButton 也是一种按钮,但它有两个状态:点击和非点击状态。通过点击按键可以在两种状态中切换。在特定场景中,这一功能将非常适用。
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 在窗口上展示一个简单的直线,可以是竖直或水平的。
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.StaticText wx.StaticText 展示一行或多行的只读文本。
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.StaticBox 这是一个装饰部件,被用来逻辑上将一组部件包括起来。需要注意的是,该部件必须在它所包含的部件创建之前创建,且那些被包含的部件是 wx.StaticBox 的兄弟部件而非子部件。
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 个部件。
wx.ComboBox wx.ComboBox 是由一行文本域、一个带有下拉箭头图标的按钮和一个列表框所构成的部件。当你按下按钮时,将出现一个列表框,用户只可选择其中的一个选项。
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.CheckBox wx.CheckBox 只有两个状态:打开或关闭。它有一个框和文本标签组成,文本标签可以设置为放在框的左边或者右边。当 wx.CheckBox 被选择之后,框里将出现一个对号√。
在上面的例子中,我们通过一个 wx.CheckBox 部件来决定是否显示或隐藏窗口的标题。
cb = wx.CheckBox(pnl, label='Show title', pos=(20, 20))
上面是 wx.CheckBox 部件的构造函数。
由于窗口的标题应该是被默认显示的,所以我们通过 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.StatusBar wx.StatusBar 用来展示应用的状态信息,可以被分成不同的部分来展示不同的信息。我们也可以把其他 widgets 插入到 wx.StatusBar 中。它可以作为 dialog 的替代选择,因为现在 dialog 被滥用,很多用户都不喜欢。我们可以通过两种方式新建 wx.StatusBar。可以直接创建 wx.StatusBar 然后调用 SetStatusBar() 函数,也可以简单的调用 CreateStatusBar() 函数即可,第二种方法创建了一个默认的 wx.StatusBar。
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.RadioButton 允许用户从一组选项中排他的选择一个唯一选项。通过对第一个 radio 按钮设置 wx.RB_GROUP 样式标记,可以将紧随其后的其他 radio 按钮囊括为一组。随后的 radio 按钮如果也被设置了 wx.RB_GROUP 样式标记,那表明将开始新的一组选择框。
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.Gauge wx.Gauge 主要用在时间较长的任务场景,用来显示当前任务的状态。
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.Slider wx.Slider 部件有一个简单的操作柄,可以向前或向后滑动。我们可以使用它完成特定的任务。
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.SpinCtrl wx.SpinCtrl 可以让我们对一个值进行增加或减少,它有两个按钮,一个带向上箭头,一个带向下箭头。用户可以直接输入数值,也可以通过两个箭头来对数值进行上下增减。
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() 函数。在该函数中,我们获取用户设定的华氏温度值,并计算对应的摄氏温度值,将其更新在静态文本上。 在本节中,我们主要讲解了各种核心 wxPython 部件。