[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

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:


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).


### 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
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)))

class MyScene(QtWidgets.QGraphicsScene):
    def __init__(self, parent=None):
        super(MyScene, self).__init__(parent)
        blackPen = QtGui.QPen(QtCore.Qt.black, 1)

        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
                item = MyPolygon(poly, parent = None)
                item.setPen(blackPen) #polygon border

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!

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    QtQml.qmlRegisterType(MyQMLScene, "Heatmap", 1, 0, "MyHeatmap")
    engine = QtQml.QQmlApplicationEngine()
-------------- 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