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

在本章中,我们讨论以下高级小部件:wx.ListBoxwx.html.HtmlWindowwx.ListCtrl

wxPython 有几个众所周知的高级小部件。 例如,树小部件,HTML 窗口,网格小部件,列表框小部件,列表小部件或具有高级样式功能的编辑器。

wx.ListBox小部件

wx.ListBox用于显示和使用项目列表。 可以在两种不同的状态下创建wx.ListBox:处于单选状态或多选状态。 单一选择状态是默认状态。

wx.ListBox中有两个重要事件。 第一个是wx.EVT_COMMAND_LISTBOX_SELECTED事件。 当我们在wx.ListBox中选择一个项目时,将生成此事件。 第二个事件是wx.EVT_COMMAND_LISTBOX_DOUBLE_CLICKED事件。 当我们双击wx.ListBox中的项目时会生成该文件。 元素从零开始编号。 如果需要,滚动条会自动显示。

listbox.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example, we create a wx.ListBox widget.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: May 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. panel = wx.Panel(self)
  17. hbox = wx.BoxSizer(wx.HORIZONTAL)
  18. self.listbox = wx.ListBox(panel)
  19. hbox.Add(self.listbox, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)
  20. btnPanel = wx.Panel(panel)
  21. vbox = wx.BoxSizer(wx.VERTICAL)
  22. newBtn = wx.Button(btnPanel, wx.ID_ANY, 'New', size=(90, 30))
  23. renBtn = wx.Button(btnPanel, wx.ID_ANY, 'Rename', size=(90, 30))
  24. delBtn = wx.Button(btnPanel, wx.ID_ANY, 'Delete', size=(90, 30))
  25. clrBtn = wx.Button(btnPanel, wx.ID_ANY, 'Clear', size=(90, 30))
  26. self.Bind(wx.EVT_BUTTON, self.NewItem, id=newBtn.GetId())
  27. self.Bind(wx.EVT_BUTTON, self.OnRename, id=renBtn.GetId())
  28. self.Bind(wx.EVT_BUTTON, self.OnDelete, id=delBtn.GetId())
  29. self.Bind(wx.EVT_BUTTON, self.OnClear, id=clrBtn.GetId())
  30. self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)
  31. vbox.Add((-1, 20))
  32. vbox.Add(newBtn)
  33. vbox.Add(renBtn, 0, wx.TOP, 5)
  34. vbox.Add(delBtn, 0, wx.TOP, 5)
  35. vbox.Add(clrBtn, 0, wx.TOP, 5)
  36. btnPanel.SetSizer(vbox)
  37. hbox.Add(btnPanel, 0.6, wx.EXPAND | wx.RIGHT, 20)
  38. panel.SetSizer(hbox)
  39. self.SetTitle('wx.ListBox')
  40. self.Centre()
  41. def NewItem(self, event):
  42. text = wx.GetTextFromUser('Enter a new item', 'Insert dialog')
  43. if text != '':
  44. self.listbox.Append(text)
  45. def OnRename(self, event):
  46. sel = self.listbox.GetSelection()
  47. text = self.listbox.GetString(sel)
  48. renamed = wx.GetTextFromUser('Rename item', 'Rename dialog', text)
  49. if renamed != '':
  50. self.listbox.Delete(sel)
  51. item_id = self.listbox.Insert(renamed, sel)
  52. self.listbox.SetSelection(item_id)
  53. def OnDelete(self, event):
  54. sel = self.listbox.GetSelection()
  55. if sel != -1:
  56. self.listbox.Delete(sel)
  57. def OnClear(self, event):
  58. self.listbox.Clear()
  59. def main():
  60. app = wx.App()
  61. ex = Example(None)
  62. ex.Show()
  63. app.MainLoop()
  64. if __name__ == '__main__':
  65. main()

该示例显示了如何从wx.ListBox添加,修改和删除项目。

  1. self.listbox = wx.ListBox(panel)
  2. hbox.Add(self.listbox, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)

我们创建一个空的wx.ListBox。 我们在列表框周围放置了 20px 的边框。

  1. self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)

