开发者

wxBufferedPaintDC (Device Context) Trouble with wxPython onPaint event handler

开发者 https://www.devze.com 2023-03-12 00:55 出处:网络
I have a class called imageBrowser that displays an image in a wxMDIChildFrame.This class is mainly for displaying an image to the user with a set of controls to browse through the image set.Now, in t

I have a class called imageBrowser that displays an image in a wxMDIChildFrame. This class is mainly for displaying an image to the user with a set of controls to browse through the image set. Now, in this class I have overridden the onPaint event handler to respond to the controls attached to this wxMDIChildFrame. So there are two checkboxes on the imageBrowser: one for a grid overlay and another for a scalebar overlay. When checked, the DC draws the grid on top of the image or the scale bar. These methods work fine. The problem occurs when I check off another checkbox in a seperate wxMDIChildFrame to draw some random dots over the image, the grid and scalebar disappear immediatly upon checking this checkbox. However, if I just resize the imageBrowser, wxMDIChildFrame, the grid, scalebar, and dots all appear. So here is my onPaint handler:

def OnPaint(self, event):
    dc = wx.BufferedPaintDC(self.staticBitmap, self.staticBitmap.GetBitmap())
    dc.Clear()
    dc.DrawBitmap(self.wxBitmap, 0, 0)
    self.drawScaleBar(dc)
    self.drawGrid(dc)
    self.drawDots(dc)
    event.Skip()

def drawGrid(self, dc):
    gridWid, gridHgt = self.staticBitmap.GetBitmap().GetSize()
    numRows, numCols = self.gridSize, self.gridSize
    if self.controlPanel.showGridBox.IsChecked():
        dc.SetPen(wx.Pen(self.gridColor, self.gridThickness))
        dc.SetTextForeground(self.gridColor)
        cellWid = float( gridWid - 1) / numRows
        cellHgt = float( gridHgt - 1) / numCols
        for rowNum in xrange( numRows + 1) :
            dc.DrawLine( 0, rowNum*cellHgt, gridWid, rowNum*cellHgt )
        for colNum in xrange( numCols + 1 ) :
            dc.DrawLine( colNum*cellWid, 0, colNum*cellWid, gridHgt )


