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 メソッドで間違っていることは何ですか?

2番目の質問 発生するすべてのランダムなことでペイントイベントが呼び出されないようにする方法はありますか? (マウスオーバーなど)?

私は次のようなものを試しました:

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 に答える