原文: http://zetcode.com/wxpython/widgets/

在本节中,我们将介绍 wxPython 中的基本小部件。 每个小部件都有一个小的代码示例。 小部件是应用的基本构建块。 wxPython 有各种各样的小部件,包括按钮,复选框,滑块和列表框。

wx.Button

wx.Button是一个简单的小部件。 它包含一个文本字符串。 用于触发动作。

button_wid.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this code example, we create a
  6. button widget.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, *args, **kw):
  14. super(Example, self).__init__(*args, **kw)
  15. self.InitUI()
  16. def InitUI(self):
  17. pnl = wx.Panel(self)
  18. closeButton = wx.Button(pnl, label='Close', pos=(20, 20))
  19. closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
  20. self.SetSize((350, 250))
  21. self.SetTitle('wx.Button')
  22. self.Centre()
  23. def OnClose(self, e):
  24. self.Close(True)
  25. def main():
  26. app = wx.App()
  27. ex = Example(None)
  28. ex.Show()
  29. app.MainLoop()
  30. if __name__ == '__main__':
  31. main()

在代码示例中,我们创建一个“关闭”按钮,当按下该按钮时,它将终止应用。

  1. cbtn = wx.Button(pnl, label='Close', pos=(20, 20))

wx.Button小部件已创建。 在小部件的构造器中,我们提供按钮的标签和面板上的位置。

  1. cbtn.Bind(wx.EVT_BUTTON, self.OnClose)

当我们单击按钮时,将触发wx.EVT_BUTTON事件。 我们为事件指定事件处理器。

  1. def OnClose(self, e):
  2. self.Close(True)

OnClose()方法中,我们使用Close()方法终止应用。

小部件 - 图1

图:wx.Button

wx.ToggleButton

wx.ToggleButton是具有两种状态的按钮:已按下和未按下。 通过单击可以在这两种状态之间切换。 在某些情况下此功能非常合适。