我们使用wx.EVT_LISTBOX_DCLICK事件绑定器将wx.EVT_COMMAND_LISTBOX_DOUBLE_CLICKED事件类型与OnRename()方法绑定。 这样,如果我们双击列表框中的特定元素,我们将显示一个重命名对话框。

  1. def NewItem(self, event):
  2. text = wx.GetTextFromUser('Enter a new item', 'Insert dialog')
  3. if text != '':
  4. self.listbox.Append(text)

我们通过单击“新建”按钮来调用NewItem()方法。 此方法使用包装器wx.GetTextFromUser()方法显示wx.TextEntryDialog。 我们输入的文本将返回到text变量。 如果文本不为空,则使用Append()方法将其附加到列表框。

  1. if renamed != '':
  2. self.listbox.Delete(sel)
  3. item_id = self.listbox.Insert(renamed, sel)
  4. self.listbox.SetSelection(item_id)

我们通过删除项目并在同一位置插入新项目来重命名该项目。 我们还将选择重新设置为修改后的项目。

  1. def OnDelete(self, event):
  2. sel = self.listbox.GetSelection()
  3. if sel != -1:
  4. self.listbox.Delete(sel)

要删除项目,我们通过调用GetSelection()方法找到所选项目的索引。 然后,我们使用Delete()方法删除该项目。 Delete()方法的参数是所选索引。

  1. def OnClear(self, event):
  2. self.listbox.Clear()

最简单的方法是清除整个列表框。 我们只需调用Clear()方法。

wxPython 中的高级小部件 - 图1

图:wx.ListBox小部件

wx.html.HtmlWindow小部件

wx.html.HtmlWindow小部件显示 HTML 页面。 它不是完整的浏览器。 我们可以使用wx.html.HtmlWindow小部件来做一些有趣的事情。

例如,在下面的程序中,我们创建一个显示基本统计信息的窗口。

page.html

  1. <!DOCTYPE html>
  2. <html>
  3. <body bgcolor="#8e8e95">
  4. <table cellspacing="5" border="0" width="250">
  5. <tr width="200" align="left">
  6. <td bgcolor="#e7e7e7">&nbsp;&nbsp;Maximum</td>
  7. <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>9000</b></td>
  8. </tr>
  9. <tr align="left">
  10. <td bgcolor="#e7e7e7">&nbsp;&nbsp;Mean</td>
  11. <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>6076</b></td>
  12. </tr>
  13. <tr align="left">
  14. <td bgcolor="#e7e7e7">&nbsp;&nbsp;Minimum</td>
  15. <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>3800</b></td>
  16. </tr>
  17. <tr align="left">
  18. <td bgcolor="#e7e7e7">&nbsp;&nbsp;Median</td>
  19. <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>6000</b></td>
  20. </tr>
  21. <tr align="left">
  22. <td bgcolor="#e7e7e7">&nbsp;&nbsp;Standard Deviation</td>
  23. <td bgcolor="#aaaaaa">&nbsp;&nbsp;<b>6076</b></td>
  24. </tr>
  25. </table>
  26. </body>
  27. </html>

这是要显示的 HTML 页面。

