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
