實戰wxPython/ target=_blank class=infotextkey>Python系列-039
wxPythontigo提供了一些高級控件。例如,樹形控件、html窗口、網格控件、列表控件、或具有高級樣式功能的編輯器等。
一、wx.ListBox列表框
wx.ListBox列表框控件從一個字符串列表中選擇一個或者多個字符串。所選字符串顯示在一個可以滾動的列表框中,所選中的字符串將特別標記。列表框可以是單選 (如果選擇了其中的一個項,則清除先前的選擇項)或者多重選擇(選擇一個項的時,不影響對其他項的選擇)。
列表框元素從0開始編號,雖然元素的最大數量是無限的,但通常最好使用虛擬控件,不需要一次性將所有項添加到其中。由于這個控件沒有做優化,比如在wx.dataview.DataViewCtrl或者使用LC_VIRTUAL樣式的wx.ListCtrl時,需要加載超過上百的項時,性能會有所影響。
注意,列表框不支持除制表符以外的控制字符。
wx.ListBox支持的窗口樣式:
- wx.LB_SINGLE:單選列表。
- wx.LB_MULTIPLE:多選列表。
- wx.LB_EXTENDED:擴展選擇列表:用戶可以使用SHIFT或CTRL鍵以及光標移動鍵或鼠標來擴展選擇。
- wx.LB_HSCROLL:如果內容太多,創建水平滾動條(僅限windows)。
- wx.LB_ALWAYS_SB:始終顯示垂直滾動條。
- wx.LB_NEEDED_SB:只在需要時創建垂直滾動條。
- wx.LB_NO_SB:不創建垂直滾動條(僅限于wxMSW和wxGTK)。
- wx.LB_SORT:列表框內容按字母順序排序。
注意:LB_SINGLE, LB_MULTIPLE和LB_EXTENDED樣式是互斥的,最多可以指定其中一個樣式(單選是默認設置)。
wx.ListBox發出的事件:
- EVT_LISTBOX:當列表中的項被選中或選擇發生變化時,處理wx.EVT_LISTBOX事件。
- EVT_LISTBOX_DCLICK:當雙擊列表框時,處理wx.EVT_LISTBOX_DCLICK事件。
wx.ListBox常用方法:
- Deselect(self, n):取消選擇列表框中的項(只適用于多選擇列表框)。
- EnsureVisible(self, n):確保當前顯示具有給定索引的項。這個方法只在必要時滾動列表框,如果這個項已經顯示,它不會做任何事情。
- FindString(self, string, caseSensitive=False):查找與給定字符串匹配的項。
- GetCount(self):返回控件中的項數。
- GetCountPerPage(self):返回可以放入列表框垂直可見區域的項數量。如果無法確定每頁的條目數,則返回-1。
- GetSelection(self):返回所選項的索引,如果沒有選擇項,則返回NOT_FOUND。
- GetSelections(self):用當前選定項的位置填充整數數組
- GetString(self, n):返回具有給定索引的項的標簽。索引必須是有效的,即小于GetCount返回的值,否則會觸發斷言。值得注意的是,如果控件為空,則不能調用此函數。
- GetTopItem(self):返回最上面可見項的索引。如果該方法沒有為當前平臺實現,則返回NOT_FOUND。
- HitTest (self, point):返回位于point上的項,如果沒有項位于point上,則返回NOT_FOUND。
- InsertItems(self, items, pos):在指定位置之前插入給定數量的字符串。
- IsSelected(self, n):確定是否選擇某項。
- IsSorted(self):如果列表框為LB_SORT樣式,則返回True。此方法主要僅用于內部使用。
- SetFirstItem (self, string):將指定的項設置為第一個可見項。
- SetItemBackgroundColour(self, item, c):如果wx.LB_OWNERDRAW標志被設置,在列表框中設置一個項的背景顏色(僅對MSW有效)。
- SetItemFont(self, item, f):如果wx.LB_OWNERDRAW標志被設置,在列表框中設置一個項的前景顏色(僅對MSW有效)。
- SetSelection(self, n):將選定項設置為給定項n,如果n == NOT_FOUND則完全刪除選定項。注意,這不會觸發任何命令事件,也不會取消控件中支持多個選擇的任何其他項。
- SetString(self, n, string):為給定的項設置標簽。
圖1:wx.ListBox類繼承關系
二、wx.ListBox演示
#列表框(wx.ListBox)
import wx
class SampleListBox(wx.Frame):
def __init__(self, *args, **kw):
super(SampleListBox, self).__init__(*args, **kw)
self.InitUi()
def InitUi(self):
#設置標題
self.SetTitle("實戰wxPython: ListBox演示")
#設置窗口尺寸
self.SetSize(400, 240)
panel = wx.Panel(self)
#水平布局
hbox = wx.BoxSizer(wx.HORIZONTAL)
# 添加一個列表框
self.listbox = wx.ListBox(panel)
hbox.Add(self.listbox, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)
# 按鈕面板
btnPanel = wx.Panel(panel)
vbox = wx.BoxSizer(wx.VERTICAL)
newButon = wx.Button(btnPanel, wx.ID_ANY, "新建", size = (90, 30))
renButton = wx.Button(btnPanel, wx.ID_ANY, "重命名", size = (90, 30))
delButton = wx.Button(btnPanel, wx.ID_ANY, "刪除", size = (90, 30))
clrButton = wx.Button(btnPanel, wx.ID_ANY, "清理", size = (90, 30))
newButon.Bind(wx.EVT_BUTTON, self.NewItem)
renButton.Bind(wx.EVT_BUTTON, self.OnRename)
delButton.Bind(wx.EVT_BUTTON, self.OnDelete)
clrButton.Bind(wx.EVT_BUTTON, self.OnClear)
self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)
vbox.Add((-1, 20)) #距離頂端20像素
vbox.Add(newButon)
vbox.Add(renButton, 0, wx.TOP, 5)
vbox.Add(delButton, 0, wx.TOP, 5)
vbox.Add(clrButton, 0, wx.TOP, 5)
btnPanel.SetSizer(vbox)
hbox.Add(btnPanel, 0.6, wx.EXPAND | wx.RIGHT, 20)
panel.SetSizer(hbox)
self.Centre()
def NewItem(self, e):
text = wx.GetTextFromUser("輸入一個新項", "插入對話框")
if text != "":
self.listbox.Append(text)
def OnRename(self, e):
sel = self.listbox.GetSelection()
text = self.listbox.GetString(sel)
renamed = wx.GetTextFromUser("項重命名", "重命名對話框", text)
if renamed != "":
self.listbox.Delete(sel)
item_id = self.listbox.Insert(renamed, sel)
self.listbox.SetSelection(item_id)
def OnDelete(self, e):
sel = self.listbox.GetSelection()
if sel != -1:
self.listbox.Delete(sel)
def OnClear(self, e):
self.listbox.Clear()
def main():
app = wx.App()
sample = SampleListBox(None)
sample.Show()
app.MainLoop()
if __name__ == "__main__":
main()
這個例子展示了如何從wx.ListBox中添加、修改和刪除項。
self.listbox = wx.ListBox(panel)
hbox.Add(self.listbox, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)
創建一個空的wx.ListBox。設置列表框邊框距離20px。
self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename)
綁定wx. EVT_LISTBOX_DCLICK事件到方法OnRename(),這樣,如果雙擊列表框中的特定元素,就會顯示重命名對話框。
def NewItem(self, e):
text = wx.GetTextFromUser("輸入一個新項", "插入對話框")
if text != "":
self.listbox.Append(text)
通過單擊新建按鈕調用NewItem()方法。在NuwItem方法中,使用包裝器wx.GetTextFromUser()方法顯示一個wx.TextEntryDialog。將對話框中輸入的文本返回給文本變量。如果文本不是空的,我們用append()方法將它添加到列表框中。
if renamed != "":
self.listbox.Delete(sel)
item_id = self.listbox.Insert(renamed, sel)
self.listbox.SetSelection(item_id)
通過刪除項并在同一位置插入新項來重命名項。將選擇設置回已修改的項。
def OnDelete(self, e):
sel = self.listbox.GetSelection()
if sel != -1:
self.listbox.Delete(sel)
要刪除一個項,通過調用GetSelection()方法找到所選項的索引。然后使用delete()方法刪除該項。
def OnClear(self, e):
self.listbox.Clear()
調用Clear()方法清除整個列表框。
圖2:wx.ListBox演示
三、wx.CheckListBox復選列表框
wx.CheckListBox是wx.ListBox的派生類,繼承了它的功能,它在每個選項上額外顯示一個復選框。
wx.CheckListBox發出的事件:
- EVT_CHECKLISTBOX:當選中或取消選中復選框中的項時,處理wx.EVT_CHECKLISTBOX事件。
wx.CkeckListBox常用方法:
- Check(self, item, check=True):設置給定的項的選擇狀態。調用此方法不會導致觸發wx.EVT_CHECKLISTBOX事件。
- GetCheckedItems(self):根據IsChecked返回與控件中已選擇項對應的整數序列。
- GetCheckedStrings(self):根據GetChecked返回與控件的已選擇項對應的字符串元組。
- GetSelections(self):返回當前選定項的索引列表。
- IsChecked(self, item):如果選中給定項則返回True,否則返回False。
- SetCheckedItems(self, indexes):如果在索引序列中找到項的索引,則設置項的已選定狀態。
- SetCheckedStrings(self, strings):如果在字符串序列中找到項的字符串,則設置項的選定狀態。
圖3:wx.CheckListBox類繼承關系
將節二中的演示代碼:
self.listbox = wx.ListBox(panel)
修改成
self.listbox = wx.CheckListBox(panel)
運行,就可以演示使用wx.CheckListBox,效果如圖4:
圖4:wx.CheckListBox演示
四、本文知識點
- 了解和使用wx.ListBox。
- 了解和使用wx.CheckListBox。