def drawScaleBar(self, dc):
    gridWid, gridHgt = self.wxBitmap.GetSize()
    if self.controlPanel.showScaleBar.IsChecked():
        dc.SetPen(wx.Pen(self.scaleColor, 2))
        dc.SetTextForeground(self.scaleColor)
        width = self.Tools.imageInfo.size.GetLabel().split()[1]
        #Scales the bar to the image width.  If the user selected scale is larger than
        #the current image the scale is set to the maximum width of the image.
        if width != 'None':
            width = width.replace('m', '')
            width = float(width)
            lineSize = ((gridWid/width) * (self.scaleSize/100.0))
            if lineSize > gridWid:
                lineSize = (gridWid * 0.9) - 1
                self.scaleSize = int(width * 100 - 10)
                self.controlPanel.chooseScaleSize.SetValue(str(self.scaleSize))
                self.drawScaleBar(dc)
            elif self.scaleLoc == 'Top Left':
                dc.DrawLine(10, gridHgt * 0.1, 10 + lineSize, gridHgt * 0.1)
                dc.DrawLine(10, gridHgt * 0.1 + 10, 10, gridHgt * 0.1 - 10)
                dc.DrawLine(10 + lineSize, gridHgt * 0.1 + 10, 10 + lineSize, gridHgt * 0.1 - 10)
                dc.DrawText(str(self.scaleSize) + 'cm', (10 + 10 + lineSize)/2.0 - 15, gridHgt * 0.1 - 25)
            elif self.scaleLoc == 'Top Right':
                dc.DrawLine(gridWid - 10, gridHgt * 0.1, (gridWid - 10) - lineSize, gridHgt * 0.1)
            开发者_运维问答    dc.DrawLine(gridWid - 10, gridHgt * 0.1 + 10, gridWid - 10, gridHgt * 0.1 - 10)
                dc.DrawLine((gridWid - 10) - lineSize, gridHgt * 0.1 + 10, (gridWid - 10) - lineSize, gridHgt * 0.1 - 10)
                dc.DrawText(str(self.scaleSize) + 'cm', ((gridWid - 10 - lineSize)+(gridWid - 10))/2.0 - 20, gridHgt * 0.1 - 25)
            elif self.scaleLoc == 'Bottom Left':
                dc.DrawLine(10, gridHgt * 0.9, 10 + lineSize, gridHgt * 0.9)
                dc.DrawLine(10, gridHgt * 0.9 + 10, 10, gridHgt * 0.9 - 10)
                dc.DrawLine(10 + lineSize, gridHgt * 0.9 + 10, 10 + lineSize, gridHgt * 0.9 - 10)
                dc.DrawText(str(self.scaleSize) + 'cm', (10 + 10 + lineSize)/2.0 - 15, gridHgt * 0.9 - 25)
            elif self.scaleLoc == 'Bottom Right':
                dc.DrawLine(gridWid - 10, gridHgt * 0.9, (gridWid - 10) - lineSize, gridHgt * 0.9)
                dc.DrawLine(gridWid - 10, gridHgt * 0.9 + 10, gridWid - 10, gridHgt * 0.9 - 10)
                dc.DrawLine((gridWid - 10) - lineSize, gridHgt * 0.9 + 10, (gridWid - 10) - lineSize, gridHgt * 0.9 - 10)
                dc.DrawText(str(self.scaleSize) + 'cm', ((gridWid - 10 - lineSize)+(gridWid - 10))/2.0 - 20, gridHgt * 0.9 - 25)
        else:
            #If there is no depth or size information for the current image the scale
            #bar is collapsed and '0cm' is displayed.
            if self.scaleLoc == 'Top Left':
                dc.DrawLine((15) + (gridWid/15), gridHgt * 0.1 + 10, (15) + (gridWid/15), gridHgt * 0.1 - 10)
                dc.DrawText('0cm', (15) + (gridWid/15/2), gridHgt * 0.1 - 25)
            elif self.scaleLoc == 'Top Right':
                dc.DrawLine((gridWid * 0.9) - (gridWid/15), gridHgt * 0.1 + 10, (gridWid * 0.9) - (gridWid/15), gridHgt * 0.1 - 10)
                dc.DrawText('0cm', (gridWid * 0.9) - (gridWid/15), gridHgt * 0.1 - 25)
            elif self.scaleLoc == 'Bottom Left':
                dc.DrawLine((15) + (gridWid/15), gridHgt * 0.9 + 10, (15) + (gridWid/15), gridHgt * 0.9 - 10)
                dc.DrawText('0cm', (15) + (gridWid/15/2), gridHgt * 0.9 - 25)
            elif self.scaleLoc == 'Bottom Right':
                dc.DrawLine((gridWid * 0.9) - (gridWid/15), gridHgt * 0.9 + 10, (gridWid * 0.9) - (gridWid/15), gridHgt * 0.9 - 10)
                dc.DrawText('0cm', (gridWid * 0.9) - (gridWid/15), gridHgt * 0.9 - 25)

def drawDots(self, dc):
    if self.Tools.classificationTool.dotEnable.GetValue():
        for dictionary in Workspace.assignmentHash:
            if dictionary.keys()[0] == Workspace.data.getImageName(Workspace.currentImageIndex):
                dc.SetPen(wx.Pen('Red', 1))
                dc.SetBrush(wx.Brush('Red'))
                print 'This image should have Dots!'
                index = Workspace.assignmentHash.index(dictionary)
                for dict in Workspace.assignmentHash[index].values()[0]:
                    s = dict.keys()[0]
                    r = re.search('(d\d+)(\(\d.\d+,\d.\d+\))', s)
                    num = r.group(1)[1:]
                    coord = r.group(2).split(',')
                    x = float(coord[0][1:])
                    x *= (Workspace.iWidth*Workspace.zoomScale)
                    x = int(x)
                    y = float(coord[1][:-1])
                    y *= (Workspace.iHeight*Workspace.zoomScale)
                    y = int(y)
                    dc.DrawCircle(x, y, 3)

Again, this works fine as long as the checkbox for drawDots (located on a different wxMDIChildFrame) is not enabled. It is important to note that this other wxMDIChildFrame initially loads as just a blank Frame. The user then opens a 'Classification File' that destroys that initial blank frame, removes its initial menu from the menu bar and then re-initializes it with widgets based on the 'classification file' and then adds the menu back into the menubar with additional options. It is only after this 'classification file' has been opened that the checkbox clears the grid/scalebar.

I implemented the drawDots() method the same way I implimented the drawGrid() and drawScaleBar(). The only difference is that the checkbox for drawDots() is in a different class. The event handler for this checkbox does literally nothing except make a call to a parent class that forces a re-paint event by calling another method that uses Refresh(). This is the way that the drawScaleBar() and drawGrid() methods do it as well.

How can I fix this problem?

0

精彩评论

暂无评论...
验证码 换一张
取 消