wxEvent.GetEventObject() returns wrong object sometimes

Maciej Kalisiak wrote:
>In my GUI I have a wxPanel with some wxChoice widgets. I bind the
>choice widgets to a certain function on an EVT_MOUSEWHEEL. The function
>makes use of wxEvent.GetEventObject() to find out on which object the
>action was taken. Overall everything works, except when I roll the mouse
>wheel while moving; occasionally, for some reason, GetEventObject()
>returns the (parent? or another one?) wxPanel object, which does not
>have this binding. Is this a known bug? Any workarounds? This is
>merely a nuisance for me, but one I'd like to get rid of nonetheless.

Platform, version and sample please.

Linux, Debian (unstable)
libwxgtk2.4 2.4.1.2
libwxgtk2.4-python 2.4.1.2

A (roughly) minimal misbehaving example is listed below. To reproduce:
move the mouse cursor in a circular motion, passing over the wxChoice
buttons, and over the empty space on the left, *all the while* rolling
the mouse wheel back and forth.

,----[ foo.py ]-

#!/usr/bin/env python
from wxPython.wx import *
from wxPython.xrc import wxXmlResource, XRCCTRL, XRCID

def chc_set_sel_and_ev(chc, sel_idx):
    """Set wxChoice's selection and post a selection event."""
    chc.SetSelection(sel_idx)
    ev = wxCommandEvent(wxEVT_COMMAND_CHOICE_SELECTED, chc.GetId())
    chc.AddPendingEvent(ev)

class App(wxApp):
    def OnInit(self):
        self.xrc = wxXmlResource("foo.xrc")

        self.win_main = self.xrc.LoadFrame(None, "FRAME1")
        self.win_main.Show(TRUE)
        self.SetTopWindow(self.win_main)

        # allow scrolling of choice lists using mouse wheel
        for nm in ['CHC1', 'CHC2', 'CHC3', 'CHC4', 'CHC5', 'CHC6']:
            EVT_MOUSEWHEEL(self._find_gui_ctrl(nm), self.on_choice_scroll)
        return TRUE

    def _find_gui_ctrl(self, name):
        return XRCCTRL(self.win_main, name)

    def on_choice_scroll(self, ev):
        def next_item(chc):
            cur = chc.GetSelection()
            # NOTE: if nothing is selected GetSelection() returns -1
            cur += 1
            if cur < chc.GetCount():
                chc_set_sel_and_ev(chc,cur)

        def prev_item(chc):
            cur = chc.GetSelection()
            if cur > 0:
                chc_set_sel_and_ev(chc,cur-1)
            elif cur == -1: # nothing selected yet
                chc_set_sel_and_ev(chc,0)

        chc = ev.GetEventObject()
        wdelta = ev.GetWheelDelta()
        if not wdelta:
            wdelta = 120
        line_delta = ev.GetWheelRotation() / wdelta
        if line_delta > 0:
            for i in range(line_delta):
                prev_item(chc)
        elif line_delta < 0:
            for i in range(abs(line_delta)):
                next_item(chc)

app = App(0)
app.MainLoop()

`----

Here's the XRC file:

,----[ foo.xrc ]-

<?xml version="1.0" ?>
<resource version="2.3.0.1">
  <object class="wxFrame" name="FRAME1">
    <size>450,350</size>
    <style>wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxRESIZE_BOX</style>
    <title></title>
    <object class="wxNotebook" name="NOTEBOOK">
      <object class="notebookpage">
        <label>Foo</label>
        <object class="wxPanel" name="NB_PAGE_1">
          <object class="wxBoxSizer">
            <orient>wxVERTICAL</orient>
            <object class="sizeritem">
              <object class="wxFlexGridSizer">
                <cols>2</cols>
                <rows>10</rows>
                <object class="spacer">
                  <size>0,15</size>
                </object>
                <object class="spacer">
                  <size>0,15</size>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticText" name="-1">
                    <label></label>
                  </object>
                  <flag>wxRIGHT|wxALIGN_CENTRE_VERTICAL</flag>
                  <border>5</border>
                </object>
                <object class="sizeritem">
                  <object class="wxChoice" name="CHC1">
                    <content/>
                    <size>150,22</size>
                    <style></style>
                  </object>
                  <flag>wxALIGN_CENTRE_VERTICAL</flag>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticLine">
                    <size>200,1</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticLine">
                    <size>200,1</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticText" name="-1">
                    <label></label>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxChoice" name="CHC2">
                    <content/>
                    <size>150,22</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticText" name="-1">
                    <label></label>
                  </object>
                </object>
                <vgap>10</vgap>
                <object class="sizeritem">
                  <object class="wxChoice" name="CHC3">
                    <content/>
                    <size>150,22</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticText" name="-1">
                    <label></label>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxChoice" name="CHC4">
                    <content/>
                    <size>200,22</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticText" name="-1">
                    <label></label>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxChoice" name="CHC5">
                    <content/>
                    <size>200,22</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticLine">
                    <size>200,1</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticLine">
                    <size>200,1</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticText" name="-1">
                    <label></label>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxChoice" name="CHC6">
                    <content/>
                    <size>200,22</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticLine" name="-1">
                    <size>200,1</size>
                  </object>
                </object>
                <object class="sizeritem">
                  <object class="wxStaticLine" name="-1">
                    <size>200,1</size>
                  </object>
                </object>
              </object>
            </object>
          </object>
        </object>
      </object>
      <usenotebooksizer>1</usenotebooksizer>
      <size>450,350</size>
    </object>
  </object>
</resource>

`----