htmlwin.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example, we create a wx.html.HtmlWindow widget.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: May 2018
  9. """
  10. import wx
  11. import wx.html
  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. panel = wx.Panel(self)
  18. vbox = wx.BoxSizer(wx.VERTICAL)
  19. hbox = wx.BoxSizer(wx.HORIZONTAL)
  20. htmlwin = wx.html.HtmlWindow(panel, wx.ID_ANY, style=wx.NO_BORDER)
  21. htmlwin.SetStandardFonts()
  22. htmlwin.LoadPage("page.html")
  23. vbox.Add((-1, 10), 0)
  24. vbox.Add(htmlwin, 1, wx.EXPAND | wx.ALL, 9)
  25. bitmap = wx.StaticBitmap(panel, wx.ID_ANY, wx.Bitmap('newt.png'))
  26. hbox.Add(bitmap, 0, wx.LEFT | wx.BOTTOM | wx.TOP, 10)
  27. btnOk = wx.Button(panel, wx.ID_ANY, 'Ok')
  28. self.Bind(wx.EVT_BUTTON, self.OnClose, id=btnOk.GetId())
  29. hbox.Add((100, -1), 1, wx.EXPAND | wx.ALIGN_RIGHT)
  30. hbox.Add(btnOk, flag=wx.TOP | wx.BOTTOM | wx.RIGHT, border=10)
  31. vbox.Add(hbox, 0, wx.EXPAND)
  32. panel.SetSizer(vbox)
  33. self.SetTitle('Basic statistics')
  34. self.Centre()
  35. def OnClose(self, event):
  36. self.Close()
  37. def main():
  38. app = wx.App()
  39. ex = Example(None)
  40. ex.Show()
  41. app.MainLoop()
  42. if __name__ == '__main__':
  43. main()

该示例在wx.html.HtmlWindow小部件中分配 HTML 文件。

  1. htmlwin = wx.html.HtmlWindow(panel, wx.ID_ANY, style=wx.NO_BORDER)
  2. htmlwin.SetStandardFonts()
  3. htmlwin.LoadPage("page.html")

wx.html.HtmlWindow已创建。 HTML 文件使用LoadPage()方法加载。

wxPython 中的高级小部件 - 图2

图:wx.html.HtmlWindow示例

帮助窗口

我们可以使用wx.html.HtmlWindow在我们的应用中提供帮助。 我们可以创建一个独立的窗口,也可以创建将成为应用一部分的窗口。 以下脚本将使用后一种想法创建一个帮助窗口。

helpwindow.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example, we create a help window window
  6. with wx.html.HtmlWindow.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: May 2018
  10. """
  11. import wx
  12. import wx.html as html
  13. class Example(wx.Frame):
  14. def __init__(self, *args, **kw):
  15. super(Example, self).__init__(*args, **kw)
  16. self.InitUI()
  17. def InitUI(self):
  18. toolbar = self.CreateToolBar()
  19. toolbar.AddTool(1, 'Exit', wx.Bitmap('exit.png'))
  20. toolbar.AddTool(2, 'Help', wx.Bitmap('help.png'))
  21. toolbar.Realize()
  22. self.splitter = wx.SplitterWindow(self)
  23. self.panelLeft = wx.Panel(self.splitter, wx.ID_ANY, style=wx.BORDER_SUNKEN)
  24. self.panelRight = wx.Panel(self.splitter)
  25. vbox2 = wx.BoxSizer(wx.VERTICAL)
  26. header = wx.Panel(self.panelRight, wx.ID_ANY)
  27. header.SetBackgroundColour('#6f6a59')
  28. header.SetForegroundColour('white')
  29. hbox = wx.BoxSizer(wx.HORIZONTAL)
  30. st = wx.StaticText(header, wx.ID_ANY, 'Help')
  31. font = st.GetFont()
  32. font.SetFamily(wx.FONTFAMILY_ROMAN)
  33. font.SetPointSize(11)
  34. st.SetFont(font)
  35. hbox.Add(st, 1, wx.TOP | wx.BOTTOM | wx.LEFT, 8)
  36. closeBtn = wx.BitmapButton(header, wx.ID_ANY, wx.Bitmap('closebutton.png',
  37. wx.BITMAP_TYPE_PNG), style=wx.NO_BORDER)
  38. closeBtn.SetBackgroundColour('#6f6a59')
  39. hbox.Add(closeBtn, 0, wx.TOP|wx.BOTTOM, 8)
  40. header.SetSizer(hbox)
  41. vbox2.Add(header, 0, wx.EXPAND)
  42. helpWin = html.HtmlWindow(self.panelRight, style=wx.NO_BORDER)
  43. helpWin.LoadPage('help.html')
  44. vbox2.Add(helpWin, 1, wx.EXPAND)
  45. self.panelRight.SetSizer(vbox2)
  46. self.panelLeft.SetFocus()
  47. self.splitter.SplitVertically(self.panelLeft, self.panelRight)
  48. self.splitter.Unsplit()
  49. self.Bind(wx.EVT_BUTTON, self.CloseHelp, id=closeBtn.GetId())
  50. self.Bind(wx.EVT_TOOL, self.OnClose, id=1)
  51. self.Bind(wx.EVT_TOOL, self.OnHelp, id=2)
  52. self.panelLeft.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
  53. self.panelLeft.SetFocus()
  54. self.CreateStatusBar()
  55. self.SetTitle('Help')
  56. self.Centre()
  57. def OnClose(self, e):
  58. self.Close()
  59. def OnHelp(self, e):
  60. self.splitter.SplitVertically(self.panelLeft, self.panelRight)
  61. self.panelLeft.SetFocus()
  62. def CloseHelp(self, e):
  63. self.splitter.Unsplit()
  64. self.panelLeft.SetFocus()
  65. def OnKeyPressed(self, e):
  66. keycode = e.GetKeyCode()
  67. print(keycode)
  68. if keycode == wx.WXK_F1:
  69. self.splitter.SplitVertically(self.panelLeft, self.panelRight)
  70. self.panelLeft.SetFocus()
  71. def main():
  72. app = wx.App()
  73. ex = Example(None)
  74. ex.Show()
  75. app.MainLoop()
  76. if __name__ == '__main__':
  77. main()

