2011-12-06 64 views
2

使用wx.TreeCtrl(在wxPython中)來顯示列表中的數據。如何創建一棵樹,以便在列表中更改數據時更新樹視圖(即通過調用wx.TreeCtrl.Refresh)?wxPython的自動更新wx.TreeCtrl

data = [ 'item1', 
     ['item2', ['item2.1','item2.2'],], 
     ['item3', [['item3.1', ['item3.1.1','item3.1.2']]]],] 

一個解決方案,我發現那種作品是創建一個虛擬樹,併爲刷新重寫:

def Refresh(self): 
    self.CollapseAll() 
    self.Expand(self.root) 

列表本身(從數據庫構建的)作爲構成

由於樹是虛擬的,所以在展開所有節點時再次從列表中讀取。但重寫刷新可能是一個黑客攻擊,我正在尋找一個更乾淨的解決方案。有很好的例子,如何做一個網格和表格(http://svn.wxwidgets.org/viewvc/wx/wxPython/trunk/demo/Grid_MegaExample.py?view=markup),但我找不到任何一顆樹。

編輯& ANSWER

有時爲了解決一個問題,最好制定的問題。我使用的是由Rappin和Dunn撰寫的「wxPython in Action」中描述的虛擬樹。但這是一個窮人的解決方案。正確的做法是從VirtualTree中派生一個類。如果有人遇到同樣的問題,請在此發佈解決方案。該解決方案是(http://wxwidgets2.8.sourcearchive.com/documentation/2.8.8.0/TreeMixin_8py-source.html)的修剪版本。

import wx 
from wx.lib.mixins.treemixin import VirtualTree 
items = [('item 0', [('item 2', [('a1', []),('b1', [])]), ('item 3', [])]), 
     ('item 1', [('item 4', [('a3', []),('b3', [])]), ('item 5', [])])] 

class MyTree(VirtualTree, wx.TreeCtrl): 
    def __init__(self, *args, **kw): 
     super(MyTree, self).__init__(*args, **kw) 
     self.RefreshItems() 
     #OnTest emulates event that causes data to change 
     self.Bind(wx.EVT_KEY_DOWN, self.OnTest) 
    def OnTest(self, evt): 
     items[0]=('boo', [('item 2', [('a1', []),('b1', [])]), ('item 3', [])]) 
     self.RefreshItems()   
    def OnGetItemText(self, index): 
     return self.GetText(index) 
    def OnGetChildrenCount(self, indices): 
     return self.GetChildrenCount(indices) 
    def GetItem(self, indices): 
     text, children = 'Hidden root', items 
     for index in indices: text, children = children[index] 
     return text, children 
    def GetText(self, indices): 
     return self.GetItem(indices)[0] 
    def GetChildrenCount(self, indices): 
     return len(self.GetChildren(indices)) 
    def GetChildren(self, indices): 
     return self.GetItem(indices)[1]  

class TreeFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, title='wxTree Test Program') 
     self.tree = MyTree(self, style=wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT) 

if __name__ == '__main__': 
    app = wx.PySimpleApp() 
    frame = TreeFrame() 
    frame.Show() 
    app.MainLoop() 

回答

1

我認爲最合適的解決方案,這樣的問題是使用Observer模式,具體而言,PubSub的庫:wxPython and PubSub

+0

Observer模式有助於進一步完善的解決方案。它可以從更改數據的函數發送消息,並且所有樹都可以訂閱此事件(實際應用程序中有多個需要更新的樹和表)。問題中的解決方案仍然需要,以便能夠調用RefreshItems()。不過,非常感謝你的回答!我很尷尬,我沒有考慮觀察者模式。目前,我明確地在調用數據的函數中調用了所有需要的刷新函數。 – bitman