wx.TreeCtrl with lib.mixins.treectrl.VirtualTree does not display anything

Hi,

I have a wxPython newbie question. I am trying to show a wx.TreeCtrl
while using mixin.mixins.VirtualTree to connect the gui to some model.
I have a separate class for the tree model which is populated with
some items when the wx application is started.

I derive the MyTree class from VirtualTree and wx.TreeCtrl and
overwrite the OnGetChildrenCount and OnGetItemText methods. I have
debugged them and they return the correct values. However, no tree
control shows up on the screen. I suppose I am not calling the
__init__ functions correctly since the OnGet... methods in MyTree are
never called. When I call the wx.TreeCtrl.__init__ method in the
MyTree class the program crashes (PyDeadObject). Here is my wx code:

···

-----------------------------------------------------------------------------------------
import wx
from wx.lib.mixins.treemixin import VirtualTree

class TreeFrame(wx.Frame):
    def __init__(self, model):
        wx.Frame.__init__(self, None, title='wxTree Test Program')
        self.model = model

        pa_main = wx.Panel(self)
        self.tree = MyTree(pa_main, treemodel=model)
        self.tree.SetMinSize((150, 300))

        szr = wx.BoxSizer(wx.VERTICAL)
        szr.Add(self.tree, 1, wx.ALIGN_CENTER)
        pa_main.SetSizer(szr)
        pa_main.Fit()
        szr.SetSizeHints(self)

class MyTree(VirtualTree, wx.TreeCtrl):
    def __init__(self, *args, **kwargs):
        kwargs['style'] = wx.TR_HIDE_ROOT
        self.model = kwargs.pop('treemodel')
        super(MyTree, self).__init__(*args, **kwargs)
        #wx.TreeCtrl.__init__(self, *args, **kwargs)

    def OnGetItemText(self, index):
        return self.model.OnGetItemText(index)

    def OnGetChildrenCount(self, index):
        return self.model.OnGetChildrenCount(index)

class TreeApp(wx.App):
    def OnInit(self):
        self.model = create_model()
        self.view = TreeFrame(self.model)
        self.view.Show()
        return True

if __name__ == '__main__':
    app = TreeApp()
    app.MainLoop()

--------------------------------------------------------------------------------------

Has someone an idea of what goes wrong here and can point me in the
right direction?

Thanks in advance

Daniel

Hi,

I just edited my code a bit so that it can run without a tree model. I
am still getting a PyDeadObject exception when the __init__ method of
VirtualTree is called. Can someone help me to understand the bug?

···

#
######################################################################
import wx
from wx.lib.mixins.treemixin import VirtualTree

class TreeFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='wxTree Test Program')

        pa_main = wx.Panel(self)
        self.tree = MyTree(pa_main)
        self.tree.SetMinSize((150, 300))

        szr = wx.BoxSizer(wx.VERTICAL)
        szr.Add(self.tree, 1, wx.ALIGN_CENTER)
        pa_main.SetSizer(szr)
        pa_main.Fit()
        szr.SetSizeHints(self)

class MyTree(VirtualTree, wx.TreeCtrl):
    def __init__(self, parent):
        wx.TreeCtrl.__init__(self, parent, style=wx.TR_HIDE_ROOT|
wx.TR_DEFAULT_STYLE)
        VirtualTree.__init__(self, parent, style=wx.TR_HIDE_ROOT|
wx.TR_DEFAULT_STYLE)

    def OnGetItemText(self, index):
        print 'text'
        return str(index)

    def OnGetChildrenCount(self, index):
        if len(index) < 3:
            return len(index) + 1
        elif len(index) == 3:
            return 0

class TreeApp(wx.App):
    def OnInit(self):
        self.view = TreeFrame()
        self.view.Show()
        return True

if __name__ == '__main__':
    app = TreeApp()
    app.MainLoop()

#
##########################################################################

Thanks in advance

Daniel

With multiple inheritance, when at least one of the bases is using super() to manage the MRO then the derived class should also. In this case without using super in __init__ it ends up partially initializing the tree class twice (I think)...

class MyTree(VirtualTree, wx.TreeCtrl):
     def __init__(self, *args, **kw):
         super(MyTree, self).__init__(*args, **kw)

Note that if you don't need to do any additional code in MyTree's __init__ then you can just leave it out and VirtualTree.__init__ will be called instead.

···

On 7/31/11 1:06 PM, Daniel Platz wrote:

Hi,

I just edited my code a bit so that it can run without a tree model. I
am still getting a PyDeadObject exception when the __init__ method of
VirtualTree is called. Can someone help me to understand the bug?

--
Robin Dunn
Software Craftsman

Thanks for your help. Indeed, the program does not crash anymore.
However, no tree is displayed, instead only a white area appears on
the panel. Is there any obvious reason for this? The
OnGetChildrenCount and OnGetItem methods which I have overwritten in
MyTree a never called. Is there some kind of event I have to fire to
build the tree?

I attached again my code and left in the the __init__ function in
MyTree for now (leaving it out does not have an effect).

···

#
#############################################################################################
import wx
from wx.lib.mixins.treemixin import VirtualTree

class TreeFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='wxTree Test Program')

        pa_main = wx.Panel(self)
        self.tree = MyTree(pa_main, style=wx.TR_DEFAULT_STYLE|
wx.TR_HIDE_ROOT)
        self.tree.SetMinSize((150, 300))

        szr = wx.BoxSizer(wx.VERTICAL)
        szr.Add(self.tree, 1, wx.ALIGN_CENTER)
        pa_main.SetSizer(szr)
        pa_main.Fit()
        szr.SetSizeHints(self)

class MyTree(VirtualTree, wx.TreeCtrl):
    def __init__(self, *args, **kw):
        super(MyTree, self).__init__(*args, **kw)

    def OnGetItemText(self, index):
        print 'OnGetItemText'
        return str(index)

    def OnGetChildrenCount(self, index):
        if len(index) < 3:
            return len(index) + 1
        elif len(index) == 3:
            return 0

class TreeApp(wx.App):
    def OnInit(self):
        self.view = TreeFrame()
        self.view.Show()
        return True

if __name__ == '__main__':
    app = TreeApp()
    app.MainLoop()

#
#########################################################################

Daniel

Daniel,

Thanks for your help. Indeed, the program does not crash anymore.
However, no tree is displayed, instead only a white area appears on
the panel. Is there any obvious reason for this? The
OnGetChildrenCount and OnGetItem methods which I have overwritten in
MyTree a never called. Is there some kind of event I have to fire to
build the tree?

I attached again my code and left in the the __init__ function in
MyTree for now (leaving it out does not have an effect).

I think the thing which was missing is "self.RefreshItems()" call. I got to this by reviewing the wxPython demo, adding in a model class and using the WIT (Widget Inspection Tool - run the application and press ctrl-alt-i or check the wiki entry for it for more information).

See the attached code, note that it throws an exception when one expands items, due to the items I hard coded, they are probably not quit in the correct format or one needs to add a check somewhere to catch the case when there is no child.

Hope this helps
Werner

danielVT.py (2.85 KB)

···

On 08/01/2011 12:43 AM, Daniel Platz wrote:

Werner,

thanks for your help. The tree is shown now and the program works like
a charm. I tried to study the TreeMixin.py file in the demo files but
this was quite overwhelming. Thanks also for the hint to the WIT -
nice tool.

Best regards,

Daniel