帮助窗口一开始是隐藏的。 我们可以通过点击工具栏上的帮助按钮或按 F1 表现出来。 帮助窗口出现在应用的右侧。 要隐藏的帮助窗口,我们点击关闭按钮。

  1. self.splitter.SplitVertically(self.panelLeft, self.panelRight)
  2. self.splitter.Unsplit()

我们创建左面板和右面板并将其垂直拆分。 之后,我们调用Unsplit()方法。 默认情况下,该方法隐藏右侧或底部窗格。

我们将右侧面板分为两部分。 面板的标题和主体。 标头是已调整的wx.Panel。 标题由静态文本和位图按钮组成。 我们将wx.html.Window放入面板的主体中。

  1. closeBtn = wx.BitmapButton(header, wx.ID_ANY, wx.Bitmap('closebutton.png',
  2. wx.BITMAP_TYPE_PNG), style=wx.NO_BORDER)
  3. closeBtn.SetBackgroundColour('#6f6a59')

位图按钮样式设置为wx.NO_BORDER。 背景颜色设置为标题面板的颜色。 这样做是为了使按钮显示为标题的一部分。

  1. helpWin = html.HtmlWindow(self.panelRight, style=wx.NO_BORDER)
  2. helpWin.LoadPage('help.html')

我们在右侧面板上创建一个wx.html.HtmlWindow小部件。 我们的 HTML 代码位于单独的文件中。 这次我们调用LoadPage()方法来获取 HTML 代码。

  1. self.panelLeft.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
  2. self.panelLeft.SetFocus()

我们将重点放在左侧面板上。 我们可以使用F1键启动帮助窗口。 为了使用键盘控制窗口,必须具有焦点。 如果未设置焦点,则必须首先单击面板,然后才能通过按 F1 键启动帮助窗口。

  1. def OnHelp(self, e):
  2. self.splitter.SplitVertically(self.panelLeft, self.panelRight)
  3. self.panelLeft.SetFocus()

为了显示帮助窗口,我们调用OnHelp()方法。 它将垂直拆分两个面板。 我们一定不要忘记再次设置焦点,因为初始焦点会因拆分而丢失。

以下是我们在应用中加载的 HTML 文件。

