wx.Overlay resetting panel background

Here’s the deal, i’m working on a Image tagger for an AI model training. My main window looks a like this (omiting some code irrelevant to the topic):

class TaggerUI(wx.Frame):

    currentPath = "../"
    saved = True
    drawMode =  CursorMode.DISABLED
    overlay = None
    cursorX,cursorY = 0,0

    def __init__(self,*args,**kwargs):
        super(TaggerUI,self).__init__(*args,**kwargs)
        
        self.InitUI()
        self.Maximize()
        self.Centre()
    
    def InitUI(self):
        #Gui panel
        panel = wx.Panel(self)

        font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT)

        font.SetPointSize(9)

        #Main Sizer 
        mainBox = wx.BoxSizer(wx.HORIZONTAL)

          
        #Main aplication box
        appBox = wx.BoxSizer(wx.VERTICAL)
       
        #Box for imageViewer + tag manager
        innerBox = wx.BoxSizer(wx.HORIZONTAL)
        
        #imageViewer

        #Separate panel for imageViewer
        imagePanel = wx.Panel(panel, size=wx.Size(550,600))
        imagePanel.SetBackgroundColour('#000000')
        imageSize = imagePanel.GetClientSize()   
        #BoxSizer to fit image into
        imageBox = wx.BoxSizer(wx.HORIZONTAL)
    
        #Load image into bitmap
        image = wx.Image("../res/test_image.jpg")

        image = image.Scale(imageSize.GetWidth() - 10,
                            imageSize.GetHeight() - 10)
        bitmap = wx.StaticBitmap(imagePanel,id=BITMAP,bitmap=wx.Bitmap(image))

        imageBox.Add(bitmap,proportion=1,flag = wx.ALL|wx.EXPAND,border = 5)
        imagePanel.SetSizer(imageBox)
        
        self.setBitmap(bitmap)
        self.setImagePanel(imagePanel)

       
   
        #Combine image viewer and tag lister into the inner box
        innerBox.Add(imagePanel,proportion=1,flag=wx.EXPAND|wx.TOP,border = 20)
        innerBox.Add(tagBox,proportion=1,flag=wx.EXPAND)
        
        #Add Viewer + Tagger box and Buttom box to make main app
        appBox.Add(innerBox,proportion=1,flag=wx.EXPAND)
        appBox.Add(buttonBox,flag=wx.EXPAND|wx.TOP|wx.BOTTOM,border = 20)

        #Combine app and fileExplorer into main sizer        
        mainBox.Add(fileDirectory,proportion=1,
                             flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM,
                             border = 10)
        mainBox.Add(appBox,proportion=1,flag=wx.EXPAND)

        panel.SetSizer(mainBox)
        self.setPanel(panel)
        
        self.bindMenuEvents()
        self.bindDirectoryEvents()
        self.bindBitmapEvents()
        self.bindButtonBoardEvents()

    def onMouseMotion(self,e):
        if self.drawMode == CursorMode.DRAWING:
            
            if self.overlay == None:
                self.overlay = wx.Overlay()
            dc = wx.WindowDC(self.imagePanel)
            dcOverlay = wx.DCOverlay(self.overlay,dc)
            dcOverlay.Clear()
            x_0, y_0 = self.cursorX, self.cursorY
            x_1, y_1 = e.GetLogicalPosition(dc).Get()
            width = x_1 - x_0
            height = y_1 - y_0

            color = '#FF0000' 
            dc.SetPen(wx.Pen(color,1))
            dc.SetBrush(wx.TRANSPARENT_BRUSH)
            dc.DrawRectangle(x_0, y_0, width, height)

Te problem is that whenever I start the tagging process, when i start moving the mouse the picture resets to the first tagged picture, but the finished rectangle draws properly over the respective image. So i asume that’s someting related to the dcOverlay.Clear() call, because when i comment it out it doesnt reset the image but i need it to clear the rectangles that show when i’m moving the mouse

Hi, mateo

I tried to run your code but couldn’t because of many undefined name errors. If the posted code was not only minimum but also runnable, I think you will get more advice.

Anyway, I made a small code, hope this would be a help for you to start up.

import wx

class TestPanel(wx.Panel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_DCLICK, lambda v: self.Draw())
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        
        self.image = wx.Image("phoenix-fire-md.png")
        self.overlay = wx.Overlay()
        self.Draw()
    
    def OnLeftDown(self, evt):
        self.CaptureMouse()
        self._startPos = evt.GetPosition()
    
    def OnMouseMove(self, evt):
        if evt.Dragging() and evt.LeftIsDown():
            dc = wx.ClientDC(self)
            # Comment out the next line if you don't want to draw on a bitmap
            dc = wx.BufferedDC(dc, self.bitmap)
            
            odc = wx.DCOverlay(self.overlay, dc)
            odc.Clear()
            
            rect = wx.Rect(self._startPos, evt.Position)
            dc = wx.GCDC(dc) # <-- necessary for transparency?
            
            dc.SetPen(wx.Pen('#0000ff80'))
            dc.SetBrush(wx.Brush('#00ffff80'))
            dc.DrawRectangle(rect)
            dc.DrawText(str(rect), *self._startPos)
            del odc
    
    def OnLeftUp(self, evt):
        if self.HasCapture():
            self.ReleaseMouse()
        
        # When the mouse is released we reset the overlay and it
        # restores the former content to the window.
        self.overlay.Reset()
        
        # Finally blit buffer to show the final image
        dc = wx.BufferedDC(wx.ClientDC(self), self.bitmap)
    
    def OnPaint(self, evt):
        dc = wx.BufferedPaintDC(self, self.bitmap)
    
    def Draw(self):
        self.bitmap = self.image.ConvertToBitmap()
        dc = wx.BufferedDC(wx.ClientDC(self), self.bitmap)

if __name__ == "__main__":
    app = wx.App()
    frm = wx.Frame(None)
    frm.panel = TestPanel(frm)
    frm.Show()
    app.MainLoop()