Hi there,
Could anybody tell me how to display an empty rectangle on the
screen (not within an window) with the specified position and size?
Thanks in advance.
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.
···
On 3/23/11 1:15 AM, Yuan-Liang Tang wrote:
Hi there,
Could anybody tell me how to display an empty rectangle on the
screen (not within an window) with the specified position and size?
--
Robin Dunn
Software Craftsman
Yuan-Liang Tang wrote:
Hi there,
Could anybody tell me how to display an empty rectangle on the
screen (not within an window) with the specified position and size?
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, timr@probo.com
Providenza & Boekelheide, Inc.
Tim Roberts wrote:
Yuan-Liang Tang wrote:
Hi there,
Could anybody tell me how to display an empty rectangle on the
screen (not within an window) with the specified position and size?You just need to create a DC for the desktop window. ...
class Desktop(wx.Frame):
def __init__(self):
super(Desktop,self).__init__(None,-1,'')
self.AssociateHandle(win32gui.GetDesktopWindow())
dc = wx.WindowDC(self)
Now I'm embarrassed, after seeing Robin's post. I didn't know about
wx.ScreenDC.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
See:
[Drawing on the Windows desktop using Python and wxPython](http://www.michaelfogleman.com/2009/12/drawing-on-the-windows-desktop-using-python-and-wxpython/)
“Windows” refers to “Microsoft Windows”, not the wxPython kind.
Thanks a lot, Robin. I used ScreenDC as you suggested and it worked.
One more question. What I intend to do is to repeatedly draw empty
rectangles on the screen. To be specific: the screen is divided into 4
areas (upper-left, upper-right, bottom-left, bottom-right), and I need
to draw, in turn, the 4 rectangles of the areas (actually, I draw 4
lines to represent a rectangle). 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?
Thanks in advance.
Yuan-Liang Tang
···
-----------------------
On 3月24日, 上午12時55分, Robin Dunn <ro...@alldunn.com> wrote:
On 3/23/11 1:15 AM, Yuan-Liang Tang wrote:
> Hi there,
> Could anybody tell me how to display an emptyrectangleon the
> screen (not within an window) with the specified position and size?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 therectangleare not transparent. See the ShapedWindow sample
in the demo.--
Robin Dunn
Software Craftsmanhttp://wxPython.org
Thanks a lot, Robin. I used ScreenDC as you suggested and it worked.
One more question. What I intend to do is to repeatedly draw empty
rectangles on the screen. To be specific: the screen is divided into 4
areas (upper-left, upper-right, bottom-left, bottom-right), and I need
to draw, in turn, the 4 rectangles of the areas (actually, I draw 4
lines to represent a rectangle).
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.
···
On 4/19/11 11:12 PM, Yuan-Liang Tang wrote:
--
Robin Dunn
Software Craftsman
It worked! Thanks a million.
One small problem though: for the following code, I was not able to
draw red rectangles; the borders are black. How should I fix it?
···
------------------
import wx
import time
app = wx.PySimpleApp()
dc = wx.ScreenDC()
screenWidth, screenHeight = wx.DisplaySize()
boxWidth = int(screenWidth/3+0.5)
boxHeight = int(screenHeight/3+0.5)
dc.StartDrawingOnTop(None)
dc.SetPen(wx.Pen('red', 2))
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetLogicalFunction(wx.INVERT)
for y in range(3):
y1 = boxHeight*y
for x in range(3):
x1 = boxWidth*x
dc.DrawRectangle(x1, y1, boxWidth, boxHeight)
time.sleep(1)
dc.DrawRectangle(x1, y1, boxWidth, boxHeight)
--------------
Yuan-Liang Tang wrote:
It worked! Thanks a million.
One small problem though: for the following code, I was not able to
draw red rectangles; the borders are black. How should I fix it?
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.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
I got the idea, thanks. Another alternative would be to create a
transparent frame using the "SetTransparent(0)" attribute. However,
its border will also be transparent. Is it possible to have a
transparent frame with visible borders?
···
On 4月22日, 上午12時43分, Tim Roberts <t...@probo.com> wrote:
Yuan-Liang Tang wrote:
> It worked! Thanks a million.
> One small problem though: for the following code, I was not able to
>drawred rectangles; the borders are black. How should I fix it?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 youdrawtherectanglein 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 youdraw,
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 therectangle.--
Tim Roberts, t...@probo.com
Providenza & Boekelheide, Inc.
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.
···
On 4/21/11 7:45 PM, Yuan-Liang Tang wrote:
I got the idea, thanks. Another alternative would be to create a
transparent frame using the "SetTransparent(0)" attribute. However,
its border will also be transparent. Is it possible to have a
transparent frame with visible borders?
--
Robin Dunn
Software Craftsman
Thanks a lot, Robin. I've written some code as follows based on
hasenj's work (Making a fancy window in wxPython | hasenj blog
window-in-wxpython/). However, I still couldn't create a transparent
rectangle with visible red borders. I must have missed something.
Would you please tell me what the problem is with the program. Thanks.
···
--------------------------
import wx
class FancyFrame(wx.Frame):
def __init__(self, width, height):
wx.Frame.__init__(self, None, style = wx.STAY_ON_TOP |
wx.FRAME_NO_TASKBAR |
wx.FRAME_SHAPED, size=(width, height))
self.SetTransparent(100)
b = wx.EmptyBitmap(width, height)
dc = wx.MemoryDC()
dc.SelectObject(b)
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetPen(wx.Pen('red', 2))
dc.DrawRectangle(10, 10, width-10, height-10)
dc.SelectObject(wx.NullBitmap)
self.SetShape(wx.RegionFromBitmap(b))
self.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
self.Show(True)
def OnKeyDown(self, event):
"""quit if user press Esc"""
if event.GetKeyCode() == 27
self.Close(force=True)
else:
event.Skip()
if __name__ == "__main__":
app = wx.App()
f = FancyFrame(300, 300)
app.MainLoop()
-------------------
On 4月23日, 上午12時28分, Robin Dunn <ro...@alldunn.com> wrote:
On 4/21/11 7:45 PM, Yuan-Liang Tang wrote:
> I got the idea, thanks. Another alternative would be to create a
> transparent frame using the "SetTransparent(0)" attribute. However,
> its border will also be transparent. Is it possible to have a
> transparent frame with visible borders?You can use wx.FRAME_SHAPED and make all but the desiredrectangle
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.--
Robin Dunn
Software Craftsmanhttp://wxPython.org
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.
rectframe.py (1.13 KB)
···
On 4/25/11 5:30 PM, yltang wrote:
Thanks a lot, Robin. I've written some code as follows based on
hasenj's work (Making a fancy window in wxPython | hasenj blog
window-in-wxpython/). However, I still couldn't create a transparent
rectangle with visible red borders. I must have missed something.
Would you please tell me what the problem is with the program. Thanks.
--
Robin Dunn
Software Craftsman
Thanks a million, Robin. This is exactly what I needed. One last
question, if I change the statement "dc.DrawRectangle(10, 10,
width-10, height-10)" to dc.DrawRectangle(0, 0, width, height)", there
would be a thin black line at the right and bottom borders of the
frame. Is there a way to get rid of them? What I intend to do is to
draw the exact border of the transparent frame.
···
On 4月29日, 上午1時16分, Robin Dunn <ro...@alldunn.com> wrote:
On 4/25/11 5:30 PM, yltang wrote:
> Thanks a lot, Robin. I've written some code as follows based on
> hasenj's work (Making a fancy window in wxPython | hasenj blog
> window-in-wxpython/). However, I still couldn't create a transparent
> rectangle with visible red borders. I must have missed something.
> Would you please tell me what the problem is with the program. Thanks.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.--
Robin Dunn
Software Craftsmanhttp://wxPython.orgrectframe.py
1K檢視下載
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.
···
On 4/28/11 10:21 PM, yltang wrote:
Thanks a million, Robin. This is exactly what I needed. One last
question, if I change the statement "dc.DrawRectangle(10, 10,
width-10, height-10)" to dc.DrawRectangle(0, 0, width, height)", there
would be a thin black line at the right and bottom borders of the
frame. Is there a way to get rid of them? What I intend to do is to
draw the exact border of the transparent frame.
--
Robin Dunn
Software Craftsman
Git it. Thanks a gain.
···
On 4月29日, 下午4時15分, Robin Dunn <ro...@alldunn.com> wrote:
On 4/28/11 10:21 PM, yltang wrote:
> Thanks a million, Robin. This is exactly what I needed. One last
> question, if I change the statement "dc.DrawRectangle(10, 10,
> width-10, height-10)" to dc.DrawRectangle(0, 0, width, height)", there
> would be a thin black line at the right and bottom borders of the
> frame. Is there a way to get rid of them? What I intend to do is to
>drawthe exact border of the transparent frame.Try using the client size of the frame instead of the total size. Then
you'll be making only the areas that you candrawon visible instead of
including the border of the frame.--
Robin Dunn
Software Craftsmanhttp://wxPython.org