You can draw on a wx.ScreenDC, although it will be wiped out as soon as
the windows you are drawing over refresh themselves. Another option
would be to use a shaped frame such that only the areas covered by the
lines of the rectangle are not transparent. See the ShapedWindow sample
in the demo.
--
Robin Dunn
Software Craftsman
http://wxPython.org
You just need to create a DC for the desktop window. Then, you can draw
on that just like you would in any of your own windows. It might be
easier to do this by using the GDI calls in PyWin32 directly, but if you
really want to do it in wx, you can. You just need to create a fake
window and make it think it is the desktop.
import wx
import win32gui
class Desktop(wx.Frame):
def __init__(self):
super(Desktop,self).__init__(None,-1,'')
self.AssociateHandle(win32gui.GetDesktopWindow())
dc = wx.WindowDC(self)
dc.DrawRectangle( 100, 100, 800, 800 )
app = wx.App(0)
mf = Desktop()
app.MainLoop()
This is not a very good example, because (1) it draws a filled
rectangle, not an empty rectangle, (2) there's no way to kill it except
by using Ctrl-C, but it shows you the general idea.
Users won't like this, of course, because you'll be drawing on top of
other windows that won't know they've been disturbed.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.
Now I'm embarrassed, after seeing Robin's post. I didn't know about
wx.ScreenDC.
If you set the DC's brush to wx.TRANSPARENT_BRUSH then you can use
DrawRectangle instead.
So, how do I do the following: Draw 4
> lines for one area, erase them, draw another 4 lines for the next
> area, erase them, ... , and so on?
Try using dc.SetLogicalFunction(wx.INVERT) or wx.XOR. Then you should
be able to draw the rectangle once to make it visible, and then draw it
again to restore what was there before. Keep in mind however that if
anything on the affected area of the screen changes due to another
program redrawing itself, or the user interacting with it, or etc. then
you'll probably end up with a bit of garbage left on the screen.
When you set the ROP to wx.INVERT, the pen color is ignored. It just
negates every pixel.
You need to make a choice here. If you draw the rectangle in solid red,
then it isn't reversible. You will have lost the pixels underneath.
The only way to restore them would be to grab a copy before you draw,
and that's expensive.
As an alternative, you can try wx.XOR instead of wx.INVERT. That turns
black into red, although it will turn white into cyan. See if you like
that better.
If you really, really need solid red, then you have no choice but to
grab a copy of the untouched screen, and copy the pixels back when it's
time to erase the rectangle.
You can use wx.FRAME_SHAPED and make all but the desired rectangle
borders be fully transparent. The demo (see ShapedWindow.py) shows
using wx.FRAME_SHAPED with an image, but it can also be done with a
wx.Region constructed in other ways if needed.
wx.RegionFromBitmap uses the bitmap's mask to know where to set the
region, so you need to give the bitmap you are using a mask for it to
work. I've done it in the attached version of your sample code by
initializing the bitmap to black, and then after drawing the rectangle I
tell the bitmap to set its mask to the area covered by the black pixels.
Try using the client size of the frame instead of the total size. Then
you'll be making only the areas that you can draw on visible instead of
including the border of the frame.