0

wxpython プログラムにパン機能を実装しようとしています。このプログラムは、ビットマップ イメージを保持する ScrolledWindow を含むフレームで構成されています。

空白のパネルをクリックしてパンすると、期待どおりの動作が得られます。画像をクリックしてパンすると、約 10px の「ジャンプ」が発生します。

ドラッグ中に mouse_pos メンバーが更新されない場合、画像のパンはスムーズですが、空白パネルのパンは正しくありません。

システム情報: wxpython 2.8.12.1、Python 2.7.3 64 ビット、および Windows 7 64 ビット。

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()
4

1 に答える 1