Earlier I asked a question about mouse interaction with a GUI. I have found a pretty comprehensive script that is supposed to work <mod edit: link removed, source inserted>:
Title: wxPython Graphics - Drawing rubberbands over a canvas
Submitter: Anand Pillai (other recipes)
Last Updated: 2003/12/30
Version no: 1.1
Category: Image
Description:
This recipe talks about how to implement rubberbanding code for canvas
objects in a wxPython application. Canvas classes in wxPython include
wxPanel, wxStaticBitmap, wxGlCanvas etc.
Expand|Select|Wrap|Line Numbers
- # This class describes a generic method of drawing rubberbands
- # on a wxPython canvas object (wxStaticBitmap, wxPanel etc) when
- # the user presses the left mouse button and drags it over a rectangular
- # area. It has methods to return the selected area by the user as
- # a rectangular 4 tuple / Clear the selected area.
- # Beginning of code
- class wxPyRubberBander:
- """ A class to manage mouse events/ rubberbanding of a wxPython
- canvas object """
- def __init__(self, canvas):
- # canvas object
- self._canvas = canvas
- # mouse selection start point
- self.m_stpoint=wxPoint(0,0)
- # mouse selection end point
- self.m_endpoint=wxPoint(0,0)
- # mouse selection cache point
- self.m_savepoint=wxPoint(0,0)
- # flags for left click/ selection
- self._leftclicked=false
- self._selected=false
- # Register event handlers for mouse
- self.RegisterEventHandlers()
- def RegisterEventHandlers(self):
- """ Register event handlers for this object """
- EVT_LEFT_DOWN(self._canvas, self.OnMouseEvent)
- EVT_LEFT_UP(self._canvas, self.OnMouseEvent)
- EVT_MOTION(self._canvas, self.OnMouseEvent)
- def OnMouseEvent(self, event):
- """ This function manages mouse events """
- if event:
- # set mouse cursor
- self._canvas.SetCursor(wxStockCursor(wxCURSOR_ARROW))
- # get device context of canvas
- dc= wxClientDC(self._canvas)
- # Set logical function to XOR for rubberbanding
- dc.SetLogicalFunction(wxXOR)
- # Set dc brush and pen
- # Here I set brush and pen to white and grey respectively
- # You can set it to your own choices
- # The brush setting is not really needed since we
- # dont do any filling of the dc. It is set just for
- # the sake of completion.
- wbrush = wxBrush(wxColour(255,255,255), wxTRANSPARENT)
- wpen = wxPen(wxColour(200, 200, 200), 1, wxSOLID)
- dc.SetBrush(wbrush)
- dc.SetPen(wpen)
- if event.LeftDown():
- # Left mouse button down, change cursor to
- # something else to denote event capture
- self.m_stpoint = event.GetPosition()
- cur = wxStockCursor(wxCURSOR_CROSS)
- self._canvas.SetCursor(cur)
- # invalidate current canvas
- self._canvas.Refresh()
- # cache current position
- self.m_savepoint = self.m_stpoint
- self._selected = false
- self._leftclicked = true
- elif event.Dragging():
- # User is dragging the mouse, check if
- # left button is down
- if self._leftclicked:
- # reset dc bounding box
- dc.ResetBoundingBox()
- dc.BeginDrawing()
- w = (self.m_savepoint.x - self.m_stpoint.x)
- h = (self.m_savepoint.y - self.m_stpoint.y)
- # To erase previous rectangle
- dc.DrawRectangle(self.m_stpoint.x, self.m_stpoint.y, w, h)
- # Draw new rectangle
- self.m_endpoint = event.GetPosition()
- w = (self.m_endpoint.x - self.m_stpoint.x)
- h = (self.m_endpoint.y - self.m_stpoint.y)
- # Set clipping region to rectangle corners
- dc.SetClippingRegion(self.m_stpoint.x, self.m_stpoint.y, w,h)
- dc.DrawRectangle(self.m_stpoint.x, self.m_stpoint.y, w, h)
- dc.EndDrawing()
- self.m_savepoint = self.m_endpoint # cache current endpoint
- elif event.LeftUp():
- # User released left button, change cursor back
- self._canvas.SetCursor(wxSTOCK_CURSOR(wxCURSOR_ARROW))
- self._selected = true #selection is done
- self._leftclicked = false # end of clicking
- def GetCurrentSelection(self):
- """ Return the current selected rectangle """
- # if there is no selection, selection defaults to
- # current viewport
- left = wxPoint(0,0)
- right = wxPoint(0,0)
- # user dragged mouse to right
- if self.m_endpoint.y > self.m_stpoint.y:
- right = self.m_endpoint
- left = self.m_stpoint
- # user dragged mouse to left
- elif self.m_endpoint.y < self.m_stpoint.y:
- right = self.m_stpoint
- left = self.m_endpoint
- return (left.x, left.y, right.x, right.y)
- def ClearCurrentSelection(self):
- """ Clear the current selected rectangle """
- box = self.GetCurrentSelection()
- dc=wxClientDC(self._canvas)
- w = box[2] - box[0]
- h = box[3] - box[1]
- dc.SetClippingRegion(box[0], box[1], w, h)
- dc.SetLogicalFunction(wxXOR)
- # The brush is not really needed since we
- # dont do any filling of the dc. It is set for
- # sake of completion.
- wbrush = wxBrush(wxColour(255,255,255), wxTRANSPARENT)
- wpen = wxPen(wxColour(200, 200, 200), 1, wxSOLID)
- dc.SetBrush(wbrush)
- dc.SetPen(wpen)
- dc.DrawRectangle(box[0], box[1], w,h)
- self._selected = false
- # reset selection to canvas size
- self.ResetSelection()
- def ResetSelection(self):
- """ Resets the mouse selection to entire canvas """
- self.m_stpoint = wxPoint(0,0)
- sz=self._canvas.GetSize()
- w,h=sz.GetWidth(), sz.GetHeight()
- self.m_endpoint = wxPoint(w,h)
The main objective would be to set the image that is loaded as the canvas of the rubberbander and output the result.
Says we start with some pseudocode:
root=Tk()
im=Image.open("filename")
rubberbandscript(........)
print output
root.mainloop()
Thanks alot,
JP