Drawing overlay rectangle using mouse

Dear All,

In one of my application, i need to draw multiple overlay rectangles over staticbitmap inside a scrollwindow. Displaying image is done but i am stuck at this overlay rectangles. I need to draw these rectangles using mouse pointer. I have seen few sample as below -

def OnMouseMove(self, evt):
if not self.HasCapture():
return
rect = wx.RectPP(self.startPos, evt.GetPosition())
# Draw the rubber-band rectangle using an overlay so it
# will manage keeping the rectangle and the former window
# contents separate.
dc = wx.ScreenDC()
odc = wx.DCOverlay(self.overlay, dc)
odc.Clear()

    pen = wx.Pen("black", 2)
    brush = wx.Brush(wx.Colour(192,192,192,128))
    if "wxMac" in wx.PlatformInfo:
        dc.SetPen(pen)
        dc.SetBrush(brush)
        dc.DrawRectangleRect(rect)
    else:
        # use a GC on Windows (and GTK?)
        # this crashed on the Mac
        ctx = wx.GraphicsContext_Create(dc)
        ctx.SetPen(pen)
        ctx.SetBrush(brush)
        ctx.DrawRectangle(*rect)

    del odc # work around a bug in the Python wrappers to make
            # sure the odc is destroyed before the dc is.

that draw rectangle very fine but whenever the windows is moved or scrolled up or down those rectangles gets erased.
My objective is that these rectangles should stay (or if possible move using keys) on images as long as i am not changing the image or closing the window completely and finally i need to capture the coordinates as well that i know how to do. I am attaching the source code example that also i found over internet (thanks to the author).
Please help.
Thanks in advance.

Regards
Gaurav

Overlaytest2.py (3 KB)

Gaurav,

···

On Fri, Mar 3, 2017 at 3:30 AM, Gaurav Sharma gauravsharma.81.in@gmail.com wrote:

Dear All,

In one of my application, i need to draw multiple overlay rectangles over staticbitmap inside a scrollwindow. Displaying image is done but i am stuck at this overlay rectangles. I need to draw these rectangles using mouse pointer. I have seen few sample as below -

def OnMouseMove(self, evt):
if not self.HasCapture():
return
rect = wx.RectPP(self.startPos, evt.GetPosition())
# Draw the rubber-band rectangle using an overlay so it
# will manage keeping the rectangle and the former window
# contents separate.
dc = wx.ScreenDC()
odc = wx.DCOverlay(self.overlay, dc)
odc.Clear()

    pen = wx.Pen("black", 2)
    brush = wx.Brush(wx.Colour(192,192,192,128))
    if "wxMac" in wx.PlatformInfo:
        dc.SetPen(pen)
        dc.SetBrush(brush)
        dc.DrawRectangleRect(rect)
    else:
        # use a GC on Windows (and GTK?)
        # this crashed on the Mac
        ctx = wx.GraphicsContext_Create(dc)
        ctx.SetPen(pen)
        ctx.SetBrush(brush)
        ctx.DrawRectangle(*rect)

    del odc # work around a bug in the Python wrappers to make
            # sure the odc is destroyed before the dc is.

that draw rectangle very fine but whenever the windows is moved or scrolled up or down those rectangles gets erased.
My objective is that these rectangles should stay (or if possible move using keys) on images as long as i am not changing the image or closing the window completely and finally i need to capture the coordinates as well that i know how to do. I am attaching the source code example that also i found over internet (thanks to the author).
Please help.
Thanks in advance.

I believe you need to bind a function to wx.EVT_PAINT and have that function redraw the entire panel, including the static bitmap and the overlays (say from saved coordinates for the rubber-band box drawn by the user). I think you’d probably also want to bind wx.EVT_SIZE to function that eventually calls self.Refresh(), which will generate a “needs repainting” event.

FWIW, when I do such things (taking a bitmap from a live camera source, and drawing that plus user-defined overlays), I do this in the Panel.onPaint method of a wx.Panel, which has been bound the wx.EVT_PAINT, roughly as:

dc = wx.AutoBufferedPaintDC(self)

dc.Clear()

dc.DrawBitmap(bitmap, pad_width, pad_height, useMask=True)

dc.SetBrush(wx.Brush(‘Black’, wx.BRUSHSTYLE_TRANSPARENT))

dc.SetPen(rect_color, 1.0, wx.SOLID))

dc.DrawRectangle(*rect_coords)

I know that’s not complete, but I think you have the dc drawing stuff understood. Using AutoBufferedPaintDC gives pretty good, flicker-free drawing.

Hope that helps,

–Matt