toggle_buttons.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this code example, we create three
  6. toggle button widgets.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: April 2018
  10. """
  11. import wx
  12. class Example(wx.Frame):
  13. def __init__(self, *args, **kw):
  14. super(Example, self).__init__(*args, **kw)
  15. self.InitUI()
  16. def InitUI(self):
  17. pnl = wx.Panel(self)
  18. self.col = wx.Colour(0, 0, 0)
  19. rtb = wx.ToggleButton(pnl, label='red', pos=(20, 25))
  20. gtb = wx.ToggleButton(pnl, label='green', pos=(20, 60))
  21. btb = wx.ToggleButton(pnl, label='blue', pos=(20, 100))
  22. self.cpnl = wx.Panel(pnl, pos=(150, 20), size=(110, 110))
  23. self.cpnl.SetBackgroundColour(self.col)
  24. rtb.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleRed)
  25. gtb.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleGreen)
  26. btb.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleBlue)
  27. self.SetSize((350, 250))
  28. self.SetTitle('Toggle buttons')
  29. self.Centre()
  30. def ToggleRed(self, e):
  31. obj = e.GetEventObject()
  32. isPressed = obj.GetValue()
  33. green = self.col.Green()
  34. blue = self.col.Blue()
  35. if isPressed:
  36. self.col.Set(255, green, blue)
  37. else:
  38. self.col.Set(0, green, blue)
  39. self.cpnl.SetBackgroundColour(self.col)
  40. self.cpnl.Refresh()
  41. def ToggleGreen(self, e):
  42. obj = e.GetEventObject()
  43. isPressed = obj.GetValue()
  44. red = self.col.Red()
  45. blue = self.col.Blue()
  46. if isPressed:
  47. self.col.Set(red, 255, blue)
  48. else:
  49. self.col.Set(red, 0, blue)
  50. self.cpnl.SetBackgroundColour(self.col)
  51. self.cpnl.Refresh()
  52. def ToggleBlue(self, e):
  53. obj = e.GetEventObject()
  54. isPressed = obj.GetValue()
  55. red = self.col.Red()
  56. green = self.col.Green()
  57. if isPressed:
  58. self.col.Set(red, green, 255)
  59. else:
  60. self.col.Set(red, green, 0)
  61. self.cpnl.SetBackgroundColour(self.col)
  62. self.cpnl.Refresh()
  63. def main():
  64. app = wx.App()
  65. ex = Example(None)
  66. ex.Show()
  67. app.MainLoop()
  68. if __name__ == '__main__':
  69. main()

我们有红色,绿色和蓝色的切换按钮和一个面板。 我们通过单击切换按钮来更改面板的颜色。

  1. rtb = wx.ToggleButton(pnl, label='red', pos=(20, 25))

wx.ToggleButton小部件已创建。

  1. self.cpnl = wx.Panel(pnl, pos=(150, 20), size=(110, 110))
  2. self.cpnl.SetBackgroundColour(self.col)

这是一个面板的颜色,我们将使用切换按钮对其进行修改。

  1. rtb.Bind(wx.EVT_TOGGLEBUTTON, self.ToggleRed)

当我们单击rtb切换按钮时,将调用ToggleRed()事件处理器。

  1. def ToggleRed(self, e):
  2. obj = e.GetEventObject()
  3. isPressed = obj.GetValue()
  4. green = self.col.Green()
  5. blue = self.col.Blue()
  6. if isPressed:
  7. self.col.Set(255, green, blue)
  8. else:
  9. self.col.Set(0, green, blue)
  10. self.cpnl.SetBackgroundColour(self.col)

ToggleRed()方法中,我们对按下rtb按钮这一事实作出反应。 我们找出颜色部分并更新颜色面板的颜色。

小部件 - 图2

图:开关按钮

wx.StaticText

wx.StaticText小部件显示一行或多行只读文本。

static_text.py

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this code example, we create a static text.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: April 2018
  9. """
  10. import wx
  11. class Example(wx.Frame):
  12. def __init__(self, *args, **kw):
  13. super(Example, self).__init__(*args, **kw)
  14. self.InitUI()
  15. def InitUI(self):
  16. txt1 = '''I'm giving up the ghost of love
  17. in the shadows cast on devotion
  18. She is the one that I adore
  19. creed of my silent suffocation
  20. Break this bittersweet spell on me
  21. lost in the arms of destiny'''
  22. txt2 = '''There is something in the way
  23. You're always somewhere else
  24. Feelings have deserted me
  25. To a point of no return
  26. I don't believe in God
  27. But I pray for you'''
  28. pnl = wx.Panel(self)
  29. vbox = wx.BoxSizer(wx.VERTICAL)
  30. font = wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.DEFAULT)
  31. st1 = wx.StaticText(pnl, label=txt1, style=wx.ALIGN_LEFT)
  32. st2 = wx.StaticText(pnl, label=txt2, style=wx.ALIGN_LEFT)
  33. st1.SetFont(font)
  34. st2.SetFont(font)
  35. vbox.Add(st1, flag=wx.ALL, border=15)
  36. vbox.Add(st2, flag=wx.ALL, border=15)
  37. pnl.SetSizer(vbox)
  38. self.SetTitle('Bittersweet')
  39. self.Centre()
  40. def main():
  41. app = wx.App()
  42. ex = Example(None)
  43. ex.Show()
  44. app.MainLoop()
  45. if __name__ == '__main__':
  46. main()

在示例中,我们使用wx.StaticText小部件显示了两首 Bittersweet 歌曲的节奏。

  1. font = wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.DEFAULT)

我们为文本创建一个字体对象。

  1. txt1 = '''I'm giving up the ghost of love
  2. in the shadows cast on devotion
  3. She is the one that I adore
  4. creed of my silent suffocation
  5. Break this bittersweet spell on me
  6. lost in the arms of destiny'''

这是要在wx.StaticText小部件中显示的字符串。

  1. st1 = wx.StaticText(pnl, label=txt1, style=wx.ALIGN_LEFT)

我们创建wx.StaticText小部件。 文本将向左对齐。

  1. st1.SetFont(font)
  2. st2.SetFont(font)

我们使用SetFont()将字体设置为静态文本小部件。

小部件 - 图3

图:wx.StaticText

wx.StaticLine

此小部件在窗口上显示一条简单的线。 它可以是水平或垂直的。

