我正在尝试在 wxpython 程序中实现平移功能。该程序由一个包含 ScrolledWindow 的框架组成,该 ScrolledWindow 包含一个位图图像。
在空白面板上单击和平移会产生预期的行为。在图像上单击和平移会产生大约 10 像素的“跳跃”。
如果在拖动过程中 mouse_pos 成员没有更新,则在图像上平移是平滑的,但在空白面板上平移是错误的。
系统信息:wxpython 2.8.12.1、Python 2.7.3 64bit 和 Windows 7 64bit。
import wx
import inspect
import threading
class MyFrame(wx.Frame):
def __init__(self, parent, mytitle):
wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle, size=(350, 350))
self.scrollwin = wx.ScrolledWindow(self, wx.ID_ANY)
width = 1000
height = 1000
self.scrollwin.SetScrollbars(20, 20, width/20, height/20)
self.scrollwin.SetScrollRate(1, 1)
self.scrollwin.Bind(wx.EVT_MOTION, self.on_mouse_drag)
self.scrollwin.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
image_file = "test.jpg"
image = wx.Bitmap(image_file)
sb = wx.StaticBitmap(self.scrollwin, wx.ID_ANY, image)
sb.Bind(wx.EVT_MOTION, self.event_defer)
sb.Bind(wx.EVT_LEFT_DOWN, self.event_defer)
self._mouse_pos = (0, 0)
self.sem = threading.Semaphore(0)
@property
def mouse_pos(self):
return self._mouse_pos
@mouse_pos.setter
def mouse_pos(self, value):
print "mouse_pos:"
print "Calling from: ", inspect.stack()[1][3]
print value
self._mouse_pos = value
def on_mouse_drag(self, event):
if event.Dragging() and event.LeftIsDown():
self.sem.release()
print self.sem._Semaphore__value
(mouse_x, mouse_y) = self.mouse_pos
#new_pos = self.scrollwin.CalcUnscrolledPosition(event.GetPosition()).Get()
#new_pos = self.scrollwin.CalcScrolledPosition(event.GetPosition()).Get()
new_pos = event.GetPositionTuple()
(new_x, new_y) = new_pos
scrollpos = self.scrollwin.GetViewStart()
(scroll_x, scroll_y) = scrollpos
(delta_x, delta_y) = ((new_x - mouse_x), (new_y - mouse_y))
(scroll_x, scroll_y) = ((scroll_x - delta_x), (scroll_y - delta_y))
print "Scroll:"
print (scroll_x, scroll_y)
self.scrollwin.Scroll(scroll_x, scroll_y)
#self.mouse_pos = self.scrollwin.CalcUnscrolledPosition(event.GetPosition()).Get()
#self.mouse_pos = self.scrollwin.CalcScrolledPosition(event.GetPosition()).Get()
self.mouse_pos = new_pos # Disabling this gives smooth panning on the image
self.sem.acquire(False)
def on_left_down(self, event):
#self.mouse_pos = self.scrollwin.CalcUnscrolledPosition(event.GetPosition()).Get()
#self.mouse_pos = self.scrollwin.CalcScrolledPosition(event.GetPosition()).Get()
self.mouse_pos = event.GetPositionTuple()
def event_defer(self, event):
event.ResumePropagation(1)
event.Skip()
app = wx.App()
MyFrame(None, "Test wx.ScrolledWindow()").Show()
app.MainLoop()