【问题标题】:In wxPython, how to get the mouse position related to image in ScrolledPanel?在 wxPython 中,如何在 ScrolledPanel 中获取与图像相关的鼠标位置?
【发布时间】:2016-07-26 06:24:02
【问题描述】:

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

滚动到顶部:

滚动到底部:

【问题讨论】:

  • 这已经如您所愿。由于您在图像本身上侦听EVT_MOTION,因此您获得的位置是相对于图像的。
  • @SelçukCihan 不,不是!该位置将是面板中的位置。

标签: position wxpython wxwidgets


【解决方案1】:

您需要使用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()

【讨论】:

  • 谢谢!这就是我想要的。
  • 很好的答案!这正是我正在寻找的
【解决方案2】:

我知道这是一个老话题,但对于所有登陆这里的人(比如我),还有另一种方式:

def OnMouseMove(self, event):
    dc = wx.ClientDC(self)
    self.DoPrepareDC(dc)
    pos = event.GetLogicalPosition(dc)

【讨论】:

  • 短小精悍!谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
相关资源
最近更新 更多