Hi,
I think I have found a problem with the ItemHasChildren method of both wx.gizmo.TreeListCtrl and wx.TreeCtrl. The problem occurs when ItemHasChildren is called for the tree root item but the root is not displayed (wx.TR_HIDE_ROOT). Specifically, the ItemHasChildren doesn't return the expected boolean results according to whether the root has any children or not. The gizmo TreeListCtrl returns True either way, and the TreeCtrl raises a PyAssertionError.
I am using Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32; with wxPython version 2.8.7.1 (same problem on 2.8.6.1)
The following script demonstrates the problem:
import wx.gizmos
class TestFrame(wx.Frame):
"""
Demonstration that the ItemHasChildren() method does not work properly
on the root item of a tree if the root is hidden. Test 2 demonstrates
the problem. Test 4 cannot be run (see Traceback included) below.
"""
def __init__(self):
wx.Frame.__init__(self, None, title="tree", size=(400,500))
"""
Let's make 4 trees to test the 4 cases of:
gizmo TreeListCtrl vs standard TreeCtrl
x
root displayed or wx.TR_HIDE_ROOT set
"""
self.panel = wx.Panel(self)
szrMain = wx.BoxSizer(wx.VERTICAL)
#1
self.treegizroot = wx.gizmos.TreeListCtrl(self.panel, -1,
style=wx.TR_FULL_ROW_HIGHLIGHT,
size=(150,150))
self.testTreeList(self.treegizroot,
"1 - Gizmo tree list with root displayed")
#2
self.treegiznoroot = wx.gizmos.TreeListCtrl(self.panel, -1,
style=wx.TR_FULL_ROW_HIGHLIGHT | \
wx.TR_HIDE_ROOT, size=(150,150))
self.testTreeList(self.treegiznoroot,
"2 - Gizmo tree list with root hidden")
#3
self.treeroot = wx.TreeCtrl(self.panel, -1,
style=wx.TR_FULL_ROW_HIGHLIGHT,
size=(150,150))
self.testTree(self.treeroot, "3 - Tree with root displayed")
#4
self.treenoroot = wx.TreeCtrl(self.panel, -1,
style=wx.TR_FULL_ROW_HIGHLIGHT | \
wx.TR_HIDE_ROOT, size=(150,150))
#self.testTree(self.treenoroot, "4 - Tree with root hidden")
"""
Traceback (most recent call last):
File "C:\Projects\python\storage\test_tree_has_children.py", line 92, in <module>
frame = TestFrame()
File "C:\Projects\python\storage\test_tree_has_children.py", line 40, in __init__
self.testTree(self.treenoroot, "4 - Tree with root hidden")
File "C:\Projects\python\storage\test_tree_has_children.py", line 81, in testTree
if tree.ItemHasChildren(root) \
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\_controls.py", line 5332, in ItemHasChildren
return _controls_.TreeCtrl_ItemHasChildren(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "tvItem->hItem != ((HTREEITEM)(ULONG_PTR)-0x10000)" failed at ..\..\src\msw\treectrl.cpp(797) in wxTreeCtrl::DoGetItem(): can't retrieve virtual root item
"""
szrMain.Add(self.treegiznoroot)
szrMain.Add(self.treegizroot)
szrMain.Add(self.treenoroot)
szrMain.Add(self.treeroot)
self.panel.SetSizer(szrMain)
szrMain.SetSizeHints(self)
self.Fit()
def testTreeList(self, treelist, test_label):
"""
Test gizmo tree list controls.
Does ItemHasChildren say the root has children even when
it doesn't (yet)?
"""
treelist.AddColumn("Col 1")
treelist.AddColumn("Col 2")
treelist.SetMainColumn(0)
treelist.SetColumnWidth(0, 100)
treelist.SetColumnWidth(1, 500)
root = treelist.AddRoot("root")
message = "ItemHasChildren says it has children" \
if treelist.ItemHasChildren(root) \
else "ItemHasChildren says it has NO children"
wx.MessageBox("%s - child not added yet: %s" % \
(test_label, message))
treelist.AppendItem(root, "child")
message = "ItemHasChildren says it has children" \
if treelist.ItemHasChildren(root) \
else "ItemHasChildren says it has NO children"
wx.MessageBox("%s - just added child: %s" % (test_label, message))
def testTree(self, tree, test_label):
"""
Test tree controls
Does ItemHasChildren say the root has children even when
it doesn't (yet)?
"""
root = tree.AddRoot("root")
message = "ItemHasChildren says it has children" \
if tree.ItemHasChildren(root) \
else "ItemHasChildren says it has NO children"
wx.MessageBox("%s - child not added yet: %s" % \
(test_label, message))
tree.AppendItem(root, "child")
message = "ItemHasChildren says it has children" \
if tree.ItemHasChildren(root) \
else "ItemHasChildren says it has NO children"
wx.MessageBox("%s - just added child: %s" % (test_label, message))
app = wx.PySimpleApp(redirect=True, filename='output.txt')
frame = TestFrame()
frame.Show()
app.MainLoop()
···
-----------------------------------------------------------------------------------
In the meantime I use the following instead:
def ItemHasChildren(tree, parent):
item, cookie = tree.GetFirstChild(parent)
return True if item else False
Have I understood everything correctly? Is this a bug? If so, is here the right place to raise it?
All the best, Grant
--
___________________________________
Dr Grant Paton-Simpson
Director, Paton-Simpson & Associates Ltd
www.p-s.co.nz
16 Summit Drive, Mt Albert, Auckland 1025
(09) 849-6696
(09) 849-6699
___________________________________