static_line.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this code example, we create a static line.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: April 2018
  9. """
  10. import wx
  11. class Example(wx.Frame):
  12. def __init__(self, *args, **kw):
  13. super(Example, self).__init__(*args, **kw)
  14. self.InitUI()
  15. def InitUI(self):
  16. pnl = wx.Panel(self)
  17. font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)
  18. heading = wx.StaticText(self, label='The Central Europe',
  19. pos=(25, 15), size=(200, -1))
  20. heading.SetFont(font)
  21. wx.StaticLine(self, pos=(25, 50), size=(300,1))
  22. wx.StaticText(self, label='Slovakia', pos=(25, 80))
  23. wx.StaticText(self, label='Hungary', pos=(25, 100))
  24. wx.StaticText(self, label='Poland', pos=(25, 120))
  25. wx.StaticText(self, label='Czech Republic', pos=(25, 140))
  26. wx.StaticText(self, label='Germany', pos=(25, 160))
  27. wx.StaticText(self, label='Slovenia', pos=(25, 180))
  28. wx.StaticText(self, label='Austria', pos=(25, 200))
  29. wx.StaticText(self, label='Switzerland', pos=(25, 220))
  30. wx.StaticText(self, label='5 445 000', pos=(250, 80))
  31. wx.StaticText(self, label='10 014 000', pos=(250, 100))
  32. wx.StaticText(self, label='38 186 000', pos=(250, 120))
  33. wx.StaticText(self, label='10 562 000', pos=(250, 140))
  34. wx.StaticText(self, label='81 799 000', pos=(250, 160))
  35. wx.StaticText(self, label='2 050 000', pos=(250, 180))
  36. wx.StaticText(self, label='8 414 000', pos=(250, 200))
  37. wx.StaticText(self, label='7 866 000', pos=(250, 220))
  38. wx.StaticLine(self, pos=(25, 260), size=(300,1))
  39. tsum = wx.StaticText(self, label='164 336 000', pos=(240, 280))
  40. sum_font = tsum.GetFont()
  41. sum_font.SetWeight(wx.BOLD)
  42. tsum.SetFont(sum_font)
  43. btn = wx.Button(self, label='Close', pos=(140, 310))
  44. btn.Bind(wx.EVT_BUTTON, self.OnClose)
  45. self.SetSize((360, 380))
  46. self.SetTitle('wx.StaticLine')
  47. self.Centre()
  48. def OnClose(self, e):
  49. self.Close(True)
  50. def main():
  51. app = wx.App()
  52. ex = Example(None)
  53. ex.Show()
  54. app.MainLoop()
  55. if __name__ == '__main__':
  56. main()

该脚本显示了中欧国家及其人口。 wx.StatLine使它看起来更具视觉吸引力。

  1. wx.StaticLine(self, pos=(25, 50), size=(300,1))

这是wx.StaticLine的构造器

小部件 - 图4

图:wx.StaticLine

wx.StaticBox

这是一种装饰器小部件。 它用于对各种小部件进行逻辑分组。 请注意,必须在其包含的窗口小部件之前创建此窗口小部件,并且这些窗口小部件应该是静态框的同级,而不是子级。

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import wx
  4. class Example(wx.Frame):
  5. def __init__(self, *args, **kw):
  6. super(Example, self).__init__(*args, **kw)
  7. self.InitUI()
  8. def InitUI(self):
  9. pnl = wx.Panel(self)
  10. wx.StaticBox(pnl, label='Personal Info', pos=(5, 5), size=(240, 170))
  11. wx.CheckBox(pnl, label='Male', pos=(15, 30))
  12. wx.CheckBox(pnl, label='Married', pos=(15, 55))
  13. wx.StaticText(pnl, label='Age', pos=(15, 95))
  14. wx.SpinCtrl(pnl, value='1', pos=(55, 90), size=(60, -1), min=1, max=120)
  15. btn = wx.Button(pnl, label='Ok', pos=(90, 185), size=(60, -1))
  16. btn.Bind(wx.EVT_BUTTON, self.OnClose)
  17. self.SetSize((270, 250))
  18. self.SetTitle('Static box')
  19. self.Centre()
  20. self.Show(True)
  21. def OnClose(self, e):
  22. self.Close(True)
  23. def main():
  24. ex = wx.App()
  25. Example(None)
  26. ex.MainLoop()
  27. if __name__ == '__main__':
  28. main()

我们有一个wx.StaticBox来装饰其他四个小部件。

小部件 - 图5

图:静态框

wx.ComboBox

wx.ComboBox是单行文本字段,带有向下箭头图像的按钮和列表框的组合。 当您按下按钮时,将出现一个列表框。 用户只能从提供的字符串列表中选择一个选项。

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import wx
  4. class Example(wx.Frame):
  5. def __init__(self, *args, **kw):
  6. super(Example, self).__init__(*args, **kw)
  7. self.InitUI()
  8. def InitUI(self):
  9. pnl = wx.Panel(self)
  10. distros = ['Ubuntu', 'Arch', 'Fedora', 'Debian', 'Mint']
  11. cb = wx.ComboBox(pnl, pos=(50, 30), choices=distros,
  12. style=wx.CB_READONLY)
  13. self.st = wx.StaticText(pnl, label='', pos=(50, 140))
  14. cb.Bind(wx.EVT_COMBOBOX, self.OnSelect)
  15. self.SetSize((250, 230))
  16. self.SetTitle('wx.ComboBox')
  17. self.Centre()
  18. self.Show(True)
  19. def OnSelect(self, e):
  20. i = e.GetString()
  21. self.st.SetLabel(i)
  22. def main():
  23. ex = wx.App()
  24. Example(None)
  25. ex.MainLoop()
  26. if __name__ == '__main__':
  27. main()

从组合框中选择的选项显示在下面的标签中。

  1. distros = ['Ubuntu', 'Arch', 'Fedora', 'Debian', 'Mint']

组合框将包含此字符串列表。

  1. cb = wx.ComboBox(pnl, pos=(50, 30), choices=distros,
  2. style=wx.CB_READONLY)

wx.ComboBox小部件已创建。 choices参数采用要在组合框显示的字符串列表。 wx.CB_READONLY样式使列表的字符串为只读。

  1. cb.Bind(wx.EVT_COMBOBOX, self.OnSelect)

当我们从组合框中选择一个选项时,将触发wx.EVT_COMBOBOX事件。 我们将OnSelect()事件处理器插入此事件。

  1. def OnSelect(self, e):
  2. i = e.GetString()
  3. self.st.SetLabel(i)

我们从组合框中获取选定的项目并将其设置为标签。

小部件 - 图6

图:wx.ComboBox

wx.CheckBox

wx.CheckBox是具有两种状态的窗口小部件:开和关。 这是一个带有标签的盒子。 标签可以设置在框的右侧或左侧。 如果选中wx.CheckBox,则在方框中用勾号表示。

checkbox.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create a checkbox widget.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: April 2018
  9. """
  10. import wx
  11. class Example(wx.Frame):
  12. def __init__(self, *args, **kw):
  13. super(Example, self).__init__(*args, **kw)
  14. self.InitUI()
  15. def InitUI(self):
  16. pnl = wx.Panel(self)
  17. vbox = wx.BoxSizer(wx.HORIZONTAL)
  18. cb = wx.CheckBox(pnl, label='Show title')
  19. cb.SetValue(True)
  20. cb.Bind(wx.EVT_CHECKBOX, self.ShowOrHideTitle)
  21. vbox.Add(cb, flag=wx.TOP|wx.LEFT, border=30)
  22. pnl.SetSizer(vbox)
  23. self.SetTitle('wx.CheckBox')
  24. self.Centre()
  25. def ShowOrHideTitle(self, e):
  26. sender = e.GetEventObject()
  27. isChecked = sender.GetValue()
  28. if isChecked:
  29. self.SetTitle('wx.CheckBox')
  30. else:
  31. self.SetTitle('')
  32. def main():
  33. app = wx.App()
  34. ex = Example(None)
  35. ex.Show()
  36. app.MainLoop()
  37. if __name__ == '__main__':
  38. main()

