[wxPython] wxTreeCtrl::SetItemData ?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[wxPython] wxTreeCtrl::SetItemData ?

Paul Robinson-14

I'm new to wxPython and I'm having trouble with Tree controls.

I'm using a slightly modified version of the XML demo to display a tree
of objects that are represented in the XML file I'm parsing.
I would like to associate an object with each of the nodes, which I
beleive I can do with SetItemData (or SetPyData).

The problem is, when use these methods I get a crash in Python.exe:
Python.exe
Exception: access violation (0xc0000005), Address: 0x00dd8fc0

So, firstly, I don't know if, when using SetPyData, the same
restrictions apply about the data object having to inherit from
wxTreeItemData (as with SetItemData). The docs do not make this clear:

"wxPython note: wxPython provides the following shortcut method:
SetPyData(item, obj)  Associate the given Python Object with the
wxTreeItemData for the given item Id."

I've tried both options to no avail.

Secondly is there something more basic wrong with my code (extract
below).

Thanks in advance,
        Paul.

<CODE>

class leafObject(wxTreeItemData):
    def __init__(self, attrs, id):
        self.data = None
        self.__id__ = id
        for idx in range(0, len(attrs), 2):
            self.data[attrs[idx]] = attrs[idx+1]
    def GetId(self):
        return self.__id__

class bcXMLTree(wxTreeCtrl):
        def __init__(self, parent, ID, style=wxTR_HAS_BUTTONS):
            wxTreeCtrl.__init__(self, parent, ID, style=style)
            self.nodeStack = [self.AddRoot("Root")]
            self.inHead = 0

        # Define a handler for start element events
        def StartElement(self, name, attrs ):
            if (name == 'ARTIFACT'):
                    id = self.AppendItem(self.nodeStack[-1],
attrs[attrs.index('name')+1] )
                    self.nodeStack.append( id )
                    #Removing both of these lines means that it all works!
                    #Neither work on their own.
                    #self.SetItemData(id, leafObject(attrs, id))
                    self.SetPyData( id, leafObject(attrs, id) )

        def EndElement(self,  name ):
            if (name == 'ARTIFACT'):
                    self.nodeStack = self.nodeStack[:-1]

        def CharacterData(self, data ):
            pass
        #---------------------------------------------
        def OnEndEdit(self, event):
            #Rename the item (folder)
            pass

        def LoadTree(self, file):
            #file is an open file object (i.e. close it!)
            # Create a parser
            Parser = pyexpat.ParserCreate()

            # Tell the parser what the start element handler is
            Parser.StartElementHandler = self.StartElement
            Parser.EndElementHandler = self.EndElement
            Parser.CharacterDataHandler = self.CharacterData

            # Parse the XML File
            ParserStatus = Parser.Parse(file.read(), 1)
            file.close()
            if self.nodeStack: return self.nodeStack[0]
</CODE>

_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] wxTreeCtrl::SetItemData ?

Robin Dunn
>
> So, firstly, I don't know if, when using SetPyData, the same
> restrictions apply about the data object having to inherit from
> wxTreeItemData (as with SetItemData). The docs do not make this clear:
>
> "wxPython note: wxPython provides the following shortcut method:
> SetPyData(item, obj)  Associate the given Python Object with the
> wxTreeItemData for the given item Id."
>

SetPyData is a convenience.  It actually creates a wxTreeItemData internally
and uses it transparently.  You can store any arbitrary Python object using
it.


> I've tried both options to no avail.
>
> Secondly is there something more basic wrong with my code (extract
> below).
>

I can't duplicate your problem.  I modified the demo a bit to be similar to
what you are doing and I don't have a crash.  On the other hand I did find
something wrong with your code, and it may be related.  In
leafObject.__init__ you assign None to self.data, and then treat self.data
as a dictionary 2 lines later.  I've noticed that the XML extension module
ignores exceptions that happen when it makes calls back to Python code, so
you never see the exception and traceback when something like this happens.
Maybe this indirectly leads to your crash...

If after fixing this and you still get the crash, try to isolate where it
happens.  Use pdb or insert print statements to track down what statement is
causing it.

--
Robin Dunn
Software Craftsman
[hidden email]
http://AllDunn.com/robin/
http://AllDunn.com/wxPython/  Check it out!




_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] wxTreeCtrl::SetItemData ?

Paul Robinson-14

Robin Dunn wrote:
>
> > Secondly is there something more basic wrong with my code (extract
> > below).
> >
> [...] I did find
> something wrong with your code, and it may be related.
> [...] I've noticed that the XML extension module
> ignores exceptions that happen when it makes calls back to Python code [...]
> Maybe this indirectly leads to your crash...

That seems to be the problem. I actually spotted that the next time I
looked at the code!

It seems that any exception in that part of the code causes Python (and
the debugger (in PythonWin build 127)) to crash!
I'll just have to not make any mistakes in future!

Thanks for the help,
        Paul.

_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users