EVT_UPDATE_UI handler question

I relatively recently discovered this and I start to use it quit a bit now.

Whenever I put some logging into such a handler I see that it is called a lot, so am a bit concerned on what overhead I am creating.

Googled to try and find some tips on what to do and what not to do in such handlers, besides the doc I haven't really found anything.

http://xoomer.virgilio.it/infinity77/Phoenix/UpdateUIEvent.html

Currently I use it to set the state of buttons and to handle a summary page in a dialog.

The buttons I do along these lines:

     def onUpdateUI(self, evt):
         event_id = evt.GetId()
         if self.dbItem:
             if event_id == self.create.GetId():
                 evt.Enable(False)
             elif event_id == self.save.GetId():
                 evt.Enable(True)
...etc.
         else:
             if event_id == self.create.GetId():
                 evt.Enable(True)
             elif event_id == self.translate.GetId():
                 evt.Enable(False)
             elif event_id == self.save.GetId():
...etc.

Is this the correct way to do it? Can it be further optimized?

My summary page I do like this:
     def setSummaryInfo(self, event):
         event_id = event.GetId()
         event_obj = event.GetEventObject()
         c = self._controller
         if event_id == c.eTotalFirstimp.GetId():
             self.tFirstimp = c.eFirstimp.GetValue()
             event_obj.SetValue(self.tFirstimp) # < ----- is this better then below?
         elif event_id == c.eTotalSight.GetId():
             self.tSight = c.eSight1.GetValue() + c.eSight2.GetValue() \
                      + c.eSight3.GetValue() + c.eSight4.GetValue()
             c.eTotalSight.SetValue(self.tSight) # < ------ or is this fine too?
... etc

Should I use constants instead of using GetId()?

Any other tips and/or links to documentation, tutorials etc.

Werner

Werner wrote:

I relatively recently discovered this and I start to use it quit a bit now.

Whenever I put some logging into such a handler I see that it is called
a lot, so am a bit concerned on what overhead I am creating.

Googled to try and find some tips on what to do and what not to do in
such handlers, besides the doc I haven't really found anything.

http://xoomer.virgilio.it/infinity77/Phoenix/UpdateUIEvent.html

Currently I use it to set the state of buttons and to handle a summary
page in a dialog.

The buttons I do along these lines:

     def onUpdateUI(self, evt):
         event_id = evt.GetId()
         if self.dbItem:
             if event_id == self.create.GetId():
                 evt.Enable(False)
             elif event_id == self.save.GetId():
                 evt.Enable(True)
...etc.
         else:
             if event_id == self.create.GetId():
                 evt.Enable(True)
             elif event_id == self.translate.GetId():
                 evt.Enable(False)
             elif event_id == self.save.GetId():
...etc.

Is this the correct way to do it? Can it be further optimized?

One improvement is to do it like this:
    def onUpdateUI(self, evt):
        event_id = evt.GetId()
        if event_id == self.create.GetId():
            evt.Enable( not self.dbItem )
        elif event_id == self.save.GetId():
            evt.Enable( self.dbItem )
        elif event_id == self.translate.GetId():
            evt.Enable( self.dbItem )

Any time I find myself explicitly writing False or True, I step back to
think about whether there is a better way.

I have had extensive internal debates about the usefulness of the
"update UI" concept. There is a certain amount of appeal to having all
of this centralized, but in many applications it makes just as much
sense to set these control states at the point were self.dbItem changes
instead of deferring it. I haven't come to a conclusion yet...

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Werner wrote:

I relatively recently discovered this and I start to use it quit a bit now.

Whenever I put some logging into such a handler I see that it is called
a lot, so am a bit concerned on what overhead I am creating.

Googled to try and find some tips on what to do and what not to do in
such handlers, besides the doc I haven't really found anything.

http://xoomer.virgilio.it/infinity77/Phoenix/UpdateUIEvent.html

Currently I use it to set the state of buttons and to handle a summary
page in a dialog.

The buttons I do along these lines:

      def onUpdateUI(self, evt):
          event_id = evt.GetId()
          if self.dbItem:
              if event_id == self.create.GetId():
                  evt.Enable(False)
              elif event_id == self.save.GetId():
                  evt.Enable(True)
...etc.
          else:
              if event_id == self.create.GetId():
                  evt.Enable(True)
              elif event_id == self.translate.GetId():
                  evt.Enable(False)
              elif event_id == self.save.GetId():
...etc.

Is this the correct way to do it? Can it be further optimized?

One improvement is to do it like this:
     def onUpdateUI(self, evt):
         event_id = evt.GetId()
         if event_id == self.create.GetId():
             evt.Enable( not self.dbItem )
         elif event_id == self.save.GetId():
             evt.Enable( self.dbItem )
         elif event_id == self.translate.GetId():
             evt.Enable( self.dbItem )

Any time I find myself explicitly writing False or True, I step back to
think about whether there is a better way.

I like that.

I have had extensive internal debates about the usefulness of the
"update UI" concept. There is a certain amount of appeal to having all
of this centralized, but in many applications it makes just as much
sense to set these control states at the point were self.dbItem changes
instead of deferring it. I haven't come to a conclusion yet...

I kind of like this better then having it where dbItem or whatever changes, which is what I did in the past.

The concern/nagging question I have is it impacting performance or is the idle event processing so optimized that one just doesn't worry about it (assuming the handler is correctly coded).

Werner

···

On 12/04/2012 19:52, Tim Roberts wrote:

I relatively recently discovered this and I start to use it quit a bit now.

Whenever I put some logging into such a handler I see that it is called
a lot, so am a bit concerned on what overhead I am creating.

If needed there are some static methods that let you control the sending of the events, etc. that you can use to fine tune when and where they are sent. See wx.UpdateUIEvent.SetMode and wx.UpdateUIEvent.SetUpdateInterval.

