When you have an event object, you can call GetPosition() to get a Point. You can also call GetX() or GetY().
The position that you receive is relative to the top-left corner of the window that the event was triggered by; It is expressed in ClientCoordinates.
You have to consider the source of the event, to interpret the position correctly.
The origin for the Frame is usually a different place than the origin for the Panel:
- The Frame places the origin at the top-left corner of the title bar.
- A Panel immediately within the Frame places the origin beneath the title bar, and to the right of the border.
If you pick the wrong one, you probably beed to generate your events from a different object, or correct for the effect.
Getting Position by Panel
Here's example code, that shows the position read by an event raised through the panel.
(0, 0) is at the corner of the panel, not the whole frame window. That is, (0, 0) is the corner beneath the title bar.
(The code is based on the VerySimpleDrawing example.)
1 import wx
2
3 app = wx.PySimpleApp(0)
4
5 frame = wx.Frame(None, -1, "Draw on Frame")
6 panel = wx.Panel(frame, -1)
7
8 x = 50
9 y = 50
10
11 text = wx.StaticText(panel, -1, "X", wx.Point(x, y))
12 text.SetBackgroundColour("white") # Make the corners visible.
13
14 def on_paint(event):
15 dc = wx.PaintDC(event.GetEventObject())
16 dc.Clear()
17 dc.SetPen(wx.Pen("BLACK", 4))
18 dc.DrawLine(x-5, y-5, x+5, y+5) # \
19 dc.DrawLine(x-5, y+5, x+5, y-5) # /
20
21 def on_motion(event):
22 global x
23 global y
24 x, y = event.GetX(), event.GetY()
25 text.SetLabel("(%s, %s)" % (x, y))
26 panel.Refresh()
27
28 wx.EVT_PAINT(panel, on_paint)
29 wx.EVT_MOTION(panel, on_motion)
30
31 frame.Show(True)
32 app.MainLoop()
This will show you the position as you move around the screen.
You'll note: If you put your cursor in the top-left of the panel, it will read (0,0). Your cursor will be in the corner just beneath the title bar, on the left.
Getting Position by Frame
1 import wx
2
3 app = wx.PySimpleApp(0)
4
5 frame = wx.Frame(None, -1, "Position by Frame")
6 panel = wx.Panel(frame, -1)
7 text = wx.StaticText(panel, -1, "X", wx.Point(50, 50))
8 text.SetBackgroundColour("white")
9
10 def on_event(event):
11 text.SetLabel("(%s, %s)" % (event.GetX(), event.GetY()))
12
13 wx.EVT_CHAR(frame, on_event)
14
15 frame.Show(True)
16 app.MainLoop()
For some reason, I can't hook up wx.EVT_MOTION and get the event to be called. (Not sure why...)
So, hook up wx.EVT_CHAR instead, and type a letter. You'll see that the coordinate is reported from the top-left corner of the title bar of the frame.
Then change the code to read wx.EVT_CHAR(panel, on_event) instead. You'll see that the coordinate is reported from the top-left corner of the panel, below (and a notch to the right, accounting for the border,) of the title bar.
Questions
- Let's suppose you wanted to raise the event from the Frame, not the Panel, and then correct. How would you do it?
See also
wxPython Mouse Position -- a code snippet, offsite