help.html

  1. <!DOCTYPE html>
  2. <html>
  3. <body bgcolor="#ababab">
  4. <h4>Table of Contents</h4>
  5. <ul>
  6. <li><a href="#basic">Basic statistics</a></li>
  7. <li><a href="#advanced">Advanced statistics</a></li>
  8. <li><a href="#intro">Introducing Newt</a></li>
  9. <li><a href="#charts">Working with charts</a></li>
  10. <li><a href="#pred">Predicting values</a></li>
  11. <li><a href="#neural">Neural networks</a></li>
  12. <li><a href="#glos">Glossary</a></li>
  13. </ul>
  14. <p>
  15. <a name="basic">
  16. <h6>Basic Statistics</h6>
  17. Overview of elementary concepts in statistics.
  18. Variables. Correlation. Measurement scales. Statistical significance.
  19. Distributions. Normality assumption.
  20. </a>
  21. </p>
  22. <p>
  23. <a name="advanced">
  24. <h6>Advanced Statistics</h6>
  25. Overview of advanced concepts in statistics. Anova. Linear regression.
  26. Estimation and hypothesis testing.
  27. Error terms.
  28. </a>
  29. </p>
  30. <p>
  31. <a name="intro">
  32. <h6>Introducing Newt</h6>
  33. Introducing the basic functionality of the Newt application. Creating sheets.
  34. Charts. Menus and Toolbars. Importing data. Saving data in various formats.
  35. Exporting data. Shortcuts. List of methods.
  36. </a>
  37. </p>
  38. <p>
  39. <a name="charts">
  40. <h6>Charts</h6>
  41. Working with charts. 2D charts. 3D charts. Bar, line, box, pie, range charts.
  42. Scatterplots. Histograms.
  43. </a>
  44. </p>
  45. <p>
  46. <a name="pred">
  47. <h6>Predicting values</h6>
  48. Time series and forecasting. Trend Analysis. Seasonality. Moving averages.
  49. Univariate methods. Multivariate methods. Holt-Winters smoothing.
  50. Exponential smoothing. ARIMA. Fourier analysis.
  51. </a>
  52. </p>
  53. <p>
  54. <a name="neural">
  55. <h6>Neural networks</h6>
  56. Overview of neural networks. Biology behind neural networks.
  57. Basic artificial Model. Training. Preprocessing. Postprocessing.
  58. Types of neural networks.
  59. </a>
  60. </p>
  61. <p>
  62. <a name="glos">
  63. <h6>Glossary</h6>
  64. Terms and definitions in statistics.
  65. </a>
  66. </p>
  67. </body>
  68. </html>

HTML 文件包含应用帮助的目录。

wxPython 中的高级小部件 - 图3

图:帮助窗口

wx.ListCtrl小部件

wx.ListCtrl是项目列表的图形表示。 一个wx.ListBox只能有一列。 wx.ListCtrl可以有多个栏。 wx.ListCtrl是一个非常常见且有用的小部件。 例如,文件管理器使用wx.ListCtrl在文件系统上显示目录和文件。 cd 刻录机应用显示要在wx.ListCtrl中刻录的文件。

wx.ListCtrl可以三种不同的格式使用。 在列表视图,报告视图或图标视图中。 这些格式由wx.ListCtrl窗口样式控制。 wx.LC_REPORTwx.LC_LISTwx.LC_ICON

wx.ListCtrl样式

  • wx.LC_LIST
  • wx.LC_REPORT
  • wx.LC_VIRTUAL
  • wx.LC_ICON
  • wx.LC_SMALL_ICON
  • wx.LC_ALIGN_LEFT
  • wx.LC_EDIT_LABELS
  • wx.LC_NO_HEADER
  • wx.LC_SORT_ASCENDING
  • wx.LC_SORT_DESCENDING
  • wx.LC_HRULES
  • wx.LC_VRULES

简单的例子

第一个示例介绍了wx.ListCtrl的一些基本功能。

