在wxPython中,如何获取ScrolledPanel中与图片相关的鼠标位置?
In wxPython, how to get the mouse position related to image in ScrolledPanel?
我正在使用 wxPython 实现一个简单的地图编辑器。 ScrolledPanel 中托管了一个 StaticBitmap 图像控件。图像尺寸大于面板尺寸,因此出现滚动条。在鼠标移动事件处理程序中,函数 event.GetPosition() 能够获取与 面板 左上角相关的鼠标位置.但是,我想获取与 image 左上角相关的鼠标位置。我怎样才能做到这一点?谢谢
例如第一个截图(滚动到顶部),如果鼠标在面板的左上角,图像相关的位置应该是(0, 0)。在第二个屏幕截图中(滚动到底部),如果鼠标在面板的左上角,则与图像相关的位置是 (0, image_height-panel_height).
#!/usr/bin/python
import wx
import wx.lib.scrolledpanel
class SimpleFrame(wx.Frame):
def __init__(self, parent):
super(SimpleFrame, self).__init__(parent)
# add a panel so it looks the correct on all platforms
self.frame_panel = wx.Panel(self)
frame_panel = self.frame_panel
# image panel
self.image_panel = wx.lib.scrolledpanel.ScrolledPanel(frame_panel, style=wx.SIMPLE_BORDER)
image_panel = self.image_panel
image_panel.SetAutoLayout(True)
image_panel.SetupScrolling()
# image panel - image control
self.image_ctrl = wx.StaticBitmap(image_panel)
self.image_ctrl.Bind(wx.EVT_MOTION, self.ImageCtrl_OnMouseMove)
img = wx.Image("image.jpg", wx.BITMAP_TYPE_ANY)
self.image_ctrl.SetBitmap(wx.BitmapFromImage(img))
image_panel.Layout()
image_sizer = wx.BoxSizer(wx.VERTICAL)
image_sizer.Add(self.image_ctrl)
image_panel.SetSizer(image_sizer)
# frame sizer
frame_sizer = wx.BoxSizer(wx.HORIZONTAL)
frame_sizer.Add(image_panel, proportion=1, flag=wx.EXPAND | wx.ALL)
frame_panel.SetSizer(frame_sizer)
return
def ImageCtrl_OnMouseMove(self, event):
# position in control
ctrl_pos = event.GetPosition()
print("ctrl_pos: " + str(ctrl_pos.x) + ", " + str(ctrl_pos.y))
# position in image
#image_pos = ??? convert control position to image position
#print("image_pos: " + str(image_pos.x) + ", " + str(image_pos.y))
app = wx.PySimpleApp()
frame = SimpleFrame(None)
frame.Show()
app.MainLoop()
滚动到顶部:
滚动到底部:
您需要使用GetScreenPosition()
获取window当前位置的坐标,使用ScreenToClient()
获取图像的客户端坐标。把它们加在一起,你就会得到你在图像上的相对位置。
这样做的好处在于,用户可以重新定位 window 或更改其大小,从而获得一致的位置。
这是您修改后的代码:
#!/usr/bin/python
import wx
import wx.lib.scrolledpanel
class SimpleFrame(wx.Frame):
def __init__(self, parent):
super(SimpleFrame, self).__init__(parent)
# add a panel so it looks the correct on all platforms
self.frame_panel = wx.Panel(self)
frame_panel = self.frame_panel
# image panel
self.image_panel = wx.lib.scrolledpanel.ScrolledPanel(frame_panel, style=wx.SIMPLE_BORDER)
image_panel = self.image_panel
image_panel.SetAutoLayout(True)
image_panel.SetupScrolling()
# image panel - image control
self.image_ctrl = wx.StaticBitmap(image_panel)
self.image_ctrl.Bind(wx.EVT_MOTION, self.ImageCtrl_OnMouseMove)
self.img = wx.Image("image.jpg", wx.BITMAP_TYPE_ANY)
self.image_ctrl.SetBitmap(wx.BitmapFromImage(self.img))
image_panel.Layout()
image_sizer = wx.BoxSizer(wx.VERTICAL)
image_sizer.Add(self.image_ctrl)
image_panel.SetSizer(image_sizer)
# frame sizer
frame_sizer = wx.BoxSizer(wx.HORIZONTAL)
frame_sizer.Add(image_panel, proportion=1, flag=wx.EXPAND | wx.ALL)
frame_panel.SetSizer(frame_sizer)
return
def ImageCtrl_OnMouseMove(self, event):
# position in control
ctrl_pos = event.GetPosition()
print("ctrl_pos: " + str(ctrl_pos.x) + ", " + str(ctrl_pos.y))
pos = self.image_ctrl.ScreenToClient(ctrl_pos)
print "pos relative to screen top left = ", pos
screen_pos = self.frame_panel.GetScreenPosition()
relative_pos_x = pos[0] + screen_pos[0]
relative_pos_y = pos[1] + screen_pos[1]
print "pos relative to image top left = ", relative_pos_x, relative_pos_y
app = wx.PySimpleApp()
frame = SimpleFrame(None)
frame.Show()
app.MainLoop()
我知道这是一个旧话题,但对于所有登陆这里的人(像我一样),还有另一种方式:
def OnMouseMove(self, event):
dc = wx.ClientDC(self)
self.DoPrepareDC(dc)
pos = event.GetLogicalPosition(dc)
我正在使用 wxPython 实现一个简单的地图编辑器。 ScrolledPanel 中托管了一个 StaticBitmap 图像控件。图像尺寸大于面板尺寸,因此出现滚动条。在鼠标移动事件处理程序中,函数 event.GetPosition() 能够获取与 面板 左上角相关的鼠标位置.但是,我想获取与 image 左上角相关的鼠标位置。我怎样才能做到这一点?谢谢
例如第一个截图(滚动到顶部),如果鼠标在面板的左上角,图像相关的位置应该是(0, 0)。在第二个屏幕截图中(滚动到底部),如果鼠标在面板的左上角,则与图像相关的位置是 (0, image_height-panel_height).
#!/usr/bin/python
import wx
import wx.lib.scrolledpanel
class SimpleFrame(wx.Frame):
def __init__(self, parent):
super(SimpleFrame, self).__init__(parent)
# add a panel so it looks the correct on all platforms
self.frame_panel = wx.Panel(self)
frame_panel = self.frame_panel
# image panel
self.image_panel = wx.lib.scrolledpanel.ScrolledPanel(frame_panel, style=wx.SIMPLE_BORDER)
image_panel = self.image_panel
image_panel.SetAutoLayout(True)
image_panel.SetupScrolling()
# image panel - image control
self.image_ctrl = wx.StaticBitmap(image_panel)
self.image_ctrl.Bind(wx.EVT_MOTION, self.ImageCtrl_OnMouseMove)
img = wx.Image("image.jpg", wx.BITMAP_TYPE_ANY)
self.image_ctrl.SetBitmap(wx.BitmapFromImage(img))
image_panel.Layout()
image_sizer = wx.BoxSizer(wx.VERTICAL)
image_sizer.Add(self.image_ctrl)
image_panel.SetSizer(image_sizer)
# frame sizer
frame_sizer = wx.BoxSizer(wx.HORIZONTAL)
frame_sizer.Add(image_panel, proportion=1, flag=wx.EXPAND | wx.ALL)
frame_panel.SetSizer(frame_sizer)
return
def ImageCtrl_OnMouseMove(self, event):
# position in control
ctrl_pos = event.GetPosition()
print("ctrl_pos: " + str(ctrl_pos.x) + ", " + str(ctrl_pos.y))
# position in image
#image_pos = ??? convert control position to image position
#print("image_pos: " + str(image_pos.x) + ", " + str(image_pos.y))
app = wx.PySimpleApp()
frame = SimpleFrame(None)
frame.Show()
app.MainLoop()
滚动到顶部:
滚动到底部:
您需要使用GetScreenPosition()
获取window当前位置的坐标,使用ScreenToClient()
获取图像的客户端坐标。把它们加在一起,你就会得到你在图像上的相对位置。
这样做的好处在于,用户可以重新定位 window 或更改其大小,从而获得一致的位置。
这是您修改后的代码:
#!/usr/bin/python
import wx
import wx.lib.scrolledpanel
class SimpleFrame(wx.Frame):
def __init__(self, parent):
super(SimpleFrame, self).__init__(parent)
# add a panel so it looks the correct on all platforms
self.frame_panel = wx.Panel(self)
frame_panel = self.frame_panel
# image panel
self.image_panel = wx.lib.scrolledpanel.ScrolledPanel(frame_panel, style=wx.SIMPLE_BORDER)
image_panel = self.image_panel
image_panel.SetAutoLayout(True)
image_panel.SetupScrolling()
# image panel - image control
self.image_ctrl = wx.StaticBitmap(image_panel)
self.image_ctrl.Bind(wx.EVT_MOTION, self.ImageCtrl_OnMouseMove)
self.img = wx.Image("image.jpg", wx.BITMAP_TYPE_ANY)
self.image_ctrl.SetBitmap(wx.BitmapFromImage(self.img))
image_panel.Layout()
image_sizer = wx.BoxSizer(wx.VERTICAL)
image_sizer.Add(self.image_ctrl)
image_panel.SetSizer(image_sizer)
# frame sizer
frame_sizer = wx.BoxSizer(wx.HORIZONTAL)
frame_sizer.Add(image_panel, proportion=1, flag=wx.EXPAND | wx.ALL)
frame_panel.SetSizer(frame_sizer)
return
def ImageCtrl_OnMouseMove(self, event):
# position in control
ctrl_pos = event.GetPosition()
print("ctrl_pos: " + str(ctrl_pos.x) + ", " + str(ctrl_pos.y))
pos = self.image_ctrl.ScreenToClient(ctrl_pos)
print "pos relative to screen top left = ", pos
screen_pos = self.frame_panel.GetScreenPosition()
relative_pos_x = pos[0] + screen_pos[0]
relative_pos_y = pos[1] + screen_pos[1]
print "pos relative to image top left = ", relative_pos_x, relative_pos_y
app = wx.PySimpleApp()
frame = SimpleFrame(None)
frame.Show()
app.MainLoop()
我知道这是一个旧话题,但对于所有登陆这里的人(像我一样),还有另一种方式:
def OnMouseMove(self, event):
dc = wx.ClientDC(self)
self.DoPrepareDC(dc)
pos = event.GetLogicalPosition(dc)