Understanding PushEventHandler and event propagation

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

Understanding PushEventHandler and event propagation

jan.leys
Dear,

While working on a larger program, I got somewhat lost in the way events are propagated up the chain.

My use case is the following: in a wx.Frame that represents a document, there is a wx.MenuItem (say, wx.ID_ABOUT), that should not be handled by the document Frame, but rather by its parent Frame (the app main window, if you want).  But, for the main Frame, I wanted to use a separate controller object (a wx.EvtHandler subclass) to contain some generic logic, like showing the AboutBox, and add that with wx.Window.PushEventHander.  The solution I put together crashes if the controller object tries to handle the menu event, but it works is if the event is handled by the main window.
Suspecting there is something wrong with my understanding of PushEventHandler, I looked into the example on the wiki, and modified it a bit, see attached.  And then I got completely lost.

When you run this with line 31 in place, I expect to see first a dialog "in EvtHandler" and then one "in Panel".  But the first one is showing twice, and I don't see why.
Then, I get an error on closing the app:

> python3 test_pusheventhandler.py 
test_pusheventhandler.py:12: DeprecationWarning: NewId() is deprecated
  ID_FOR_THE_BTN = wx.NewId()
Mouse down at (51, 16) on Button
Button clicked in EvtHandler
Button clicked in EvtHandler
Button clicked in Panel
Traceback (most recent call last):
  File "test_pusheventhandler.py", line 70, in <module>
    app.MainLoop()
  File "/usr/local/lib/python3.7/site-packages/wx/core.py", line 2134, in MainLoop
    rv = wx.PyApp.MainLoop(self)
wx._core.wxAssertionError: C++ assertion "GetEventHandler() == this" failed at /Users/robind/projects/buildbots/macosx-vm6/dist-osx-py37/Phoenix/ext/wxWidgets/src/common/wincmn.cpp(478) in ~wxWindowBase(): any pushed event handlers must have been removed

Any help with either would be appreciated.

Best regards,
Jan

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