A few notes:

        if "wxMac" in wx.PlatformInfo:

            dc.SetPen(pen)
            dc.SetBrush(brush)
            dc.DrawRectangleRect(rect)
        else:
            # use a GC on Windows (and GTK?)
            # this crashed on the Mac
            ctx = wx.GraphicsContext_Create(dc)
            ctx.SetPen(pen)
            ctx.SetBrush(brush)
            ctx.DrawRectangle(*rect)

I'd just use a DC everywhere, then -- this use case doesn't make use of the
GCs advantages, anyway.

that draw rectangle very fine but whenever the windows is moved or scrolled

up or down those rectangles gets erased.

scrolling is an issue -- what coordinates do you want teh overlay to be in?
i.e., should it scroll with the contents? IF so, I think you may not be
able to do that with an overlay.

I believe you need to bind a function to wx.EVT_PAINT and have that
function redraw the entire panel, including the static bitmap and the
overlays (say from saved coordinates for the rubber-band box drawn by the
user).

whic pretty much defeats the whole point of an overlay -- if you meed to
mange drawing it, you might as well simply draw the rect normally.

That being said, I so recall al ot of frustration with Overlays not really
doing what I think they should :slight_smile:

You may want to take a look at these examples:

I haven't tested them for ages, but maybe there is something useful there?

there are a couple Overlay examples in there.

And a bunch of other useful drawing code.

-CHB

···

I think you'd probably also want to bind wx.EVT_SIZE to function that
eventually calls self.Refresh(), which will generate a "needs repainting"
event.

FWIW, when I do such things (taking a bitmap from a live camera source,
and drawing that plus user-defined overlays), I do this in the
Panel.onPaint method of a wx.Panel, which has been bound the wx.EVT_PAINT,
roughly as:

    dc = wx.AutoBufferedPaintDC(self)
    dc.Clear()
    dc.DrawBitmap(bitmap, pad_width, pad_height, useMask=True)
    dc.SetBrush(wx.Brush('Black', wx.BRUSHSTYLE_TRANSPARENT))
    dc.SetPen(rect_color, 1.0, wx.SOLID))
    dc.DrawRectangle(*rect_coords)

I know that's not complete, but I think you have the dc drawing stuff
understood. Using AutoBufferedPaintDC gives pretty good, flicker-free
drawing.

Hope that helps,

--Matt

--
You received this message because you are subscribed to the Google Groups
"wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (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

Hello Chris,

First of all thanks for your reply and all others.

I have tried many things from replies of your and many other users but no success. I would explain what i want to do -
I have a bitmap image inside a scrolled window. Now i need a feature to draw a one or more rectangle over the image. These rectangles must not change the original image and just stay over image temporarily as long as i don’t close the app. I don’t want to get them erased by scrolling action. i should be able to move them over image using mouse. Behind the scene i would be recording the coordinates of rectangles in some file. I am not sure if i need overlay or not. I am not well versed in wxpython now as i am a beginner.
If you can suggest some way then it would be great help.

Thanks
-Gaurav

···

On Saturday, 4 March 2017 03:04:28 UTC+5:30, Chris Barker wrote:

A few notes:

if “wxMac” in wx.PlatformInfo:
dc.SetPen(pen)
dc.SetBrush(brush)
dc.DrawRectangleRect(rect)
else:
# use a GC on Windows (and GTK?)
# this crashed on the Mac
ctx = wx.GraphicsContext_Create(dc)
ctx.SetPen(pen)
ctx.SetBrush(brush)
ctx.DrawRectangle(*rect)

I’d just use a DC everywhere, then – this use case doesn’t make use of the GCs advantages, anyway.

that draw rectangle very fine but whenever the windows is moved or scrolled up or down those rectangles gets erased.

scrolling is an issue – what coordinates do you want teh overlay to be in? i.e., should it scroll with the contents? IF so, I think you may not be able to do that with an overlay.

I believe you need to bind a function to wx.EVT_PAINT and have that function redraw the entire panel, including the static bitmap and the overlays (say from saved coordinates for the rubber-band box drawn by the user).

whic pretty much defeats the whole point of an overlay – if you meed to mange drawing it, you might as well simply draw the rect normally.

That being said, I so recall al ot of frustration with Overlays not really doing what I think they should :slight_smile:

You may want to take a look at these examples:

I haven’t tested them for ages, but maybe there is something useful there?

https://github.com/PythonCHB/wxPythonDemos

there are a couple Overlay examples in there.

And a bunch of other useful drawing code.

-CHB

I think you’d probably also want to bind wx.EVT_SIZE to function that eventually calls self.Refresh(), which will generate a “needs repainting” event.

