使用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()
Observer模式有助于进一步完善的解决方案。它可以从更改数据的函数发送消息,并且所有树都可以订阅此事件(实际应用程序中有多个需要更新的树和表)。问题中的解决方案仍然需要,以便能够调用RefreshItems()。不过,非常感谢你的回答!我很尴尬,我没有考虑观察者模式。目前,我明确地在调用数据的函数中调用了所有需要的刷新函数。 – bitman