在上面的示例中,我们使用wx.CheckBox小部件显示或隐藏窗口标题。

  1. cb = wx.CheckBox(pnl, label='Show title')

这是wx.CheckBox小部件的构造器。

  1. cb.SetValue(True)

默认情况下显示框架窗口的标题,因此我们使用SetValue()方法检查wx.CheckBox小部件。

  1. cb.Bind(wx.EVT_CHECKBOX, self.ShowOrHideTitle)

当我们单击wx.CheckBox小部件时,将触发wx.EVT_CHECKBOX事件。 在此事件上调用ShowOrHideTitle()事件处理器。

  1. def ShowOrHideTitle(self, e):
  2. sender = e.GetEventObject()
  3. isChecked = sender.GetValue()
  4. if isChecked:
  5. self.SetTitle('wx.CheckBox')
  6. else:
  7. self.SetTitle('')

ShowOrHideTitle()方法中,我们根据wx.CheckBox小部件的状态显示或隐藏标题。

小部件 - 图7

图:wx.CheckBox

wx.StatusBar

wx.StatusBar小部件用于显示应用状态信息。 它可以分为几个部分以显示不同类型的信息。 我们可以在wx.StatusBar中插入其他小部件。 它可以用作对话框的替代方法,因为对话框经常被滥用,并且大多数用户不喜欢它们。 我们可以通过两种方式创建wx.StatusBar。 我们可以手动创建自己的wx.StatusBar并调用SetStatusBar()方法,也可以简单地调用CreateStatusBar()方法。 后一种方法为我们创建了默认的wx.StatusBar

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import wx
  4. class Example(wx.Frame):
  5. def __init__(self, *args, **kw):
  6. super(Example, self).__init__(*args, **kw)
  7. self.InitUI()
  8. def InitUI(self):
  9. pnl = wx.Panel(self)
  10. button = wx.Button(pnl, label='Button', pos=(20, 20))
  11. text = wx.CheckBox(pnl, label='CheckBox', pos=(20, 90))
  12. combo = wx.ComboBox(pnl, pos=(120, 22), choices=['Python', 'Ruby'])
  13. slider = wx.Slider(pnl, 5, 6, 1, 10, (120, 90), (110, -1))
  14. pnl.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
  15. button.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
  16. text.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
  17. combo.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
  18. slider.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)
  19. self.sb = self.CreateStatusBar()
  20. self.SetSize((250, 230))
  21. self.SetTitle('wx.Statusbar')
  22. self.Centre()
  23. self.Show(True)
  24. def OnWidgetEnter(self, e):
  25. name = e.GetEventObject().GetClassName()
  26. self.sb.SetStatusText(name + ' widget')
  27. e.Skip()
  28. def main():
  29. ex = wx.App()
  30. Example(None)
  31. ex.MainLoop()
  32. if __name__ == '__main__':
  33. main()

