[PyQt] CPU spin and an error when using QQuickPaintedItem
Russell Warren
russ at perspexis.com
Sat Nov 19 23:31:57 GMT 2016
I'm having a CPU-spinning problem, together with an odd QObject::killTimer
error, with a basic use case of QQuickPaintedItem.
I've reduced the example down so that the meat of it is just this:
1. Create a QGraphicsScene with some QGraphicsItems in it
2. Create a QQuickPaintedItem to render the scene to QML
3. Call QGraphicsScene.render(painter) inside the .paint of
QQuickPaintedItem
When I do this, it superficially works as I want, but I get an error to
stdout, and the CPU spins to 100%. Using strace it can be seen that the CPU
is spinning on a poll(), like seen in this capture:
https://i.snag.gy/I6QZvH.jpg
The FDs being polled are a socket and an 'anon_inode:[eventfd]', which is
(I think) the normal Qt event loop.
The error that results is this:
$ python HeatMapProblem.py
QObject::killTimer: Timers cannot be stopped from another thread
This timer problem is probably related, because the spinning is likely what
would happen with a zero timeout timer.
Everything *seems* like it is being done correctly from the Qt side of
things. Is there something wrong I'm doing with PyQt?
Basic code below (two files... heatmap.qml and HeatMapProblem.py).
Thanks,
Russ
#####
### heatmap.qml
#####
import QtQuick 2.0
import QtQuick.Window 2.2
import Heatmap 1.0
Window {
visible: true
width: 500
height: 500
MyHeatmap {
anchors.fill: parent
}
}
#####
### HeatMapProblem.py
#####
#!/usr/bin/env python
import random
from OpenGL import GL # workaround for Nvidia issue on linux (see
http://goo.gl/pGPgVz)
import PyQt5.QtWidgets as QtWidgets
from PyQt5.QtQuick import QQuickItem, QQuickPaintedItem, QQuickView
import PyQt5.QtCore as QtCore
import PyQt5.QtGui as QtGui
import PyQt5.QtQml as QtQml
class MyPolygon(QtWidgets.QGraphicsPolygonItem):
def __init__(self, PolyPoints, parent = None):
super(MyPolygon, self).__init__(PolyPoints, parent)
color = QtGui.QColor(*(random.randint(0, 128) for x in range(3)))
self.setBrush(QtGui.QBrush(color))
class MyScene(QtWidgets.QGraphicsScene):
def __init__(self, parent=None):
super(MyScene, self).__init__(parent)
blackPen = QtGui.QPen(QtCore.Qt.black, 1)
blackPen.setCosmetic(True)
numWide = numHigh = 3
boxes = []
for x in range(numWide):
for y in range(numHigh):
bl = (x*10, y*10)
tl = (x*10 , y*10 + 10)
tr = (x*10 + 10, y*10 + 10)
br = (x*10 + 10, y*10)
polyDef = [bl, tl, tr, br, bl]
poly = QtGui.QPolygonF([QtCore.QPointF(x, y) for (x, y) in
polyDef])
item = MyPolygon(poly, parent = None)
item.setPen(blackPen) #polygon border
self.addItem(item)
class MyQMLScene(QQuickPaintedItem):
def __init__(self, parent = None):
super(MyQMLScene, self).__init__(parent)
self._Scene = MyScene(parent = self)
def paint(self, painter):
self._Scene.render(painter) # NOTE: comment this out and no
problems exist!
pass
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
QtQml.qmlRegisterType(MyQMLScene, "Heatmap", 1, 0, "MyHeatmap")
engine = QtQml.QQmlApplicationEngine()
engine.load("heatmap.qml")
sys.exit(app.exec_())
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20161119/d67d0138/attachment.html>
More information about the PyQt
mailing list