我和我的同事正在用 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
这“有效”,但我想一般来说......它实际上使错误看起来比没有条件的情况要快得多。