test_pusheventhandler.py (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Understanding PushEventHandler and event propagation

Robin Dunn
On Tuesday, July 10, 2018 at 11:26:40 AM UTC-7, [hidden email] wrote:
Dear,

While working on a larger program, I got somewhat lost in the way events are propagated up the chain.

My use case is the following: in a wx.Frame that represents a document, there is a wx.MenuItem (say, wx.ID_ABOUT), that should not be handled by the document Frame, but rather by its parent Frame (the app main window, if you want).  But, for the main Frame, I wanted to use a separate controller object (a wx.EvtHandler subclass) to contain some generic logic, like showing the AboutBox, and add that with wx.Window.PushEventHander.  The solution I put together crashes if the controller object tries to handle the menu event, but it works is if the event is handled by the main window.
Suspecting there is something wrong with my understanding of PushEventHandler, I looked into the example on the wiki, and modified it a bit, see attached.  And then I got completely lost.

When you run this with line 31 in place, I expect to see first a dialog "in EvtHandler" and then one "in Panel".  But the first one is showing twice, and I don't see why.


Because you pushed the EvtHandler on both the button and the panel. So when the button click happens in the button it sends the event to the EvtHandler and then propagates to the parent. When the panel gets it then it first sends the event to its pushed EvtHandler and then the panel's own EVT_BUTTON event binding get's the event and the panel's OnButton is called.

 
Then, I get an error on closing the app:


It is now required to pop pushed EvtHandlers before the window they are pushed onto is destroyed. IIRC, this change happened sometime in the 2.9.x series.

 --
Robin

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Understanding PushEventHandler and event propagation

jan.leys


On Wednesday, July 11, 2018 at 8:37:51 PM UTC+2, Robin Dunn wrote:
On Tuesday, July 10, 2018 at 11:26:40 AM UTC-7, <a href="javascript:" target="_blank" gdf-obfuscated-mailto="-tqgFFztBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">jan....@... wrote:
Dear,

While working on a larger program, I got somewhat lost in the way events are propagated up the chain.

My use case is the following: in a wx.Frame that represents a document, there is a wx.MenuItem (say, wx.ID_ABOUT), that should not be handled by the document Frame, but rather by its parent Frame (the app main window, if you want).  But, for the main Frame, I wanted to use a separate controller object (a wx.EvtHandler subclass) to contain some generic logic, like showing the AboutBox, and add that with wx.Window.PushEventHander.  The solution I put together crashes if the controller object tries to handle the menu event, but it works is if the event is handled by the main window.
Suspecting there is something wrong with my understanding of PushEventHandler, I looked into the example on the wiki, and modified it a bit, see attached.  And then I got completely lost.

When you run this with line 31 in place, I expect to see first a dialog "in EvtHandler" and then one "in Panel".  But the first one is showing twice, and I don't see why.


Because you pushed the EvtHandler on both the button and the panel. So when the button click happens in the button it sends the event to the EvtHandler and then propagates to the parent. When the panel gets it then it first sends the event to its pushed EvtHandler and then the panel's own EVT_BUTTON event binding get's the event and the panel's OnButton is called.

Thanks, that clarified the whole example.
 


 
Then, I get an error on closing the app:


It is now required to pop pushed EvtHandlers before the window they are pushed onto is destroyed. IIRC, this change happened sometime in the 2.9.x series.

It doesn't seem to be documented clearly in either the wxwidgets or wxpython references.  I may try to add a sentence at an appropriate place, once I have found out where and how.

Meanwhile, I wanted to update the example code to add it to the wxpython wiki, but it seems what I thought to be the logical approach for calling PopEventHandler is not that logical, or I failed to implement it correctly.  Anyway, if the script attached is run, it still gives the assert failure.

Jan
 

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

test_pusheventhandler.py (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Understanding PushEventHandler and event propagation

Robin Dunn
On Thursday, July 12, 2018 at 5:38:14 AM UTC-7, [hidden email] wrote:


On Wednesday, July 11, 2018 at 8:37:51 PM UTC+2, Robin Dunn wrote:

It is now required to pop pushed EvtHandlers before the window they are pushed onto is destroyed. IIRC, this change happened sometime in the 2.9.x series.

It doesn't seem to be documented clearly in either the wxwidgets or wxpython references.  I may try to add a sentence at an appropriate place, once I have found out where and how.

Meanwhile, I wanted to update the example code to add it to the wxpython wiki, but it seems what I thought to be the logical approach for calling PopEventHandler is not that logical, or I failed to implement it correctly.  Anyway, if the script attached is run, it still gives the assert failure.

Jan
 

Non top-level windows do not typically get the EVT_CLOSE event. I've always wished that the did, but it's not to be. It may work to use EVT_WINDOW_DESTROY but that might be sent too late. Probably the safest would be to catch EVT_CLOSE in your frame, and then from there call a method in the panel to pop the handlers.

--
Robin
 

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Understanding PushEventHandler and event propagation

jan.leys

On 12 Jul 2018, at 20:35, Robin Dunn <[hidden email]> wrote:

On Thursday, July 12, 2018 at 5:38:14 AM UTC-7, [hidden email] wrote:


On Wednesday, July 11, 2018 at 8:37:51 PM UTC+2, Robin Dunn wrote:

It is now required to pop pushed EvtHandlers before the window they are pushed onto is destroyed. IIRC, this change happened sometime in the 2.9.x series.

It doesn't seem to be documented clearly in either the wxwidgets or wxpython references.  I may try to add a sentence at an appropriate place, once I have found out where and how.

Meanwhile, I wanted to update the example code to add it to the wxpython wiki, but it seems what I thought to be the logical approach for calling PopEventHandler is not that logical, or I failed to implement it correctly.  Anyway, if the script attached is run, it still gives the assert failure.

Jan
 

Non top-level windows do not typically get the EVT_CLOSE event. I've always wished that the did, but it's not to be. It may work to use EVT_WINDOW_DESTROY but that might be sent too late. Probably the safest would be to catch EVT_CLOSE in your frame, and then from there call a method in the panel to pop the handlers.


Both appear to be working.  If there are no further comments, I’ll update the wiki page.

Jan

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.