actresses.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example, we create a simple
  6. wx.ListCtrl widget.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: May 2018
  10. """
  11. import wx
  12. data = [('Jessica Alba', 'Pomona', '1981'), ('Sigourney Weaver', 'New York', '1949'),
  13. ('Angelina Jolie', 'los angeles', '1975'), ('Natalie Portman', 'Jerusalem', '1981'),
  14. ('Rachel Weiss', 'London', '1971'), ('Scarlett Johansson', 'New York', '1984' )]
  15. class Example(wx.Frame):
  16. def __init__(self, *args, **kw):
  17. super(Example, self).__init__(*args, **kw)
  18. self.InitUI()
  19. def InitUI(self):
  20. hbox = wx.BoxSizer(wx.HORIZONTAL)
  21. panel = wx.Panel(self)
  22. self.list = wx.ListCtrl(panel, wx.ID_ANY, style=wx.LC_REPORT)
  23. self.list.InsertColumn(0, 'name', width=140)
  24. self.list.InsertColumn(1, 'place', width=130)
  25. self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)
  26. idx = 0
  27. for i in data:
  28. index = self.list.InsertItem(idx, i[0])
  29. self.list.SetItem(index, 1, i[1])
  30. self.list.SetItem(index, 2, i[2])
  31. idx += 1
  32. hbox.Add(self.list, 1, wx.EXPAND)
  33. panel.SetSizer(hbox)
  34. self.SetTitle('Actresses')
  35. self.Centre()
  36. def main():
  37. app = wx.App()
  38. ex = Example(None)
  39. ex.Show()
  40. app.MainLoop()
  41. if __name__ == '__main__':
  42. main()

该代码示例在wx.ListCtrl中显示有关女演员的数据。

  1. self.list = wx.ListCtrl(panel, wx.ID_ANY, style=wx.LC_REPORT)

我们用wx.LC_REPORT样式创建一个wx.ListCtrl

  1. self.list.InsertColumn(0, 'name', width=140)
  2. self.list.InsertColumn(1, 'place', width=130)
  3. self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)

我们插入三列。 我们可以指定列的width和列的format。 默认格式为wx.LIST_FORMAT_LEFT

  1. idx = 0
  2. for i in data:
  3. index = self.list.InsertItem(idx, i[0])
  4. self.list.SetItem(index, 1, i[1])
  5. self.list.SetItem(index, 2, i[2])
  6. idx += 1

我们使用两种方法将数据插入wx.ListCtrl。 每行以InsertItem()方法开头。 方法的第一个参数指定行号。 该方法返回行索引。 SetItem()方法将数据添加到当前行的连续列中。

Mixin

Mixins 是进一步增强wx.ListCtrl函数的类。 它们位于wx.lib.mixins.listctrl模块中。 为了使用它们,我们必须从这些类继承。

有六个 mixin:

  • wx.ColumnSorterMixin
  • wx.ListCtrlAutoWidthMixin
  • wx.ListCtrlSelectionManagerMix
  • wx.TextEditMixin
  • wx.CheckListCtrlMixin
  • wx.ListRowHighlighter

wx.ColumnSorterMixin是一个混合器,可以对报表视图中的列进行排序。 wx.ListCtrlAutoWidthMixin类自动将最后一列的大小调整为wx.ListCtrl的末尾。 默认情况下,最后一列不占用剩余空间。 请参阅前面的示例。 wx.ListCtrlSelectionManagerMix定义了平台无关的选择策略。 wx.TextEditMixin可以编辑文本。 wx.CheckListCtrlMixin向每行添加一个复选框。 这样我们可以控制行。 我们可以将每一行设置为选中或取消选中。 wx.ListRowHighlighter处理wx.ListCtrl中交替行的自动背景突出显示。

wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin

以下代码显示了如何使用wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin

autowidth.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example, we use wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin
  6. with a wx.ListBox.
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: May 2018
  10. """
  11. import wx
  12. import wx.lib.mixins.listctrl
  13. data = [('Jessica Alba', 'Pomona', '1981'), ('Sigourney Weaver', 'New York', '1949'),
  14. ('Angelina Jolie', 'Los Angeles', '1975'), ('Natalie Portman', 'Jerusalem', '1981'),
  15. ('Rachel Weiss', 'London', '1971'), ('Scarlett Johansson', 'New York', '1984')]
  16. class AutoWidthListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin):
  17. def __init__(self, parent, *args, **kw):
  18. wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT)
  19. wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin.__init__(self)
  20. class Example(wx.Frame):
  21. def __init__(self, *args, **kw):
  22. super(Example, self).__init__(*args, **kw)
  23. self.InitUI()
  24. def InitUI(self):
  25. hbox = wx.BoxSizer(wx.HORIZONTAL)
  26. panel = wx.Panel(self)
  27. self.list = AutoWidthListCtrl(panel)
  28. self.list.InsertColumn(0, 'name', width=140)
  29. self.list.InsertColumn(1, 'place', width=130)
  30. self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)
  31. idx = 0
  32. for i in data:
  33. index = self.list.InsertItem(idx, i[0])
  34. self.list.SetItem(index, 1, i[1])
  35. self.list.SetItem(index, 2, i[2])
  36. idx += 1
  37. hbox.Add(self.list, 1, wx.EXPAND)
  38. panel.SetSizer(hbox)
  39. self.SetTitle('Actresses')
  40. self.Centre()
  41. def main():
  42. app = wx.App()
  43. ex = Example(None)
  44. ex.Show()
  45. app.MainLoop()
  46. if __name__ == '__main__':
  47. main()

我们稍微改变前面的示例。

  1. import wx.lib.mixins.listctrl