在我们的示例中,我们有一个wx.Frame小部件以及其他五个小部件。 如果将鼠标指针悬停在窗口小部件上,则其名称将显示在wx.StatusBar中。

  1. pnl.Bind(wx.EVT_ENTER_WINDOW, self.OnWidgetEnter)

如果我们输入小部件的区域,则会生成EVT_ENTER_WINDOW事件。

  1. self.sb = self.CreateStatusBar()

使用CreateStatusBar()方法创建状态栏。

  1. def OnWidgetEnter(self, e):
  2. name = e.GetEventObject().GetClassName()
  3. self.sb.SetStatusText(name + ' widget')
  4. e.Skip()

OnWidgetEnter()方法内部,我们找出使用鼠标指针输入的小部件的名称。 我们使用SetStatusText()方法设置状态文本。

小部件 - 图8

图:wx.StatusBar

wx.RadioButton

wx.RadioButton是一个小部件,允许用户从一组选项中选择一个唯一选项。 通过使组中的第一个单选按钮包含wx.RB_GROUP样式来定义单选按钮组。 在第一个带有此样式标记的单选按钮之后定义的所有其他单选按钮将添加到第一个单选按钮的功能组中。 用wx.RB_GROUP标志声明另一个单选按钮将启动一个新的单选按钮组。

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import wx
  4. class Example(wx.Frame):
  5. def __init__(self, *args, **kw):
  6. super(Example, self).__init__(*args, **kw)
  7. self.InitUI()
  8. def InitUI(self):
  9. pnl = wx.Panel(self)
  10. self.rb1 = wx.RadioButton(pnl, label='Value A', pos=(10, 10),
  11. style=wx.RB_GROUP)
  12. self.rb2 = wx.RadioButton(pnl, label='Value B', pos=(10, 30))
  13. self.rb3 = wx.RadioButton(pnl, label='Value C', pos=(10, 50))
  14. self.rb1.Bind(wx.EVT_RADIOBUTTON, self.SetVal)
  15. self.rb2.Bind(wx.EVT_RADIOBUTTON, self.SetVal)
  16. self.rb3.Bind(wx.EVT_RADIOBUTTON, self.SetVal)
  17. self.sb = self.CreateStatusBar(3)
  18. self.sb.SetStatusText("True", 0)
  19. self.sb.SetStatusText("False", 1)
  20. self.sb.SetStatusText("False", 2)
  21. self.SetSize((210, 210))
  22. self.SetTitle('wx.RadioButton')
  23. self.Centre()
  24. self.Show(True)
  25. def SetVal(self, e):
  26. state1 = str(self.rb1.GetValue())
  27. state2 = str(self.rb2.GetValue())
  28. state3 = str(self.rb3.GetValue())
  29. self.sb.SetStatusText(state1, 0)
  30. self.sb.SetStatusText(state2, 1)
  31. self.sb.SetStatusText(state3, 2)
  32. def main():
  33. ex = wx.App()
  34. Example(None)
  35. ex.MainLoop()
  36. if __name__ == '__main__':
  37. main()

