[wxPython] Drawing question

I'd like to draw a rectangle when the left mouse button is pressed
and dragged and have the rectangle resize accordingly during the
drag. While I can easily compute the coordinates of the drag, I'm
not sure how to save the old region from the dc and copy it back
afterwards. I'm sure it's a really simple function usage but I
can't find any docs and was unable to make it work. Perhaps the
blit function is needed if I can somehow get the old region into a
wxMemoryDC?

                  -- Mike

···

--
Michael Gilfix
mgilfix@eecs.tufts.edu

Michael Gilfix wrote:

I'd like to draw a rectangle when the left mouse button is pressed
and dragged and have the rectangle resize accordingly during the
drag. While I can easily compute the coordinates of the drag, I'm
not sure how to save the old region from the dc and copy it back
afterwards.

I think that's essentially impossible, as you have no way of knowing
what was drawn UNDER The rectangle. If someone has I nifty trick, I'd
love to hear it. (by the way the is an image-dragging example in teh
demo somewhere, you might want to take a look)

I'm sure it's a really simple function usage but I
can't find any docs and was unable to make it work.

I don't think it's that simple. You can redraw the area under the
rectangle each time, and use SetClippingRegion (or something like that)
to draw just the part that is damaged. If you are drawing a lot, that
could be slow, however.

Perhaps the
blit function is needed if I can somehow get the old region into a
wxMemoryDC?

A similar option is to double buffer the whole panel (draw to a wxMemory
DC, and then blit it to the Panel. On your OnPaint, all you need is the
Blit(). This also has the advantage of essentially instant re-drawing
when the window is uncovered. I'm a big fan of double buffering.

Another option is not to draw the whole rectangle, but rather an outline
of it, and use

dc.SetLogicalFunction(wxINVERT)

What this does is draw the inverse color of whatever is already on the
dc. If you draw the same thing twice, you are back to where you started.
You can then draw a rectangle where the mouse is, then the next mouse
moving event, you can re-draw that one, putting the dc back to the way
it was, and then draw another one in teh new mouse position. Enough
talk, I've enclosed some code. As you can tell by the name, I wrote it
to experiment with generating events, but if you right click-and-drag on
the rectangle, you can see how they get moved. Look in the MouseMoving
function to see how I did it. Maybe this will work for you.

-Chris

TestEvents.py (6.58 KB)

···

--
Christopher Barker, Ph.D.
Oceanographer
                                        
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Thanks Chris. That did the trick. wxINVERT was the key. I knew I
wanted something similar (my first thought was xor but that wouldn't
work because I'm not guaranteed that the background was white) but
wasn't sure what it was. If it were more complicated than the mouse
movement, I would probably have gone the double buffering route and I
may yet still if I try to do some fancy stuff like animation at some
point.

                       -- Mike

···

On Mon, Feb 25 @ 13:46, Chris Barker wrote:

Michael Gilfix wrote:
A similar option is to double buffer the whole panel (draw to a wxMemory
DC, and then blit it to the Panel. On your OnPaint, all you need is the
Blit(). This also has the advantage of essentially instant re-drawing
when the window is uncovered. I'm a big fan of double buffering.

Another option is not to draw the whole rectangle, but rather an outline
of it, and use

dc.SetLogicalFunction(wxINVERT)

What this does is draw the inverse color of whatever is already on the
dc. If you draw the same thing twice, you are back to where you started.
You can then draw a rectangle where the mouse is, then the next mouse
moving event, you can re-draw that one, putting the dc back to the way
it was, and then draw another one in teh new mouse position. Enough
talk, I've enclosed some code. As you can tell by the name, I wrote it
to experiment with generating events, but if you right click-and-drag on
the rectangle, you can see how they get moved. Look in the MouseMoving
function to see how I did it. Maybe this will work for you.

`-> (Chris.Barker)

--
Michael Gilfix
mgilfix@eecs.tufts.edu