Wxpython高级组件wx.ListCtrl
wx.ListCtrl 组件
wx.ListCtrl是一个项目列表的图形表示。一个wx.ListBox只能有一列,而wx.ListCtrl可以有多于一列。例如,一个文件管理器使用wx.ListCtrl来显示文件系统中的目录和文件。一个CD刻录程序在wx.ListCtrl中显示要刻录的文件。
一个wx.ListCtrl可以以三种不同的样式使用。列表视图、报告视图或图标视图。这些样式由wx.ListCtrl窗口样式控制,wx.LC_REPORT、wx.LC_LIST和wx.LC_ICON。
更多参考文档:http://xoomer.virgilio.it/infinity77/wxPython/Widgets/wx.ListCtrl.html
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 例子
#listctrl_exam.py import wx data = [('Jessica Alba', 'Pomona', '1981'), ('Sigourney Weaver', 'New York', '1949'), ('Angelina Jolie', 'los angeles', '1975'), ('Natalie Portman', 'Jerusalem', '1981'), ('Rachel Weiss', 'London', '1971'), ('Scarlett Johansson', 'New York', '1984' )] class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): hbox = wx.BoxSizer(wx.HORIZONTAL) panel = wx.Panel(self) self.list = wx.ListCtrl(panel, wx.ID_ANY, style=wx.LC_REPORT) self.list.InsertColumn(0, 'name', width=140) self.list.InsertColumn(1, 'place', width=130) self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90) idx = 0 for i in data: index = self.list.InsertItem(idx, i[0]) self.list.SetItem(index, 1, i[1]) self.list.SetItem(index, 2, i[2]) idx += 1 hbox.Add(self.list, 1, wx.EXPAND) panel.SetSizer(hbox) self.SetTitle('Actresses') self.Centre() def main(): app = wx.App() ex = Example(None) ex.Show() app.MainLoop() if __name__ == '__main__': main()
该代码示例在wx.ListCtrl
中显示有关女演员的数据。
self.list = wx.ListCtrl(panel, wx.ID_ANY, style=wx.LC_REPORT)
我们创建一个具有wx.LC_REPORT
风格的wx.ListCtrl
。
self.list.InsertColumn(0, 'name', width=140) self.list.InsertColumn(1, 'place', width=130) self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)
我们插入三列。我们可以指定列的宽度和列的格式。默认的格式是wx.LIST_FORMAT_LEFT。
idx = 0 for i in data: index = self.list.InsertItem(idx, i[0]) self.list.SetItem(index, 1, i[1]) self.list.SetItem(index, 2, i[2]) idx += 1
我们使用两个方法将数据插入到wx.ListCtrl
中。每一行都以InsertItem()
方法开始。该方法的第一个参数指定了行号。该方法返回行的索引。SetItem()
方法将数据添加到当前行的连续列中。
Mixins
Mixins是进一步增强wx.ListCtrl
功能的类。它们位于wx.lib.mixins.listctrl
模块中。为了使用它们,我们必须继承这些类的功能。
有六个 mixins。
- wx.ColumnSorterMixin
- wx.ListCtrlAutoWidthMixin
- wx.ListCtrlSelectionManagerMix
- wx.TextEditMixin
- wx.CheckListCtrlMixin
- wx.ListRowHighlighter
wx.ColumnSorterMixin
是一个能够在报表视图中对列进行排序的mixin。
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 import wx import wx.lib.mixins.listctrl data = [('Jessica Alba', 'Pomona', '1981'), ('Sigourney Weaver', 'New York', '1949'), ('Angelina Jolie', 'Los Angeles', '1975'), ('Natalie Portman', 'Jerusalem', '1981'), ('Rachel Weiss', 'London', '1971'), ('Scarlett Johansson', 'New York', '1984')] class AutoWidthListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin): def __init__(self, parent, *args, **kw): wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT) wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin.__init__(self) class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): hbox = wx.BoxSizer(wx.HORIZONTAL) panel = wx.Panel(self) self.list = AutoWidthListCtrl(panel) self.list.InsertColumn(0, 'name', width=140) self.list.InsertColumn(1, 'place', width=130) self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90) idx = 0 for i in data: index = self.list.InsertItem(idx, i[0]) self.list.SetItem(index, 1, i[1]) self.list.SetItem(index, 2, i[2]) idx += 1 hbox.Add(self.list, 1, wx.EXPAND) panel.SetSizer(hbox) self.SetTitle('Actresses') self.Centre() def main(): app = wx.App() ex = Example(None) ex.Show() app.MainLoop() if __name__ == '__main__': main()
我们把前面的例子改一下。
import wx.lib.mixins.listctrl
这里我们导入 mixin 模块。
class AutoWidthListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin):
def __init__(self, parent, *args, **kw):
wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT)
wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin.__init__(self)
我们创建一个新的AutoWidthListCtrl
类。这个类继承自wx.ListCtrl
和wx.lib.mixins.listctrl.ListCtrlAutoWidthMixin
。这就是所谓的多继承。最后一列会自动调整大小以占用wx.ListCtrl
的剩余宽度。
wx.lib.mixins.listctrl.ColumnSorterMixin
下面的例子创建了可排序的列。如果我们点击列头,列中相应的行就会被排序。
#sorted.py import wx import wx.lib.mixins.listctrl actresses = { 1 : ('Jessica Alba', 'Pomona', '1981'), 2 : ('Sigourney Weaver', 'New York', '1949'), 3 : ('Angelina Jolie', 'Los Angeles', '1975'), 4 : ('Natalie Portman', 'Jerusalem', '1981'), 5 : ('Rachel Weiss', 'London', '1971'), 6 : ('Scarlett Johansson', 'New York', '1984') } class SortedListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.ColumnSorterMixin): def __init__(self, parent): wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT) wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, len(actresses)) self.itemDataMap = actresses def GetListCtrl(self): return self class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) self.InitUI() def InitUI(self): hbox = wx.BoxSizer(wx.HORIZONTAL) panel = wx.Panel(self) self.list = SortedListCtrl(panel) self.list.InsertColumn(0, 'name', width=140) self.list.InsertColumn(1, 'place', width=130) self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90) items = actresses.items() idx = 0 for key, data in items: index = self.list.InsertItem(idx, data[0]) self.list.SetItem(index, 1, data[1]) self.list.SetItem(index, 2, data[2]) self.list.SetItemData(index, key) idx += 1 hbox.Add(self.list, 1, wx.EXPAND) panel.SetSizer(hbox) self.SetTitle('Actresses') self.Centre() def main(): app = wx.App() ex = Example(None) ex.Show() app.MainLoop() if __name__ == '__main__': main()
我们再以女演员为例。
wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, len(actresses))
wx.lib.mixins.listctrl.ColumnSorterMixin
接受一个参数:要排序的列数。
self.itemDataMap = actresses
我们必须将我们要显示在列表控件中的数据映射到itemDataMap
属性中。数据必须是一个字典数据类型。
def GetListCtrl(self):
return self
我们必须创建一个GetListCtrl()方法。这个方法返回要排序的wx.ListCtrl部件。
self.list.SetItemData(index, key)
我们必须为每一行分配一个特殊的索引。这是通过SetItemData
方法完成的。
wx.lib.mixins.listctrl.CheckListCtrl
列表控件中可以放置一个复选框。在wxPython中,我们可以使用wx.lib. mixins.listctrl.CheckListCtrl
。
#repository.py import wx from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin packages = [('abiword', '5.8M', 'base'), ('adie', '145k', 'base'), ('airsnort', '71k', 'base'), ('ara', '717k', 'base'), ('arc', '139k', 'base'), ('asc', '5.8M', 'base'), ('ascii', '74k', 'base'), ('ash', '74k', 'base')] class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin): def __init__(self, parent): wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT | wx.SUNKEN_BORDER) CheckListCtrlMixin.__init__(self) ListCtrlAutoWidthMixin.__init__(self) class Example(wx.Frame): def __init__(self, *args, **kw): super(Example, self).__init__(*args, **kw) panel = wx.Panel(self) vbox = wx.BoxSizer(wx.VERTICAL) hbox = wx.BoxSizer(wx.HORIZONTAL) leftPanel = wx.Panel(panel) rightPanel = wx.Panel(panel) self.log = wx.TextCtrl(rightPanel, style=wx.TE_MULTILINE|wx.TE_READONLY) self.list = CheckListCtrl(rightPanel) self.list.InsertColumn(0, 'Package', width=140) self.list.InsertColumn(1, 'Size') self.list.InsertColumn(2, 'Repository') idx = 0 for i in packages: index = self.list.InsertItem(idx, i[0]) self.list.SetItem(index, 1, i[1]) self.list.SetItem(index, 2, i[2]) idx += 1 vbox2 = wx.BoxSizer(wx.VERTICAL) selBtn = wx.Button(leftPanel, label='Select All') desBtn = wx.Button(leftPanel, label='Deselect All') appBtn = wx.Button(leftPanel, label='Apply') self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id=selBtn.GetId()) self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id=desBtn.GetId()) self.Bind(wx.EVT_BUTTON, self.OnApply, id=appBtn.GetId()) vbox2.Add(selBtn, 0, wx.TOP|wx.BOTTOM, 5) vbox2.Add(desBtn, 0, wx.BOTTOM, 5) vbox2.Add(appBtn) leftPanel.SetSizer(vbox2) vbox.Add(self.list, 4, wx.EXPAND | wx.TOP, 3) vbox.Add((-1, 10)) vbox.Add(self.log, 1, wx.EXPAND) vbox.Add((-1, 10)) rightPanel.SetSizer(vbox) hbox.Add(leftPanel, 0, wx.EXPAND | wx.RIGHT, 5) hbox.Add(rightPanel, 1, wx.EXPAND) hbox.Add((3, -1)) panel.SetSizer(hbox) self.SetTitle('Repository') self.Centre() def OnSelectAll(self, event): num = self.list.GetItemCount() for i in range(num): self.list.CheckItem(i) def OnDeselectAll(self, event): num = self.list.GetItemCount() for i in range(num): self.list.CheckItem(i, False) def OnApply(self, event): num = self.list.GetItemCount() for i in range(num): if i == 0: self.log.Clear() if self.list.IsChecked(i): self.log.AppendText(self.list.GetItemText(i) + '\n') def main(): app = wx.App() ex = Example(None) ex.Show() app.MainLoop() if __name__ == '__main__': main()
这个例子用wx.lib.mixins.listctrl.CheckListCtrl
创建了一个版本库UI。
class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
def __init__(self, parent):
wx.ListCtrl.__init__(self, parent, wx.ID_ANY, style=wx.LC_REPORT |
wx.SUNKEN_BORDER)
CheckListCtrlMixin.__init__(self)
ListCtrlAutoWidthMixin.__init__(self)
我们从三个不同的类中继承。
def OnSelectAll(self, event):
num = self.list.GetItemCount()
for i in range(num):
self.list.CheckItem(i)
OnSelectAll()
方法选择所有的复选框。GetItemCount()
确定项数,CheckItem()
方法标记当前复选框。
转载:https://zhuanlan.zhihu.com/p/270279041