wxBufferedPaintDC(设备上下文)wxPython onPaint事件处理程序出现问题

时间:2011-06-08 14:19:00

标签: python events handler wxwidgets

我有一个名为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()drawScaleBar()的实施方式相同。唯一的区别是drawDots()的复选框位于不同的类中。除了通过调用使用Refresh()的另一个方法调用强制重新绘制事件的父类之外,此复选框的事件处理程序几乎没有任何作用。这是drawScaleBar()drawGrid()方法也可以这样做的方式。

如何解决此问题?

0 个答案:

没有答案