Capturing mouse position in top level windows with children

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

Capturing mouse position in top level windows with children

rasbx8
I have a top level wx.Frame that contains a single wx.Panel as a child. I would like to capture the position of the mouse cursor in the top level frame, display the mouse coords in a status bar, and then pass this positional data to the child panel for further processing. However, if I bind the EVT_MOTION event to the top level frame, nothing happens (I assume because the panel takes up all the available window area and it doesn't inherit the event handler from the parent frame). If I move this binding to be within the child panel, I am able to capture data from within this panel, but not for the whole frame.

Is there a way to capture the mouse position in the top level parent frame and propagate it downstream to child window event handlers as necessary?


My code:

import wx

class myPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        # fancy painting code to go here

class myWindow(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "hello", size=(500,500))
        self.CreateStatusBar()
        self.pan = wx.Panel(self)
        self.Bind(wx.EVT_MOTION, self.onMouseMove)  

    def onMouseMove(self, event):  #never called because mouse is always on the panel?
        position = event.GetPosition()
        self.SetStatusText("Mouse X: %d  Y: %d" %(position.x, position.y))

if __name__ == '__main__':
    app = wx.App(redirect=False)
    frame = myWindow(None)
    frame.Show(True)
    app.MainLoop()

--
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/groups/opt_out.
Reply | Threaded
Open this post in threaded view
|

Re: Capturing mouse position in top level windows with children

Robin Dunn
[hidden email] wrote:

> I have a top level wx.Frame that contains a single wx.Panel as a child.
> I would like to capture the position of the mouse cursor in the top
> level frame, display the mouse coords in a status bar, and then pass
> this positional data to the child panel for further processing. However,
> if I bind the EVT_MOTION event to the top level frame, nothing happens
> (I assume because the panel takes up all the available window area and
> it doesn't inherit the event handler from the parent frame). If I move
> this binding to be within the child panel, I am able to capture data
> from within this panel, but not for the whole frame.
>
> Is there a way to capture the mouse position in the top level parent
> frame and propagate it downstream to child window event handlers as
> necessary?

Not simply.  Events in wx tend to work the other way around, traveling
up the containment hierarchy in search of a handler.  But since mouse
events are not command events they don't even do that much, they are
only sent to the widget in which they happen.  For mouse events that
means that they are only sent to the widgets on the top of the z-order.

It takes a little more brute force but you can still do something like
what you want.  Basically you would need to Bind() the EVT_MOTION event
to every widget contained within the frame (a recursive traversal using
GetChildren would be a good way to do it) and bind them to a method in
the frame.  If that method calls event.Skip() then the event system will
still look for a handler in the widget class and call it if there is
one.  Keep in mind that the coordinates in the mouse events will be
relative to the widget not the frame, but you can use something like
this to translate them to be relative to the frame if you need it:

self.ScreenToClient(event.GetEventObject().ClientToScreen(event.GetPos()))


--
Robin Dunn
Software Craftsman
http://wxPython.org

--
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/groups/opt_out.
Reply | Threaded
Open this post in threaded view
|

Re: Capturing mouse position in top level windows with children

Rufus V. Smith
On 2/25/2014 9:06 PM, Robin Dunn wrote:


self.ScreenToClient(event.GetEventObject().ClientToScreen(event.GetPos()))


Love it!

--
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/groups/opt_out.