weirdness in TreeCtrl

Howdy,

I've discovered something I really don't understand. I have a tree control
with editable labels. After editing a label, I need to decorate the text by prepending
a text label on the front, so the following example isn't as contrived as it might seem.

I have two questions. the first is that after editing a label, event.GetItem()
doesn't return the same TreeItemId as the original item, even though they do
test equal logically. I don't really understand this, but I assume it's something related
to references.

The second question is that after editing
the label, I can't SetItemText and have the label change. If I pretend to edit
(open for editing and then immediately hit return) I can change the label. Is there
a refresh of some sort I need to call?

I really don't understand what's going on. I'm including the same sample code inline and
as an attachment. Run the app and then edit the label. I would expect no matter
what you type, the text of the node should always be 'reset2' when you hit return. Also
try opening the label for editing, but not changing anything. After editing, notice that "root" and
"item" aren't equal, but test equal, and the side effect of programmatically changing the text
doesn't take unless there is no edit.

BTW I'm on MSW,Python 2.5, wxPython 2.7.2.

TIA,
Danny

import wx

class MyFrame(wx.Frame):
  def __init__(self, parent, id, title):
    wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(450, 350))
    self.tree = wx.TreeCtrl(self, 1, wx.DefaultPosition, (-1,-1), wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS)
    self.root = self.tree.AddRoot('Root Node')
    print "in __init__\n\troot = ", self.root
    self.Centre()
    self.tree.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndEdit)
    
  def OnEndEdit(self, event):
    item = event.GetItem()
    print ('-'*50) + "\nin OnEndEdit\n\titem = ",item
    print "testing equality: ", item==self.root
    self.tree.SetItemText(item,'reset1')
    self.tree.SetItemText(self.root,'reset2') #should always be the value after editing
    print "after resetting"
    
class MyApp(wx.App):
  def OnInit(self):
    frame = MyFrame(None, -1, 'treectrl.py')
    frame.Show(True)
    return True

app = MyApp(0)
app.MainLoop()

minimal tree2.py (887 Bytes)

Danny Shevitz wrote:

Howdy,

I've discovered something I really don't understand. I have a tree control
with editable labels. After editing a label, I need to decorate the text by prepending
a text label on the front, so the following example isn't as contrived as it might seem.

I have two questions. the first is that after editing a label, event.GetItem()
doesn't return the same TreeItemId as the original item, even though they do
test equal logically. I don't really understand this, but I assume it's something related
to references.

The TreeItemId's are more or less just an opaque handle to the tree item, and are generated on the fly as needed.

The second question is that after editing
the label, I can't SetItemText and have the label change. If I pretend to edit
(open for editing and then immediately hit return) I can change the label. Is there
a refresh of some sort I need to call?

The text in the item isn't actually changed until after the wx.EVT_TREE_END_LABEL_EDIT handler returns. This is because it is giving you a chance to prevent the change by calling event.Veto. If you want to further change the text then you can use wx.CallAfter to call a method later to make the change.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

The text in the item isn't actually changed until after the wx.EVT_TREE_END_LABEL_EDIT handler returns. This is because it is giving you a chance to prevent the change by calling event.Veto. If you want to further change the text then you can use wx.CallAfter to call a method later to make the change.

thanks, definitely something totally outside my wx experience.

D