我正在使用wxPython实现一个简单的地图编辑器。 StaticBitmap图像控件托管在ScrolledPanel中。图像大小大于面板大小,因此会出现滚动条。在鼠标移动事件处理程序中,函数 event.GetPosition()能够获取与面板左上角相关的鼠标位置。但是,我希望鼠标位置与图像的左上角相关。我怎么能实现这一目标?感谢。
例如,在第一个屏幕截图(滚动到顶部)中,如果鼠标位于面板的左上角,则与图像相关的位置应为(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()
答案 0 :(得分:2)
您需要使用GetScreenPosition()
来获取窗口当前所在的坐标,并使用ScreenToClient()
来获取图像的客户端坐标。将它们添加到一起,您将获得图像上的相对位置
这样做的好处在于用户可以重新定位窗口或改变其大小,并获得一致的位置。
以下是您修改的代码:
#!/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()
答案 1 :(得分:0)
我知道这是一个老话题,但是对于所有落在这里的人(例如我),还有另一种方法:
def OnMouseMove(self, event):
dc = wx.ClientDC(self)
self.DoPrepareDC(dc)
pos = event.GetLogicalPosition(dc)