···

On Sat, Sep 20, 2003 at 01:32:31PM -0400, Robin Dunn wrote:

--
Maciej Kalisiak mac "at" dgp.toronto.edu www.dgp.toronto.edu/~mac

In my case, it's real simple -- I have a wxFrame with a wxMenuBar and an
assortment of menus. In one special case I needed to know which menu item
generated the event. I was trapping EVT_MENU. When I got it,
event.GetEventObject() returned the frame instead of the menu item, as I
expected it.

Like I said, at the time I just figured I was unaware of a special
circumstance for menu and tool bars, but maybe this is the same thing?

Sure sounds like it.

Particulars: wxPython 2.4.1.2, Python 2.3, Win2K install.

I forgot to mention in my specs post: I too am using Python 2.3.

···

On Sun, Sep 21, 2003 at 05:21:26PM -0700, Jeff Grimmett wrote:

--
Maciej Kalisiak mac "at" dgp.toronto.edu www.dgp.toronto.edu/~mac

Maciej Kalisiak wrote:

···

On Sat, Sep 20, 2003 at 01:32:31PM -0400, Robin Dunn wrote:

Maciej Kalisiak wrote:

In my GUI I have a wxPanel with some wxChoice widgets. I bind the
choice widgets to a certain function on an EVT_MOUSEWHEEL. The function
makes use of wxEvent.GetEventObject() to find out on which object the
action was taken. Overall everything works, except when I roll the mouse
wheel while moving; occasionally, for some reason, GetEventObject()
returns the (parent? or another one?) wxPanel object, which does not
have this binding. Is this a known bug? Any workarounds? This is
merely a nuisance for me, but one I'd like to get rid of nonetheless.

Platform, version and sample please.

Linux, Debian (unstable)
libwxgtk2.4 2.4.1.2
libwxgtk2.4-python 2.4.1.2

A (roughly) minimal misbehaving example is listed below. To reproduce:
move the mouse cursor in a circular motion, passing over the wxChoice
buttons, and over the empty space on the left, *all the while* rolling
the mouse wheel back and forth.

This is probably due to the fact that on GTK many controls are not true X-Windows, but window-less widgets that are drawn on the parent window. What mouse events that are supported are synthsized to look like they are coming from the control. Perhaps what you are seeing is a rare (I could only make it happen once) boundary condition that is doing the wrong thing.

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

Maciej Kalisiak wrote:

···

On Mon, Sep 22, 2003 at 04:43:36PM -0400, Robin Dunn wrote:

This is probably due to the fact that on GTK many controls are not true X-Windows, but window-less widgets that are drawn on the parent window. What mouse events that are supported are synthsized to look like they are coming from the control. Perhaps what you are seeing is a rare (I could only make it happen once) boundary condition that is doing the wrong thing.

So what do you recommend? I guess I should file a bug against
wxWindows, or if there is a specific bug list for the GTK implementation
of them... The bug doesn't bother me too much, but since I spent the
time getting the minimal example going, etc, it would be nice if some
good came of it (i.e., the report makes it to the group that can do
something about it).

Go ahead and file a bug report for wxGTK and maybe somebody will know what to do about it.

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