我们有一组三个单选按钮。 每个单选按钮的状态显示在状态栏中。

  1. self.rb1 = wx.RadioButton(pnl, label='Value A', pos=(10, 10),
  2. style=wx.RB_GROUP)
  3. self.rb2 = wx.RadioButton(pnl, label='Value B', pos=(10, 30))
  4. self.rb3 = wx.RadioButton(pnl, label='Value C', pos=(10, 50))

我们创建三个单选按钮。 第一个单选按钮设置为wx.RB_GROUP样式。 它将启动一个新的广播组。

  1. self.rb1.Bind(wx.EVT_RADIOBUTTON, self.SetVal)

我们将wx.EVT_RADIOBUTTON事件绑定到SetVal()事件处理器。

  1. self.sb = self.CreateStatusBar(3)
  2. self.sb.SetStatusText("True", 0)
  3. self.sb.SetStatusText("False", 1)
  4. self.sb.SetStatusText("False", 2)

我们创建一个带有三个字段的状态栏。 我们将初始文本设置为与单选按钮状态相对应的状态栏。

  1. def SetVal(self, e):
  2. state1 = str(self.rb1.GetValue())
  3. state2 = str(self.rb2.GetValue())
  4. state3 = str(self.rb3.GetValue())
  5. self.sb.SetStatusText(state1, 0)
  6. self.sb.SetStatusText(state2, 1)
  7. self.sb.SetStatusText(state3, 2)

SetVal()方法内,我们找出单选按钮的状态。 我们将状态栏字段更新为当前的单选按钮值。

小部件 - 图9

图:wx.RadioButton

wx.Gauge

wx.Gauge是在处理冗长的任务时使用的小部件。 它具有一个指示器以显示任务的当前状态。