在这里,我们导入 mixin 模块。

  1. class AutoWidthListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin):
  2. def __init__(self, parent, *args, **kw):
  3. wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT)
  4. wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin.__init__(self)

我们创建一个新的AutoWidthListCtrl类。 此类从wx.ListCtrlwx.lib.mixins.listctrl.ListCtrlAutoWidthMixin继承。 这称为多重继承。 最后一列将自动调整大小以占据wx.ListCtrl的剩余宽度。

wx.lib.mixins.listctrl.ColumnSorterMixin

以下示例创建可排序的列。 如果单击列标题,则会对列中的相应行进行排序。

sorted.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example, we create sortable columns with
  6. wx.lib.mixins.listctrl.ColumnSorterMixin
  7. author: Jan Bodnar
  8. website: www.zetcode.com
  9. last modified: May 2018
  10. """
  11. import wx
  12. import wx.lib.mixins.listctrl
  13. actresses = {
  14. 1 : ('Jessica Alba', 'Pomona', '1981'),
  15. 2 : ('Sigourney Weaver', 'New York', '1949'),
  16. 3 : ('Angelina Jolie', 'Los Angeles', '1975'),
  17. 4 : ('Natalie Portman', 'Jerusalem', '1981'),
  18. 5 : ('Rachel Weiss', 'London', '1971'),
  19. 6 : ('Scarlett Johansson', 'New York', '1984')
  20. }
  21. class SortedListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ColumnSorterMixin):
  22. def __init__(self, parent):
  23. wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT)
  24. wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, len(actresses))
  25. self.itemDataMap = actresses
  26. def GetListCtrl(self):
  27. return self
  28. class Example(wx.Frame):
  29. def __init__(self, *args, **kw):
  30. super(Example, self).__init__(*args, **kw)
  31. self.InitUI()
  32. def InitUI(self):
  33. hbox = wx.BoxSizer(wx.HORIZONTAL)
  34. panel = wx.Panel(self)
  35. self.list = SortedListCtrl(panel)
  36. self.list.InsertColumn(0, 'name', width=140)
  37. self.list.InsertColumn(1, 'place', width=130)
  38. self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)
  39. items = actresses.items()
  40. idx = 0
  41. for key, data in items:
  42. index = self.list.InsertItem(idx, data[0])
  43. self.list.SetItem(index, 1, data[1])
  44. self.list.SetItem(index, 2, data[2])
  45. self.list.SetItemData(index, key)
  46. idx += 1
  47. hbox.Add(self.list, 1, wx.EXPAND)
  48. panel.SetSizer(hbox)
  49. self.SetTitle('Actresses')
  50. self.Centre()
  51. def main():
  52. app = wx.App()
  53. ex = Example(None)
  54. ex.Show()
  55. app.MainLoop()
  56. if __name__ == '__main__':
  57. main()

我们将再次在女演员中使用该示例。

  1. wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, len(actresses))

wx.lib.mixins.listctrl.ColumnSorterMixin接受一个参数:要排序的列数。

  1. self.itemDataMap = actresses

我们必须将要显示在列表控件中的数据映射到itemDataMap属性。 数据必须为字典数据类型。

  1. def GetListCtrl(self):
  2. return self

我们必须创建一个GetListCtrl()方法。 此方法返回将要排序的wx.ListCtrl小部件。

  1. self.list.SetItemData(index, key)

我们必须将每行与一个特殊索引相关联。 这是通过SetItemData方法完成的。

wx.lib.mixins.listctrl.CheckListCtrl

可以在列表控件内放置一个复选框。 在 wxPython 中,我们可以使用wx.lib.mixins.listctrl.CheckListCtrl

repository.py

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. ZetCode wxPython tutorial
  5. In this example, we create a check list control widget.
  6. author: Jan Bodnar
  7. website: www.zetcode.com
  8. last modified: May 2018
  9. """
  10. import wx
  11. from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
  12. packages = [('abiword', '5.8M', 'base'), ('adie', '145k', 'base'),
  13. ('airsnort', '71k', 'base'), ('ara', '717k', 'base'), ('arc', '139k', 'base'),
  14. ('asc', '5.8M', 'base'), ('ascii', '74k', 'base'), ('ash', '74k', 'base')]
  15. class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
  16. def __init__(self, parent):
  17. wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT |
  18. wx.SUNKEN_BORDER)
  19. CheckListCtrlMixin.__init__(self)
  20. ListCtrlAutoWidthMixin.__init__(self)
  21. class Example(wx.Frame):
  22. def __init__(self, *args, **kw):
  23. super(Example, self).__init__(*args, **kw)
  24. panel = wx.Panel(self)
  25. vbox = wx.BoxSizer(wx.VERTICAL)
  26. hbox = wx.BoxSizer(wx.HORIZONTAL)
  27. leftPanel = wx.Panel(panel)
  28. rightPanel = wx.Panel(panel)
  29. self.log = wx.TextCtrl(rightPanel, style=wx.TE_MULTILINE|wx.TE_READONLY)
  30. self.list = CheckListCtrl(rightPanel)
  31. self.list.InsertColumn(0, 'Package', width=140)
  32. self.list.InsertColumn(1, 'Size')
  33. self.list.InsertColumn(2, 'Repository')
  34. idx = 0
  35. for i in packages:
  36. index = self.list.InsertItem(idx, i[0])
  37. self.list.SetItem(index, 1, i[1])
  38. self.list.SetItem(index, 2, i[2])
  39. idx += 1
  40. vbox2 = wx.BoxSizer(wx.VERTICAL)
  41. selBtn = wx.Button(leftPanel, label='Select All')
  42. desBtn = wx.Button(leftPanel, label='Deselect All')
  43. appBtn = wx.Button(leftPanel, label='Apply')
  44. self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id=selBtn.GetId())
  45. self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id=desBtn.GetId())
  46. self.Bind(wx.EVT_BUTTON, self.OnApply, id=appBtn.GetId())
  47. vbox2.Add(selBtn, 0, wx.TOP|wx.BOTTOM, 5)
  48. vbox2.Add(desBtn, 0, wx.BOTTOM, 5)
  49. vbox2.Add(appBtn)
  50. leftPanel.SetSizer(vbox2)
  51. vbox.Add(self.list, 4, wx.EXPAND | wx.TOP, 3)
  52. vbox.Add((-1, 10))
  53. vbox.Add(self.log, 1, wx.EXPAND)
  54. vbox.Add((-1, 10))
  55. rightPanel.SetSizer(vbox)
  56. hbox.Add(leftPanel, 0, wx.EXPAND | wx.RIGHT, 5)
  57. hbox.Add(rightPanel, 1, wx.EXPAND)
  58. hbox.Add((3, -1))
  59. panel.SetSizer(hbox)
  60. self.SetTitle('Repository')
  61. self.Centre()
  62. def OnSelectAll(self, event):
  63. num = self.list.GetItemCount()
  64. for i in range(num):
  65. self.list.CheckItem(i)
  66. def OnDeselectAll(self, event):
  67. num = self.list.GetItemCount()
  68. for i in range(num):
  69. self.list.CheckItem(i, False)
  70. def OnApply(self, event):
  71. num = self.list.GetItemCount()
  72. for i in range(num):
  73. if i == 0: self.log.Clear()
  74. if self.list.IsChecked(i):
  75. self.log.AppendText(self.list.GetItemText(i) + '\n')
  76. def main():
  77. app = wx.App()
  78. ex = Example(None)
  79. ex.Show()
  80. app.MainLoop()
  81. if __name__ == '__main__':
  82. main()

该示例使用wx.lib.mixins.listctrl.CheckListCtrl创建仓库 UI。

  1. class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
  2. def __init__(self, parent):
  3. wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT |
  4. wx.SUNKEN_BORDER)
  5. CheckListCtrlMixin.__init__(self)
  6. ListCtrlAutoWidthMixin.__init__(self)

我们从三个不同的类继承。

  1. def OnSelectAll(self, event):
  2. num = self.list.GetItemCount()
  3. for i in range(num):
  4. self.list.CheckItem(i)

OnSelectAll()方法选择所有复选框。 GetItemCount()确定项目数,CheckItem()方法标记当前复选框。

wxPython 中的高级小部件 - 图4

图:存储库

在 wxPython 教程的这一部分中,我们介绍了几个高级小部件,包括wx.ListBoxwx.html.HtmlWindowwx.ListCtrl