从 TreeEvent 获取的 TreeItemId 与从 AppendItem 获取的不同
TreeItemId obtained from TreeEvent is not the same as obtained from AppendItem
我正在构建一个程序来存储一些复杂的对象,我正在为 UI 使用 wxPython。对象层次结构将具有树形表示 (TreeCtrl
)。我正在使用字典将对象从 UI 映射到数据库,使用 AppendItem
返回的 TreeItemId
作为键,对象本身作为值(实际上我没有使用对象作为值,但它简化了问题)。以下片段举例说明了我正在尝试做的事情:
import wx
class ComplexObject(object):
def __init__(self, name, otherdata):
self.name = name
self.otherdata = otherdata
class TestFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super(TestFrame, self).__init__(*args, **kwargs)
self.tree = wx.TreeCtrl(self)
self.rootid = self.tree.AddRoot("Root")
self.tree.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onrightclick)
self.objectmap = {}
def addobject(self, obj):
itemid = self.tree.AppendItem(self.rootid, obj.name)
self.objectmap[itemid] = obj
def onrightclick(self, event):
itemid = event.GetItem()
if itemid == self.rootid:
return
obj = self.objectmap[itemid]
print "Do something with ComplexObject {}".format(obj.name)
if __name__ == '__main__':
app = wx.App(False)
testframe = TestFrame(None)
for i in range(3):
obj = ComplexObject('obj{}'.format(i), i)
testframe.addobject(obj)
testframe.Show()
app.MainLoop()
当我右键单击树中的一个条目时,我得到一个 KeyError
,因为我从事件 (itemid = event.GetItem()
) 中得到的对象与我添加一个项目时得到的对象不同(itemid = self.tree.AppendItem(self.rootid, obj.name)
)。这是预期的行为吗?我应该如何着手实现我想要做的事情?我开始尝试 SetPyData
和 GetPyData
,但我希望有更好的方法。
非常感谢。
平台信息: MS Windows 7, Python 2.7.9, wxPython 2.8.12.1
是的,这是意料之中的。
你可以把 TreeItemId
想象成一个封闭的盒子,里面有一个依赖于实现的句柄,而 treectrl 是唯一可以打开盒子取出句柄的。对于同一个树项目,您可能会在不同时间看到不同的盒子,但它们内部的手柄都是相同的。但是由于句柄本身是一个实现细节,所以没有程序可以访问它。
使用 SetPyData
将数据关联到树项是执行此类操作的正确方法。如果您想将相关数据保存在单独的字典中,那么您可以在添加项目时生成唯一的字典键,然后将它们的键传递给 SetPyData
,并在稍后使用 GetPyData
获取键需要从字典中获取值对象。
我正在构建一个程序来存储一些复杂的对象,我正在为 UI 使用 wxPython。对象层次结构将具有树形表示 (TreeCtrl
)。我正在使用字典将对象从 UI 映射到数据库,使用 AppendItem
返回的 TreeItemId
作为键,对象本身作为值(实际上我没有使用对象作为值,但它简化了问题)。以下片段举例说明了我正在尝试做的事情:
import wx
class ComplexObject(object):
def __init__(self, name, otherdata):
self.name = name
self.otherdata = otherdata
class TestFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super(TestFrame, self).__init__(*args, **kwargs)
self.tree = wx.TreeCtrl(self)
self.rootid = self.tree.AddRoot("Root")
self.tree.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onrightclick)
self.objectmap = {}
def addobject(self, obj):
itemid = self.tree.AppendItem(self.rootid, obj.name)
self.objectmap[itemid] = obj
def onrightclick(self, event):
itemid = event.GetItem()
if itemid == self.rootid:
return
obj = self.objectmap[itemid]
print "Do something with ComplexObject {}".format(obj.name)
if __name__ == '__main__':
app = wx.App(False)
testframe = TestFrame(None)
for i in range(3):
obj = ComplexObject('obj{}'.format(i), i)
testframe.addobject(obj)
testframe.Show()
app.MainLoop()
当我右键单击树中的一个条目时,我得到一个 KeyError
,因为我从事件 (itemid = event.GetItem()
) 中得到的对象与我添加一个项目时得到的对象不同(itemid = self.tree.AppendItem(self.rootid, obj.name)
)。这是预期的行为吗?我应该如何着手实现我想要做的事情?我开始尝试 SetPyData
和 GetPyData
,但我希望有更好的方法。
非常感谢。
平台信息: MS Windows 7, Python 2.7.9, wxPython 2.8.12.1
是的,这是意料之中的。
你可以把 TreeItemId
想象成一个封闭的盒子,里面有一个依赖于实现的句柄,而 treectrl 是唯一可以打开盒子取出句柄的。对于同一个树项目,您可能会在不同时间看到不同的盒子,但它们内部的手柄都是相同的。但是由于句柄本身是一个实现细节,所以没有程序可以访问它。
使用 SetPyData
将数据关联到树项是执行此类操作的正确方法。如果您想将相关数据保存在单独的字典中,那么您可以在添加项目时生成唯一的字典键,然后将它们的键传递给 SetPyData
,并在稍后使用 GetPyData
获取键需要从字典中获取值对象。