gauge_wid.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create gauge widget.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: April 2018
  9. """
  10. import wx
  11. TASK_RANGE = 50
  12. class Example(wx.Frame):
  13. def __init__(self, *args, **kw):
  14. super(Example, self).__init__(*args, **kw)
  15. self.InitUI()
  16. def InitUI(self):
  17. self.timer = wx.Timer(self, 1)
  18. self.count = 0
  19. self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
  20. pnl = wx.Panel(self)
  21. vbox = wx.BoxSizer(wx.VERTICAL)
  22. hbox1 = wx.BoxSizer(wx.HORIZONTAL)
  23. hbox2 = wx.BoxSizer(wx.HORIZONTAL)
  24. hbox3 = wx.BoxSizer(wx.HORIZONTAL)
  25. self.gauge = wx.Gauge(pnl, range=TASK_RANGE, size=(250, -1))
  26. self.btn1 = wx.Button(pnl, wx.ID_OK)
  27. self.btn2 = wx.Button(pnl, wx.ID_STOP)
  28. self.text = wx.StaticText(pnl, label='Task to be done')
  29. self.Bind(wx.EVT_BUTTON, self.OnOk, self.btn1)
  30. self.Bind(wx.EVT_BUTTON, self.OnStop, self.btn2)
  31. hbox1.Add(self.gauge, proportion=1, flag=wx.ALIGN_CENTRE)
  32. hbox2.Add(self.btn1, proportion=1, flag=wx.RIGHT, border=10)
  33. hbox2.Add(self.btn2, proportion=1)
  34. hbox3.Add(self.text, proportion=1)
  35. vbox.Add((0, 30))
  36. vbox.Add(hbox1, flag=wx.ALIGN_CENTRE)
  37. vbox.Add((0, 20))
  38. vbox.Add(hbox2, proportion=1, flag=wx.ALIGN_CENTRE)
  39. vbox.Add(hbox3, proportion=1, flag=wx.ALIGN_CENTRE)
  40. pnl.SetSizer(vbox)
  41. self.SetTitle('wx.Gauge')
  42. self.Centre()
  43. def OnOk(self, e):
  44. if self.count >= TASK_RANGE:
  45. return
  46. self.timer.Start(100)
  47. self.text.SetLabel('Task in Progress')
  48. def OnStop(self, e):
  49. if self.count == 0 or self.count >= TASK_RANGE or not self.timer.IsRunning():
  50. return
  51. self.timer.Stop()
  52. self.text.SetLabel('Task Interrupted')
  53. def OnTimer(self, e):
  54. self.count = self.count + 1
  55. self.gauge.SetValue(self.count)
  56. if self.count == TASK_RANGE:
  57. self.timer.Stop()
  58. self.text.SetLabel('Task Completed')
  59. def main():
  60. app = wx.App()
  61. ex = Example(None)
  62. ex.Show()
  63. app.MainLoop()
  64. if __name__ == '__main__':
  65. main()

我们有一个压力表和两个按钮。 一个按钮启动压力表,另一按钮停止压力表。

  1. self.timer = wx.Timer(self, 1)
  2. self.count = 0

我们使用wx.Timer在特定间隔执行代码。 届时我们将更新量规。 count变量用于确定已完成任务的一部分。

  1. self.gauge = wx.Gauge(pnl, range=TASK_RANGE, size=(250, -1))

这是wx.Gauge小部件的构造器。 range参数设置窗口小部件的最大整数值。

  1. def OnOk(self, e):
  2. if self.count >= TASK_RANGE:
  3. return
  4. self.timer.Start(100)
  5. self.text.SetLabel('Task in Progress')

当我们单击确定按钮时,将调用OnOk()方法。 我们首先检查count变量是否在任务范围内。 如果没有,我们从方法中返回。 如果任务尚未完成,我们将启动计时器并更新静态文本。

  1. def OnStop(self, e):
  2. if self.count == 0 or self.count >= TASK_RANGE or not self.timer.IsRunning():
  3. return
  4. self.timer.Stop()
  5. self.text.SetLabel('Task Interrupted')

当我们单击停止按钮时,将调用OnStop()方法。 我们检查停止任务的条件。 如果遇到他们,我们将停止计时器并更新静态文本。

  1. def OnTimer(self, e):
  2. self.count = self.count + 1
  3. self.gauge.SetValue(self.count)
  4. if self.count == TASK_RANGE:
  5. self.timer.Stop()
  6. self.text.SetLabel('Task Completed')

启动计时器后,会定期调用OnTimer()方法。 在该方法中,我们更新了count变量和gauge控件。 如果count变量等于TASK_RANGE,我们将停止计时器并更新静态文本。

小部件 - 图10

图:wx.Gauge

wx.Slider

wx.Slider是具有简单句柄的小部件。 该手柄可以前后拉动。 这样,我们可以选择特定任务。

slider_wid.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create slider control.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: April 2018
  9. """
  10. import wx
  11. class Example(wx.Frame):
  12. def __init__(self, *args, **kw):
  13. super(Example, self).__init__(*args, **kw)
  14. self.InitUI()
  15. def InitUI(self):
  16. pnl = wx.Panel(self)
  17. sizer = wx.GridBagSizer(5, 5)
  18. sld = wx.Slider(pnl, value=200, minValue=150, maxValue=500,
  19. style=wx.SL_HORIZONTAL)
  20. sld.Bind(wx.EVT_SCROLL, self.OnSliderScroll)
  21. sizer.Add(sld, pos=(0, 0), flag=wx.ALL|wx.EXPAND, border=25)
  22. self.txt = wx.StaticText(pnl, label='200')
  23. sizer.Add(self.txt, pos=(0, 1), flag=wx.TOP|wx.RIGHT, border=25)
  24. sizer.AddGrowableCol(0)
  25. pnl.SetSizer(sizer)
  26. self.SetTitle('wx.Slider')
  27. self.Centre()
  28. def OnSliderScroll(self, e):
  29. obj = e.GetEventObject()
  30. val = obj.GetValue()
  31. self.txt.SetLabel(str(val))
  32. def main():
  33. app = wx.App()
  34. ex = Example(None)
  35. ex.Show()
  36. app.MainLoop()
  37. if __name__ == '__main__':
  38. main()

静态文本中显示了在滑块中选择的值。

  1. sld = wx.Slider(pnl, value=200, minValue=150, maxValue=500,
  2. style=wx.SL_HORIZONTAL)

