Jump to content
  • Advertisement
Sign in to follow this  
Oysterman

[wxPython] Making a Panel draggable

This topic is 3281 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, Long story short, I'm exploring wxPython, and I want to make it possible for a user to drag panels around in a Frame using the mouse. My spontaneous approach was to do something like this:
import wx

class Draggable(wx.Panel):
    def __init__(self, parent, size):
        wx.Panel.__init__(self, parent, size=size)
        self.SetBackgroundColour(wx.BLACK)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
        self.Bind(wx.EVT_LEFT_UP, self.OnRelease)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
    def OnClick(self, e):
        self.clickDelta = e.GetPositionTuple()
        self.oldPos = self.GetPositionTuple()
        self.SetBackgroundColour(wx.WHITE)
        self.Refresh()
    def OnRelease(self, e):
#        self.SetPosition(self.oldPos)
        self.SetBackgroundColour(wx.BLACK)
        self.Refresh()
    def OnMouseMove(self, e):
        if e.Dragging():
            dx, dy = self.clickDelta
            mx, my = e.GetPositionTuple()
            x,y = self.GetPositionTuple()
            x += mx-dx
            y += my-dy
            self.SetPosition((x,y))
            self.Refresh()

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)

        d = Draggable(self, (50, 50))
        d.SetPosition((50, 50))

class App(wx.App):
    def OnInit(self):
        f = Frame()
        self.SetTopWindow(f)
        f.Show()
        return True

app = App(0)
app.MainLoop()

However, this approach makes it possible for the user to drag the things around faster than the event handling seems to be able to cope with. If you drag fast enough, you can make the mouse leave the panel while dragging it, messing everything up. I figure I could create a specific Panel class that functions as a container for Draggables. I'd register a Draggable with this container, and process the EVT_MOTION events in the container rather than in the individual Draggables. I like the first approach a lot better though, and I've successfully implemented it before in a similar way in Java/Swing. Is there a way I can make the first approach work well in wxPython?

Share this post


Link to post
Share on other sites
Advertisement
This is not python related, but I think this could help, specifically the Vadim post about wxEVT_MOUSE_CAPTURE_CHANGED. I guess in wxPython its wx.EVT_MOUSE_CAPTURE_CHANGED

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!