Python pyqt-运行时出错,可能是错误的paintevent方法实现

Python pyqt-运行时出错,可能是错误的paintevent方法实现,python,qt,user-interface,pyqt,Python,Qt,User Interface,Pyqt,我和我的同事正在用python编写一个数据处理应用程序。 我们目前正在处理应用程序的前端部分 不过,我们有一个大问题,那就是应用程序在经过随机时间后会出现以下错误: QWidget::repaint: Recursive repaint detected 这一条也不时出现: QPainter::begin: Paint device returned engine == 0, type: 1 这是所有gui相关内容发生的文件,为了避免冗长,我删去了不相关的方法: gfx.py: import

我和我的同事正在用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

这“有效”,但我想是一般性的。。它实际上使错误的出现速度比没有条件的要快得多。

在您的gfx.py中,您有:

    self.repaint(self.map.contentsRect())
    self.update(self.map.contentsRect())
依次调用
repaint
update
是多余的。如果一个绘制事件通过该处理程序调用
repaint()
,则要求无限递归

记下文档中的任何警告注释

我看不出您的其他错误的原因,但它可能与QPainter在不应该使用时被使用有关


希望能有所帮助。

你提到的两行字确实是个错误。。他们有点意外地到达了那里,而不是在真正的应用程序中^^-好的,只有一个是,重新绘制。目前,我通过在句柄“needsrepaint”中设置一个布尔值来解决重新绘制问题,在重新绘制时,它会检查它是否为true,然后将“needsrepaint”设置为false。这消除了我的错误。。(我想这是由于重新粉刷太多造成的)