创建了wx.Slider。 我们使用值参数提供滑块的初始位置,并使用minValuemaxValue参数提供最小和最大滑块位置。 wx.SL_HORIZONTAL使滑块变为水平。

  1. sld.Bind(wx.EVT_SCROLL, self.OnSliderScroll)

遇到wx.EVT_SCROLL事件时,将调用OnSliderScroll()方法。

  1. self.txt = wx.StaticText(pnl, label='200')

当前选择的滑块值显示在静态文本中,该文本位于滑块下方。

  1. def OnSliderScroll(self, e):
  2. obj = e.GetEventObject()
  3. val = obj.GetValue()
  4. self.txt.SetLabel(str(val))

OnSliderScroll()方法中,我们获取事件的发送者。 我们获取滑块的当前值并将其设置为静态文本。

小部件 - 图11

图:wx.Slider

wx.SpinCtrl

wx.SpinCtrl小部件使我们可以增加和减少值。

spin_ctrl.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example we create spin control.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: April 2018
  9. """
  10. import wx
  11. class Example(wx.Frame):
  12. def __init__(self, *args, **kw):
  13. super(Example, self).__init__(*args, **kw)
  14. self.InitUI()
  15. def InitUI(self):
  16. pnl = wx.Panel(self)
  17. sizer = wx.GridBagSizer(5, 5)
  18. st1 = wx.StaticText(pnl, label='Convert Fahrenheit temperature to Celsius')
  19. sizer.Add(st1, pos=(0, 0), span=(1, 2), flag=wx.ALL, border=15)
  20. st2 = wx.StaticText(pnl, label='Fahrenheit:')
  21. sizer.Add(st2, pos=(1, 0), flag=wx.ALL | wx.ALIGN_CENTER, border=15)
  22. self.sc = wx.SpinCtrl(pnl, value='0')
  23. self.sc.SetRange(-459, 1000)
  24. sizer.Add(self.sc, pos=(1, 1), flag=wx.ALIGN_CENTER)
  25. st3 = wx.StaticText(pnl, label='Celsius:')
  26. sizer.Add(st3, pos=(2, 0), flag=wx.ALL|wx.ALIGN_RIGHT, border=15)
  27. self.celsius = wx.StaticText(pnl, label='')
  28. sizer.Add(self.celsius, pos=(2, 1), flag=wx.ALL, border=15)
  29. computeButton = wx.Button(pnl, label='Compute')
  30. computeButton.SetFocus()
  31. sizer.Add(computeButton, pos=(3, 0), flag=wx.ALIGN_RIGHT|wx.TOP, border=30)
  32. closeButton = wx.Button(pnl, label='Close')
  33. sizer.Add(closeButton, pos=(3, 1), flag=wx.ALIGN_LEFT|wx.TOP, border=30)
  34. computeButton.Bind(wx.EVT_BUTTON, self.OnCompute)
  35. closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
  36. pnl.SetSizer(sizer)
  37. self.SetTitle('wx.SpinCtrl')
  38. self.Centre()
  39. def OnClose(self, e):
  40. self.Close(True)
  41. def OnCompute(self, e):
  42. fahr = self.sc.GetValue()
  43. cels = round((fahr - 32) * 5 / 9.0, 2)
  44. self.celsius.SetLabel(str(cels))
  45. def main():
  46. app = wx.App()
  47. ex = Example(None)
  48. ex.Show()
  49. app.MainLoop()
  50. if __name__ == '__main__':
  51. main()

该脚本将华氏温度转换为摄氏温度。 我们使用wx.SpinCtrl小部件为华氏温度选择一个值。

  1. self.sc = wx.SpinCtrl(pnl, value='0')
  2. self.sc.SetRange(-459, 1000)

我们创建一个初始值为 0 的wx.SpinCtrl小部件。SetRange()设置该小部件的值范围。

  1. def OnCompute(self, e):
  2. fahr = self.sc.GetValue()
  3. cels = round((fahr - 32) * 5 / 9.0, 2)
  4. self.celsius.SetLabel(str(cels))

当我们单击计算按钮时,将调用OnCompute()方法。 在方法的主体中,我们从旋转控件中获取当前值。 我们计算摄氏温度并将计算的温度设置为静态文本小部件。

小部件 - 图12

图:wx.SpinCtrl

wxPython 教程的这一部分专用于核心 wxPython 小部件。