FWIW, when I do such things (taking a bitmap from a live camera source, and drawing that plus user-defined overlays), I do this in the Panel.onPaint method of a wx.Panel, which has been bound the wx.EVT_PAINT, roughly as:

dc = wx.AutoBufferedPaintDC(self)

dc.Clear()

dc.DrawBitmap(bitmap, pad_width, pad_height, useMask=True)

dc.SetBrush(wx.Brush(‘Black’, wx.BRUSHSTYLE_TRANSPARENT))

dc.SetPen(rect_color, 1.0, wx.SOLID))

dc.DrawRectangle(*rect_coords)

I know that’s not complete, but I think you have the dc drawing stuff understood. Using AutoBufferedPaintDC gives pretty good, flicker-free drawing.

Hope that helps,

–Matt

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-user...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris....@noaa.gov

I have a bitmap image inside a scrolled window. Now i need a feature to
draw a one or more rectangle over the image. These rectangles must not
change the original image and just stay over image temporarily as long as i
don't close the app. I don't want to get them erased by scrolling action.

If you want them to stay in the same "virtual position", then try the
enclosed.

(you'll need to edit the file to point to an image file of your own...)

This code can be found here also:

along with a bunch of other demos

In this case, it's a single hard-coded rectangle -- I'll leave it as an
exercise for the reader to add code to update the position of the
rectangle...

This is the simple, no-overlay way to do it.

-CHB

ScrolledBitmap.py (1.39 KB)

···

On Wed, Mar 15, 2017 at 2:01 AM, Gaurav Sharma <gauravsharma.81.in@gmail.com > wrote:

i should be able to move them over image using mouse. Behind the scene i
would be recording the coordinates of rectangles in some file. I am not
sure if i need overlay or not. I am not well versed in wxpython now as i am
a beginner.
If you can suggest some way then it would be great help.

Thanks
-Gaurav

On Saturday, 4 March 2017 03:04:28 UTC+5:30, Chris Barker wrote:

A few notes:

        if "wxMac" in wx.PlatformInfo:

            dc.SetPen(pen)
            dc.SetBrush(brush)
            dc.DrawRectangleRect(rect)
        else:
            # use a GC on Windows (and GTK?)
            # this crashed on the Mac
            ctx = wx.GraphicsContext_Create(dc)
            ctx.SetPen(pen)
            ctx.SetBrush(brush)
            ctx.DrawRectangle(*rect)

I'd just use a DC everywhere, then -- this use case doesn't make use of
the GCs advantages, anyway.

that draw rectangle very fine but whenever the windows is moved or

scrolled up or down those rectangles gets erased.

scrolling is an issue -- what coordinates do you want teh overlay to be
in? i.e., should it scroll with the contents? IF so, I think you may not be
able to do that with an overlay.

I believe you need to bind a function to wx.EVT_PAINT and have that
function redraw the entire panel, including the static bitmap and the
overlays (say from saved coordinates for the rubber-band box drawn by the
user).

whic pretty much defeats the whole point of an overlay -- if you meed to
mange drawing it, you might as well simply draw the rect normally.

That being said, I so recall al ot of frustration with Overlays not
really doing what I think they should :slight_smile:

You may want to take a look at these examples:

I haven't tested them for ages, but maybe there is something useful there?

GitHub - PythonCHB/wxPythonDemos: wxPython Demos: Various small demos of wxPython features -- dveloped over years of discussion on the wxPython-users mailinglist

there are a couple Overlay examples in there.

And a bunch of other useful drawing code.

-CHB

I think you'd probably also want to bind wx.EVT_SIZE to function that
eventually calls self.Refresh(), which will generate a "needs repainting"
event.

FWIW, when I do such things (taking a bitmap from a live camera source,
and drawing that plus user-defined overlays), I do this in the
Panel.onPaint method of a wx.Panel, which has been bound the wx.EVT_PAINT,
roughly as:

    dc = wx.AutoBufferedPaintDC(self)
    dc.Clear()
    dc.DrawBitmap(bitmap, pad_width, pad_height, useMask=True)
    dc.SetBrush(wx.Brush('Black', wx.BRUSHSTYLE_TRANSPARENT))
    dc.SetPen(rect_color, 1.0, wx.SOLID))
    dc.DrawRectangle(*rect_coords)

I know that's not complete, but I think you have the dc drawing stuff
understood. Using AutoBufferedPaintDC gives pretty good, flicker-free
drawing.

Hope that helps,

--Matt

--
You received this message because you are subscribed to the Google
Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to wxpython-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris....@noaa.gov

--
You received this message because you are subscribed to the Google Groups
"wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (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