Googled to try and find some tips on what to do and what not to do in
such handlers, besides the doc I haven't really found anything.

http://xoomer.virgilio.it/infinity77/Phoenix/UpdateUIEvent.html

Currently I use it to set the state of buttons and to handle a summary
page in a dialog.

The buttons I do along these lines:

def onUpdateUI(self, evt):
event_id = evt.GetId()
if self.dbItem:
if event_id == self.create.GetId():
evt.Enable(False)
elif event_id == self.save.GetId():
evt.Enable(True)
...etc.
else:
if event_id == self.create.GetId():
evt.Enable(True)
elif event_id == self.translate.GetId():
evt.Enable(False)
elif event_id == self.save.GetId():
...etc.

Is this the correct way to do it? Can it be further optimized?

Yes. You can avoid all the if/else statements and just have a separate update ui handler for each widget or menu item. I often have handlers that are just a single line, something like this:

     def OnSomethingUpdateUI(self, evt):
         evt.Enable(self.someVariable == someValue)

Then when something in the program changes (and presumably causes a change to self.somVariable as well) then the item is automatically enabled or disabled. If you have multiple widgets or items that depend on self.somVariable then you can have them all bind to the same handler of course. The point I'm trying to make here is that these events work best if you don't think about them as being widget-centric like most other events, but rather state-centric. In other words, that they react to changes in the program state, and that reaction is visualized by whatever widgets are bound to the handler.

My summary page I do like this:
def setSummaryInfo(self, event):
event_id = event.GetId()
event_obj = event.GetEventObject()
c = self._controller
if event_id == c.eTotalFirstimp.GetId():
self.tFirstimp = c.eFirstimp.GetValue()
event_obj.SetValue(self.tFirstimp) # < ----- is this better then below?
elif event_id == c.eTotalSight.GetId():
self.tSight = c.eSight1.GetValue() + c.eSight2.GetValue() \
+ c.eSight3.GetValue() + c.eSight4.GetValue()
c.eTotalSight.SetValue(self.tSight) # < ------ or is this fine too?
... etc

Using update ui events for setting values doesn't make as much sense to me, and I've never used them that way.

···

On 4/12/12 10:37 AM, Werner wrote:

--
Robin Dunn
Software Craftsman

I relatively recently discovered this and I start to use it quit a bit now.

Whenever I put some logging into such a handler I see that it is called
a lot, so am a bit concerned on what overhead I am creating.

If needed there are some static methods that let you control the sending of the events, etc. that you can use to fine tune when and where they are sent. See wx.UpdateUIEvent.SetMode and wx.UpdateUIEvent.SetUpdateInterval.

I use the later to update only every 500 milliseconds, will look into SetMode.

...

My summary page I do like this:
def setSummaryInfo(self, event):
event_id = event.GetId()
event_obj = event.GetEventObject()
c = self._controller
if event_id == c.eTotalFirstimp.GetId():
self.tFirstimp = c.eFirstimp.GetValue()
event_obj.SetValue(self.tFirstimp) # < ----- is this better then below?
elif event_id == c.eTotalSight.GetId():
self.tSight = c.eSight1.GetValue() + c.eSight2.GetValue() \
+ c.eSight3.GetValue() + c.eSight4.GetValue()
c.eTotalSight.SetValue(self.tSight) # < ------ or is this fine too?
... etc

Using update ui events for setting values doesn't make as much sense to me, and I've never used them that way.

The controls I update are basically "view only totals".

Before these controls where on a notebook, so I used page change to recalculate and update the values. I am moving this to AUI, so I can't do it that way any more.

Considered using pubsub but then I tried it with update ui event and it works very nicely.

Any other way I should consider doing the summary page update?

Werner

···

On 12/04/2012 20:15, Robin Dunn wrote:

On 4/12/12 10:37 AM, Werner wrote:

If it's working well with update ui events then I'd say that sticking with that approach is fine. Some optimizations to consider would be to have one handler per widget like I mentioned for the other types of cases to eliminate the extra conditionals, and also don't do a SetValue unless the value has actually changed.

···

On 4/13/12 12:58 AM, Werner wrote:

On 12/04/2012 20:15, Robin Dunn wrote:

On 4/12/12 10:37 AM, Werner wrote:

My summary page I do like this:
def setSummaryInfo(self, event):
event_id = event.GetId()
event_obj = event.GetEventObject()
c = self._controller
if event_id == c.eTotalFirstimp.GetId():
self.tFirstimp = c.eFirstimp.GetValue()
event_obj.SetValue(self.tFirstimp) # < ----- is this better then below?
elif event_id == c.eTotalSight.GetId():
self.tSight = c.eSight1.GetValue() + c.eSight2.GetValue() \
+ c.eSight3.GetValue() + c.eSight4.GetValue()
c.eTotalSight.SetValue(self.tSight) # < ------ or is this fine too?
... etc

Using update ui events for setting values doesn't make as much sense
to me, and I've never used them that way.

The controls I update are basically "view only totals".

Before these controls where on a notebook, so I used page change to
recalculate and update the values. I am moving this to AUI, so I can't
do it that way any more.

Considered using pubsub but then I tried it with update ui event and it
works very nicely.

Any other way I should consider doing the summary page update?

--
Robin Dunn
Software Craftsman

Robin,

...

Any other way I should consider doing the summary page update?

If it's working well with update ui events then I'd say that sticking with that approach is fine. Some optimizations to consider would be to have one handler per widget like I mentioned for the other types of cases to eliminate the extra conditionals,

already done that.

and also don't do a SetValue unless the value has actually changed.

Will do this too, thanks for the tips.

Werner

···

On 13/04/2012 19:55, Robin Dunn wrote: