How can I drag a frame without a title bar

One obvious result of the previous example is that the frame is stuckā€”in the absence of a title bar, there's no standard method of dragging the window. To resolve this problem, we need to add event handlers to move the window when dragging occurs. Listing 8.11 displays the same shaped window as before, with the addition of some events for handling left mouse clicks and mouse moves. This technique is applicable to any other frame, or even to a window inside a frame that you want to move (such as an element in a draw program).

Listing 8.11 Events to allow a user to drag a frame from the body of the frame import wx import images class ShapedFrame(wx.Frame):

wx.Frame.__init__(self, None, -1, "Shaped Window", style = wx.FRAME_SHAPED | wx.SIMPLE_BORDER ) self.hasShape = False = wx.Point(0,0) self.bmp = images.getVippiBitmap()

self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight())) dc = wx.ClientDC(self) dc.DrawBitmap(self.bmp, 0,0, True) self.SetWindowShape()

self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) self.Bind(wx.EVT_MOTION, self.OnMouseMove) self.Bind(wx.EVT_RIGHT_UP, self.OnExit) self.Bind(wx.EVT_PAINT, self.OnPaint)

self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)

def SetWindowShape(self, evt=None): r = wx.RegionFromBitmap(self.bmp) self.hasShape = self.SetShape(r)

def OnDoubleClick(self, evt): if self.hasShape:

self.SetShape(wx.Region()) self.hasShape = False else:


A New y' events def OnPaint(self, evt): dc = wx.PaintDC(self) dc.DrawBitmap(self.bmp, 0,0, True)

def OnExit(self, evt): self.Close()

Mouse down self.CaptureMouse()

pos = self.ClientToScreen(evt.GetPosition()) origin = self.GetPosition() = wx.Point(pos.x - origin.x, pos.y - origin.y)

def OnMouseMove(self, evt): ..

Mouse move if evt.Dragging() and evt.LeftIsDown():

pos = self.ClientToScreen(evt.GetPosition()) newPos = (pos.x -, pos.y -


def OnLeftUp(self, evt): if self.HasCapture(): self.ReleaseMouse()

app = wx.PySimpleApp()



Mouse up

O We're adding handlers for three events to make this work. Left mouse down, left mouse up, and mouse movement.

C A drag event starts when the left mouse is pressed. This event handler does two things. First, it captures the mouse, which prevents mouse events from being sent to other widgets until the mouse is released. Second, it calculates an offset between the position of the event and the upper left-hand corner of the window, which will be used to calculate the new position of the window as the mouse moves.

d This handler, called when the mouse moves, first checks to see if the event is a drag with the left button down. If so, it uses the new position of the mouse and the previously calculated offset to determine the new position of the window, and moves the window.

O When the left mouse button is released, ReleaseMouse() is called, which again allows mouse events to be sent to other widgets.

This drag technique can be refined to suit other needs. For example, if the mouse click should only start a drag if it is within is a defined region, you can do a test on the initial location of the mouse down event and only enable dragging if the click is in the right place.

+2 0

Post a comment