0

The Problem:

It seems like one event is disabling another event. Before calling event B, event A works just fine. After event B fires, event A no longer works. Both events are custom ones that people made for their wxPython libraries (FloatCanvas and ColourSelect). I'd like to trace the generated events to make sure that, after event B, event A is still being fired (but perhaps not triggering the handler code?)

The Details:

I have a wxPython app where I create a wx.Panel object with two child items - a plot and a legend. This top level panel handles the majority of the events.

  • The plot is a wx.Panel object with a single wx.lib.FloatCanvas.FloatCanvas canvas in it.

  • The legend is a wx.Panel with multiple wx.StaticText and wx.lib.colourselect.ColourSelect objects in it (I'm plotting discrete data points).

On the plot, I bind FloatCanvas.EVT_MOUSEWHEEL to my zoom in/out function. On the legend, I bind the wx.lib.colourselect.EVT_COLOURSELECT event to my update_colors function which then sends the event to the parent panel via wx.PostEvent(event).

The parent panel then receives EVT_COLOURSELECT from the child and executes code that changes the colors of my plots.

Source Code:

I haven't had time to write a small sample that demo's the problem, but you can see the problem by running the source code: https://github.com/dougthor42/wafer_map

Run the wm_app.py file and then go through the following test steps.

Testing Steps:

  1. Scroll/zoom in and out - works just fine
  2. Change a plot color (fires EVT_COLOURSELECT). If you're testing with the source code you do this by clicking on a legend color box and choosing a new color.
  3. Attempt to zoom in and out again. Doesn't work!
  4. Verify that all other events (key down, click-and-drag, mouse move) all work.

Things I've Tried:

Obviously these didn't work or else I wouldn't be here :-P

  • Unbinding the mousewheel event and rebinding it when the top level panel receives the event from the child.

  • Completely disabling the handlers for EVT_COLOURSELECT in both the parent panel and the legend.

    • I thought that perhaps there was something going on in my handlers. Turns out, just triggering EVT_COLOURSELECT causes the EVT_MOUSEWHEEL to stop working.
  • Changing FloatCanvas.EVT_MOUSEWHEEL to some other event, for example FloatCanvas.EVT_RIGHT_DOWN

    • This does actually work! I loose the 'speed' info from the mouse wheel, but right-clicking before and after step 2 both work.
    • Seems to indicate that it's an issue with the mouse scroll event specifically.

Has anyone had a problem where events interfere with each other?

dthor
  • 1,749
  • 1
  • 18
  • 45
  • Can you show your event handlers? Or even better a self contained sample showing the problem. – Werner Dec 12 '14 at 17:11
  • I don't have time to write a sample that shows the issue right now, but you can view the source code for the project at https://github.com/dougthor42/wafer_map. Run wm_app.py and then run through the Testing Steps listed above. I've edited them to be a bit more descriptive. – dthor Dec 12 '14 at 22:08

1 Answers1

0

It turns out that there wasn't any interference with events - at least not the events that I mentioned.

After a ton of fiddling and attempts at making a bare-bones version that still demonstrated the problem (which I was unsuccessful at doing), I figured out the root cause. Sadly, I did not figure out a workaround.

The Problem:

My plot wx.Panel was binding wx.MOUSE_LEFT_DOWN. It seems that this was preventing the parent wx.Frame window from giving focus to the Panel that held the plot and the legend.

The Solution:

I removed the bind to wx.EVT_LEFT_DOWN and that seems to fix the underlying issue. However, this is still not the ideal case because it causes two other problems:

  1. I can no longer use my left mouse button on the plot. Not a big deal, I guess, because I can always bind right-mouse.
  2. A user must first left-click on the plot area to give it focus before the mouse scroll or any keyboard shortcuts will work. This doesn't necessarily stem from not binding wx.EVT_LEFT_DOWN, but rather (I believe), from something that Windows does. See Focus-follows-mouse in wxPython? for a bit more info.

Failed Workaround:

I tried a workaround: adding code that sends the wx.EVT_LEFT_DOWN event to the parent but either that still didn't work or I was doing it wrong. Here's the left-click event handler that I tried:

def left_click(self, event):
    print("left click!")
    parent = wx.GetTopLevelParent()
    wx.PostEvent(self.parent, event)

So anyway, this question is kinda solved. Hopefully what I've got here helps someone else out.

Community
  • 1
  • 1
dthor
  • 1,749
  • 1
  • 18
  • 45