wxBufferedPaintDC(设备上下文)wxPython onPaint事件指针出现故障

2024-05-23 17:06:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个名为imageBrowser的类,它在wxMDIChildFrame中显示一个图像。该类主要用于向用户显示图像,其中包含一组用于浏览图像集的控件。现在,在这个类中,我重写了onPaint事件处理程序,以响应附加到此wxMDIChildFrame的控件。因此imageBrowser上有两个复选框:一个用于网格覆盖,另一个用于缩放覆盖。选中时,DC在图像或比例尺顶部绘制网格。这些方法效果很好。当我在一个单独的wxMDIChildFrame中选中另一个复选框,在图像上画一些随机点时,网格和比例尺会在选中此复选框后立即消失。但是,如果我只是调整imageBrowserwxMDIChildFrame,网格、比例尺和点都会出现。下面是我的onPaint处理程序:

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)

同样,只要drawDots的复选框(位于不同的wxMDIChildFrame)没有启用,这个方法就可以正常工作。需要注意的是,另一个wxMDIChildFrame最初只加载一个空白帧。然后,用户打开一个“分类文件”,该文件会销毁最初的空白框,从菜单栏中删除其初始菜单,然后使用基于“分类文件”的小部件重新初始化它,然后使用其他选项将菜单添加回菜单栏中。只有在打开这个“分类文件”之后,复选框才会清除网格/比例尺。在

我实现drawDots()方法的方式与实现drawGrid()和{相同。唯一的区别是drawDots()的复选框在不同的类中。这个复选框的事件处理程序实际上什么也不做,只调用父类,该类通过调用另一个使用Refresh()的方法来强制重新绘制事件。这就是drawScaleBar()drawGrid()方法的方法。在

我怎样才能解决这个问题?在


Tags: theselfifdcwidthworkspace复选框elif