Phoenix - wx.PyCommandEvent

Hi,

With Phoenix I see a problem with a custom event that the 'setter' is not called.

The event is define like this:

class ScEventDbItemSet(wx.PyCommandEvent):
     """Custom event to be notified when a dbItem is set on the control"""
     def __init__(self, evtType, id):
         wx.PyCommandEvent.__init__(self, evtType, id)
         self._dbItem = None

     @property
     def dbItem(self):
         return self._dbItem

     @dbItem.setter
     def dbItem(self, dbitem):
         self._dbItem = dbitem

and I am using it like this:

         evt = ScEventDbItemSet(scEVT_SEARCHCTRL_DBITEMSET, self.GetId())
         evt.dbItem = item
         self.GetEventHandler().ProcessEvent(evt)

Anyone knows why this is not working?

Werner

Hi,

With Phoenix I see a problem with a custom event that the 'setter' is not called.

The event is define like this:

class ScEventDbItemSet(wx.PyCommandEvent):
    """Custom event to be notified when a dbItem is set on the control"""
    def __init__(self, evtType, id):
        wx.PyCommandEvent.__init__(self, evtType, id)
        self._dbItem = None

    @property
    def dbItem(self):
        return self._dbItem

    @dbItem.setter
    def dbItem(self, dbitem):
        self._dbItem = dbitem

and I am using it like this:

        evt = ScEventDbItemSet(scEVT_SEARCHCTRL_DBITEMSET, self.GetId())
        evt.dbItem = item
        self.GetEventHandler().ProcessEvent(evt)

Anyone knows why this is not working?

If I add this, as mentioned on wxPython Project Phoenix Migration Guide — wxPython Phoenix 4.2.3a1 documentation
     def __getattr__(self, name):
         d = self._getAttrDict()
         if name in d:
             return d[name]
         return getattr(self, name)

     def __setattr__(self, name, value):
         d = self._getAttrDict()
         if name in d:
             return d[name]
         return setattr(self, name, value)

Then I get a RunTimeError: max recursion exceeded

I could go back to define Get/Set, but it would be nice to be able to use properties.

Werner

···

On 9/18/2015 18:41, Werner wrote:

Werner

Werner wrote:

Hi,

With Phoenix I see a problem with a custom event that the 'setter' is
not called.

The event is define like this:

class ScEventDbItemSet(wx.PyCommandEvent):
"""Custom event to be notified when a dbItem is set on the control"""
def __init__(self, evtType, id):
wx.PyCommandEvent.__init__(self, evtType, id)
self._dbItem = None

@property
def dbItem(self):
return self._dbItem

@dbItem.setter
def dbItem(self, dbitem):
self._dbItem = dbitem

Hmm... I expected that would work correctly. It looks like __getattr__ and friends don't always play nice with properties. See python - Using __getattr__ and meeting expected behaviour for subclasses - Stack Overflow. The wx.PyEvent and wx.PyCommandEvent classes have implementations for __[get|set|del]attr__ and is how they ensure that all attributes are stored in the dictionary that gets shared by the clones that go through the event system. I'll add a TODO to my list to take another look at that implementation and see if there is another way to do it.

and I am using it like this:

evt = ScEventDbItemSet(scEVT_SEARCHCTRL_DBITEMSET, self.GetId())
evt.dbItem = item
self.GetEventHandler().ProcessEvent(evt)

Anyone knows why this is not working?

If I add this, as mentioned on
wxPython Project Phoenix Migration Guide — wxPython Phoenix 4.2.3a1 documentation

Yeah, that example is broken. I'll fix that too when I reinvestigate the current implementation. For clarification, you should only need to follow this example if your class already had __getattr__ etc. implementations in Classic, and the intent is to show how they would need to be updated to work with Phoenix using the extra dictionary.

···

On 9/18/2015 18:41, Werner wrote:

--
Robin Dunn
Software Craftsman

May not apply but reminded me:

http://stackoverflow.com/questions/17020115/how-to-use-setattr-correctly-avoiding-infinite-recursion

Basically super() is needed somewhere when you use both __setattr__ and
__getattr__.