在wxPython中,如何在ScrolledPanel中获取与图像相关的鼠标位置?

时间:2016-04-06 03:50:02

标签: position wxpython wxwidgets

我正在使用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()

滚动到顶部: Scrolled to top

滚动到底部: Scrolled to bottom

2 个答案:

答案 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)