我一直在尝试使用wxPython创建需要树/列表编辑器的程序。但是,我很快遇到了一个问题,即文本编辑框的问题是子项出现在列表的底部,而不是放在适当的位置。在下面显示的简化示例中,我双击编辑AA旁边的单元格,但是编辑框出现在最后一行。
但是,当我编辑父单元格时,没有问题,并且可以正确显示。
我已附上以下代码。对于解决此问题的任何建议,我将不胜感激。谢谢!
import wx
import wx.dataview as dv
class Node:
def __init__(self, name, parent):
self.name = name
self.parent = parent
self.children = []
self.value = ''
class DVC_Model(dv.PyDataViewModel):
def __init__(self, data):
super().__init__()
self.data = data
self.UseWeakRefs(True)
def GetColumnCount(self):
return 2
def GetColumnType(self, col):
return 'string'
def GetChildren(self, item, children):
if not item:
for child in self.data.children:
children.append(self.ObjectToItem(child))
return len(self.data.children)
obj = self.ItemToObject(item)
for child in obj.children:
children.append(self.ObjectToItem(child))
return len(obj.children)
def GetParent(self, item):
obj = self.ItemToObject(item)
if obj.parent is None:
return dv.NullDataViewItem
return self.ObjectToItem(obj.parent)
def IsContainer(self, item):
if not item:
return True
obj = self.ItemToObject(item)
return len(obj.children) > 0
def HasContainerColumns(self, item):
return True
def GetValue(self, item, col):
if not item:
return [root.name, root.value][col]
obj = self.ItemToObject(item)
return [obj.name, obj.value][col]
def SetValue(self, variant, item, col):
obj = self.ItemToObject(item)
if col == 1:
obj.value = variant
return True
def GetAttr(self, item, col, attr):
obj = self.ItemToObject(item)
if len(obj.children) > 0:
attr.SetColour('blue')
attr.SetBold(True)
return True
return False
if __name__ == '__main__':
app = wx.App()
window = wx.Frame(None, -1, "Test title", style=wx.DEFAULT_FRAME_STYLE)
window.SetFocus()
dvc = dv.DataViewCtrl(window, style=wx.BORDER_THEME | dv.DV_ROW_LINES | dv.DV_VERT_RULES | dv.DV_MULTIPLE)
root = Node('root', None)
A = Node('A', root)
AA = Node('AA', A)
AB = Node('AB', A)
A.children = [AA, AB]
B = Node('B', root)
BA = Node('BA', B)
BB = Node('BB', B)
B.children = [BA, BB]
root.children = [A, B]
model = DVC_Model(root)
dvc.AssociateModel(model)
dvc.AppendTextColumn('Name', 0)
dvc.AppendTextColumn('Value', 1, mode=dv.DATAVIEW_CELL_EDITABLE)
window.Show(True)
app.MainLoop()
更新:我在Linux上测试了该程序,但遇到了分段错误。 wxPython演示程序可以正常工作。也许可以帮助识别我的代码中的问题。
答案 0 :(得分:0)
看到Linux上的错误后,我开始进行进一步的测试,并意识到我正在GetParent()
中将根节点作为父节点返回给节点A和B。但是,该节点对于wxPython和I应该是不可见的需要返回wx.NullDataViewItem
。我发现的解决方案是修改GetParent()
或实例化没有父对象的对象,如下所示:
def GetParent(self, item):
obj = self.ItemToObject(item)
if obj.parent is None or obj.parent == self.data: # if the parent is the invisible root node, return null
return dv.NullDataViewItem
return self.ObjectToItem(obj.parent)
root = Node('root', None)
A = Node('A', None) # root changed to None
AA = Node('AA', A)
AB = Node('AB', A)
A.children = [AA, AB]
B = Node('B', None) # root changed to None
BA = Node('BA', B)
BB = Node('BB', B)
B.children = [BA, BB]
root.children = [A, B]