I use the code below, only tested it on Windows, but I don't think it contains anything platform
specifics.
(The code could be 1*1 pixel wrong, didn't have time to test that )
cheers,
Stef
# ***********************************************************************
# ***********************************************************************
class _Screen_Capture ( wx.Dialog ) :
def __init__(self, Filename, parent = None ) :
self.Filename = Filename
self.c1 = None
self.c2 = None
wx.Dialog.__init__( self, parent, -1, '', size=wx.DisplaySize(),
style = wx.SYSTEM_MENU | wx.FRAME_NO_TASKBAR | wx.NO_BORDER )
self.panel = wx.Panel (self, size=self.GetSize () )
self.SetTransparent ( 50 )
self.panel.Bind ( wx.EVT_LEFT_DOWN, self.OnMouseDown )
self.panel.Bind ( wx.EVT_MOTION , self.OnMouseMove )
self.panel.Bind ( wx.EVT_LEFT_UP , self.OnMouseUp )
self.panel.Bind ( wx.EVT_PAINT , self.OnPaint )
self.SetCursor ( wx.StockCursor ( wx.CURSOR_CROSS ) )
self.Show ()
def OnMouseDown ( self, event ) :
self.c1 = event.GetPosition()
def OnMouseMove ( self, event ) :
if event.Dragging() and event.LeftIsDown():
self.c2 = event.GetPosition()
self.Refresh()
def OnMouseUp ( self, event ) :
## Don't know for sure that +(1,1) is correct ??
self.c1 = self.ClientToScreen ( self.c1 ) + ( 1, 1 )
self.c2 = self.ClientToScreen ( self.c2 ) + ( 1, 1 )
x0 = self.c1.x
x1 = self.c2.x
y0 = self.c1.y
y1 = self.c2.y
if x0 == x1 or y0 == y1 :
self.c1 = None
self.c2 = None
return
if x0 > x1 :
x = x0
x0 = x1
x1 = x
if y0 > y1 :
y = y0
y0 = y1
y1 = y
from PIL import ImageGrab
bbox = ( x0, y0, x1, y1 )
# For bounded bbox, yields, x0, y0 is included, x1, y1 is excluded !!
ImageGrab.grab ( bbox ).save ( self.Filename )
self.Close()
def OnPaint ( self, event ) :
if ( self.c1 is None ) or ( self.c2 is None ) :
return
dc = wx.PaintDC ( self.panel )
dc.SetPen ( wx.Pen ( 'red', 1 ) )
dc.SetBrush ( wx.Brush ( wx.Color ( 0, 0, 0 ), wx.TRANSPARENT ))
dc.DrawRectangle ( self.c1.x, self.c1.y,
self.c2.x - self.c1.x, self.c2.y - self.c1.y )
# ***********************************************************************
# ***********************************************************************
# ***********************************************************************
@_Wrap_No_GUI
def Screen_Capture ( Filename, parent = None ) :
dlg = _Screen_Capture ( Filename, parent )
dlg.ShowModal()
dlg.Destroy()
# ***********************************************************************
···
On 21-03-2011 17:29, Bryan Oakley wrote:
I would like a way to take a screenshot of the desktop from within my
wxPython application, and I need this to work on all major platforms.
I've seen a solution from a thread back in 2006 but wonder if now
there is a module or widget or something to do this. What I _really_
want is the ability for the user to draw a rectangle anywhere on the
display and grab that, or click on any window, though I would settle
for the whole desktop.
Does such a thing already exist or am I going to have to roll my own
using a ScreenDC?
Thanks