0

我和我的同事正在用 python 编写一个数据处理应用程序。我们目前正在开发应用程序的前端部分。

但是我们有一个大问题,那就是应用程序在随机时间后收到以下错误:

QWidget::repaint: Recursive repaint detected

这个也是时不时冒出来的:

QPainter::begin: Paint device returned engine == 0, type: 1

这是所有 gui 相关内容发生的文件,为了不冗长,我删除了不相关的方法:

gfx.py:

import sys, random, math

from PyQt4 import QtGui, QtCore
from random import randrange

from eventbased import listener

app = QtGui.QApplication(sys.argv)

def exec():
    return app.exec_()

class MapView(QtGui.QMainWindow, listener.Listener):
    def __init__(self, mapimagepath = 0, nodes = 0):

        QtGui.QMainWindow.__init__(self)
        listener.Listener.__init__(self)


        self.setWindowTitle('Population mapping')
        self.map = Map(self, mapimagepath)

        self.setCentralWidget(self.map)

        self.map.start()
        self.center()


    def center(self):
        screen = QtGui.QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move(50, 0)


    def handle(self, event):
        if(event.type == 0):
            self.map.addNode(event.object.scanner)
        if(event.type == 1):
            self.map.delNode(event.object.scanner)
        if(event.type == 2):
            self.map.addBranch(event.object.node1.scanner, event.object.node2.scanner)
        if(event.type == 3):
            self.map.delBranch(event.object.node1.scanner, event.object.node2.scanner)
        if(event.type == 4):
            self.map.changeNode(event.object.scanner.sensorid, event.result)
        if(event.type == 5):
            self.map.changeBranch(event.object.node1.scanner.sensorid, event.object.node2.scanner.sensorid, event.result)


        self.repaint(self.map.contentsRect())
        self.update(self.map.contentsRect())



######################################################################

class Map(QtGui.QFrame):

    def __init__(self, parent, mapimagepath):
        QtGui.QFrame.__init__(self, parent)

        #self.timer = QtCore.QBasicTimer()

        #coordinaten hoeken NE en SW voor kaart in map graphics van SKO 
        self.realmap = RealMap( 
            mapimagepath,
            (51.0442, 3.7268), 
            (51.0405, 3.7242),
            550, 
            800)

        parent.setGeometry(0,0,self.realmap.width, self.realmap.height)
        self.refreshspeed = 5000

        self.mapNodes = {}

    def addNode(self, scanner):
        coord = self.realmap.convertLatLon2Pix((scanner.latitude, scanner.longitude))

        self.mapNodes[scanner.sensorid] = MapNode(scanner, coord[0], coord[1])

    # type: 4 --> changenode    ,   
    #((change, gem_ref, procentuele verandering ref), scanner object)
    def changeNode(self, sensorid, branchdata):
        self.mapNodes[sensorid].calcDanger(branchdata[2])

    def paintEvent(self, event):

        painter = QtGui.QPainter(self)
        rect = self.contentsRect()

        #teken achtergrond
        self.realmap.drawRealMap(painter)

        #teken nodes
        for sensorid, mapNode in self.mapNodes.items():
            mapNode.drawMapNode(painter, self.realmap)


######################################################################

class RealMap:
    def __init__(self, path, coordRightTop, 
        coordLeftBot, width, height, pixpermet = 2.6):

        self.path = path
        self.coordLeftBot = coordLeftBot
        self.coordRightTop = coordRightTop

        self.width = width
        self.height = height

        self.realdim = self.calcRealDim()

        self.pixpermet = pixpermet

    def drawRealMap(self, painter):
        image = QtGui.QImage(self.path)
        painter.drawImage(0,0,image)


######################################################################

class MapNode:
    dangertocolor = {"normal":"graphics//gradients//green.png",
                    "elevated":"graphics//gradients//orange.png",
                    "danger":"graphics//gradients//red.png"}

    def __init__(self, scanner, x, y, danger = 0):
        self.scanner = scanner
        self.x = x
        self.y = y
        self.danger = 'normal'

        self.calcDanger(danger)

    def drawMapNode(self, painter, realmap):
        radiusm = self.scanner.range
        radiusp = radiusm*realmap.pixpermet
        factor = radiusp/200        # basis grootte gradiënten is 200 pixels.

        icon = QtGui.QImage("graphics//BT-icon.png")

        grad = QtGui.QImage(MapNode.dangertocolor[self.danger])
        grad = grad.scaled(grad.size().width()*factor, grad.size().height()*factor)


        painter.drawImage(self.x-100*factor,self.y-100*factor, grad)
        painter.drawImage(self.x-10, self.y-10,icon)
        painter.drawText(self.x-15, self.y+20, str(self.scanner.sensorid) + '-' + str(self.scanner.name))

通过我们的应用程序类创建一个对象:

    mapview = gfx.MapView(g_image)
    mapview.show()

所以第一个问题是。我们在paintEvent 方法中做错了什么?

第二个问题 有没有办法让每次发生的随机事件都不会调用paintevent?(如鼠标悬停等)?

我试过类似的东西:

def paintEvent(self, event):
    if(isinstance(event, QtGui.QPaintEvent)):

        painter = QtGui.QPainter(self)
        rect = self.contentsRect()

        #teken achtergrond
        self.realmap.drawRealMap(painter)

        #teken nodes
        for sensorid, mapNode in self.mapNodes.items():
             mapNode.drawMapNode(painter, self.realmap)
    else:
        pass

这“有效”,但我想一般来说......它实际上使错误看起来比没有条件的情况要快得多。

4

1 回答 1

1

在您的 gfx.py 中,您有:

    self.repaint(self.map.contentsRect())
    self.update(self.map.contentsRect())

repaint一个接一个地打电话是update多余的。如果一个绘画事件通过那个处理程序并且你repaint()在那里调用,你就是在请求无限递归。

记下文档中的任何警告注意事项

http://doc.qt.io/qt-4.8/qwidget.html#update

http://doc.qt.io/qt-4.8/qwidget.html#repaint

http://doc.qt.io/qt-4.8/qwidget.html#paintEvent

我没有立即看到您的其他错误的原因,但这可能与 QPainter 在不应该使用的情况下使用有关...

http://doc.qt.io/qt-4.8/qpainter.html#begin

http://doc.qt.io/qt-4.8/qpainter.html#details

希望有帮助。

于 2013-05-10T22:16:48.730 回答