[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: [PyQt] CPU spin and an error when using QQuickPaintedItem
From:       Russell Warren <russ () perspexis ! com>
Date:       2016-11-21 16:30:45
Message-ID: CAD91c14sgQ=cN6FS6PtMDxxYhyPo5Y585HDxumRwrmOObw8ZZQ () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


As a small follow-up, the same exact CPU spinning problem (and the
presumably related QObject::killTimer message) also happen when run on
Windows with python 3.5.2 (Anaconda 4.1.1 64-bit) with the PyQt 5.7.0 wheel.


On Sat, Nov 19, 2016 at 7:32 PM, Russell Warren <russ@perspexis.com> wrote:

> Sorry... This is on 64 bit Linux with the latest version from pypi at this
> moment.
>
> On Nov 19, 2016 6:31 PM, "Russell Warren" <russ@perspexis.com> wrote:
>
>> 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_())
>>
>>
>>
>>


-- 
Russell Warren
Perspexis Technologies Inc.

This information is confidential and intended solely for the use of the
individual or entity to whom it is addressed.
If you have received this email in error, please notify the sender
immediately.

[Attachment #5 (text/html)]

<div dir="ltr">As a small follow-up, the same exact CPU spinning problem (and the \
presumably related QObject::killTimer message) also happen when run on Windows with \
python 3.5.2 (Anaconda 4.1.1 64-bit) with the PyQt 5.7.0 \
wheel.<div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On \
Sat, Nov 19, 2016 at 7:32 PM, Russell Warren <span dir="ltr">&lt;<a \
href="mailto:russ@perspexis.com" target="_blank">russ@perspexis.com</a>&gt;</span> \
wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px \
#ccc solid;padding-left:1ex"><p dir="ltr">Sorry... This is on 64 bit Linux with the \
latest version from pypi at this moment.</p><div class="HOEnZb"><div class="h5"> <div \
class="gmail_extra"><br><div class="gmail_quote">On Nov 19, 2016 6:31 PM, \
&quot;Russell Warren&quot; &lt;<a href="mailto:russ@perspexis.com" \
target="_blank">russ@perspexis.com</a>&gt; wrote:<br type="attribution"><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"><div dir="ltr"><div>I&#39;m having a CPU-spinning problem, \
together with an odd QObject::killTimer error, with a basic use case of \
QQuickPaintedItem.</div><div><br></div><div>I&#39;ve reduced the example down so that \
the meat of it is just this:</div><div><br></div><div>1. Create a QGraphicsScene with \
some QGraphicsItems in it</div><div>2. Create a QQuickPaintedItem to render the scene \
to QML</div><div>3. Call QGraphicsScene.render(painter) inside the .paint of \
QQuickPaintedItem</div><div><br></div><div>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:</div><div><br></div><div><a href="https://i.snag.gy/I6QZvH.jpg" \
target="_blank">https://i.snag.gy/I6QZvH.jpg</a></div><div><br></div><div>The FDs \
being polled are a socket and an &#39;anon_inode:[eventfd]&#39;, which is (I think) \
the normal Qt event loop.</div><div><br></div><div>The error that results is \
this:</div><div><br></div><div>      $ python HeatMapProblem.py</div><div>      \
QObject::killTimer: Timers cannot be stopped from another \
thread</div><div><br></div><div>This timer problem is probably related, because the \
spinning is likely what would happen with a zero timeout \
timer.</div><div><br></div><div>Everything *seems* like it is being done correctly \
from the Qt side of things. Is there something wrong I&#39;m doing with \
PyQt?</div><div><br></div><div>Basic code below (two files... heatmap.qml and \
HeatMapProblem.py).</div><div><br></div><div>Thanks,</div><div>Russ</div><div><br></div><div><font \
face="monospace, monospace">#####</font></div><div><font face="monospace, \
monospace">### heatmap.qml</font></div><div><font face="monospace, \
monospace">#####</font></div><div><font face="monospace, \
monospace"><br></font></div><div><font face="monospace, monospace">import QtQuick \
2.0</font></div><div><font face="monospace, monospace">import QtQuick.Window \
2.2</font></div><div><font face="monospace, monospace">import Heatmap \
1.0</font></div><div><font face="monospace, monospace"><br></font></div><div><font \
face="monospace, monospace">Window {</font></div><div><font face="monospace, \
monospace">      visible: true</font></div><div><font face="monospace, monospace">    \
width: 500</font></div><div><font face="monospace, monospace">      height: \
500</font></div><div><font face="monospace, monospace">      MyHeatmap \
{</font></div><div><font face="monospace, monospace">            anchors.fill: \
parent</font></div><div><font face="monospace, monospace">      \
}</font></div><div><font face="monospace, monospace">}</font></div><div><font \
face="monospace, monospace"><br></font></div><div><font face="monospace, \
monospace">#####</font></div><div><font face="monospace, monospace">### \
HeatMapProblem.py</font></div><div><font face="monospace, \
monospace">#####</font></div><div><font face="monospace, monospace">#!/usr/bin/env \
python</font></div><div><font face="monospace, monospace">import \
random</font></div><div><font face="monospace, monospace"><br></font></div><div><font \
face="monospace, monospace">from OpenGL import GL    # workaround for Nvidia issue on \
linux (see <a href="http://goo.gl/pGPgVz" \
target="_blank">http://goo.gl/pGPgVz</a>)</font></div><div><font face="monospace, \
monospace">import PyQt5.QtWidgets as QtWidgets</font></div><div><font \
face="monospace, monospace">from PyQt5.QtQuick import QQuickItem, QQuickPaintedItem, \
QQuickView</font></div><div><font face="monospace, monospace">import PyQt5.QtCore as \
QtCore</font></div><div><font face="monospace, monospace">import PyQt5.QtGui as \
QtGui</font></div><div><font face="monospace, monospace">import PyQt5.QtQml as \
QtQml</font></div><div><font face="monospace, monospace"><br></font></div><div><font \
face="monospace, monospace">class \
MyPolygon(QtWidgets.QGraphicsP<wbr>olygonItem):</font></div><div><font \
face="monospace, monospace">      def __init__(self, PolyPoints, parent = \
None):</font></div><div><font face="monospace, monospace">            \
super(MyPolygon, self).__init__(PolyPoints, parent)</font></div><div><font \
face="monospace, monospace">            color = QtGui.QColor(*(random.randint(<wbr>0, \
128) for x in range(3)))</font></div><div><font face="monospace, monospace">          \
self.setBrush(QtGui.QBrush(col<wbr>or))</font></div><div><font face="monospace, \
monospace">       </font></div><div><font face="monospace, monospace">class \
MyScene(QtWidgets.QGraphicsSce<wbr>ne):</font></div><div><font face="monospace, \
monospace">      def __init__(self, parent=None):</font></div><div><font \
face="monospace, monospace">            super(MyScene, \
self).__init__(parent)</font></div><div><font face="monospace, monospace">            \
blackPen = QtGui.QPen(QtCore.Qt.black, 1)</font></div><div><font face="monospace, \
monospace">            blackPen.setCosmetic(True)</font></div><div><font \
face="monospace, monospace">             </font></div><div><font face="monospace, \
monospace">            numWide = numHigh = 3</font></div><div><font face="monospace, \
monospace">            boxes = []</font></div><div><font face="monospace, monospace"> \
for x in range(numWide):</font></div><div><font face="monospace, monospace">          \
for y in range(numHigh):</font></div><div><font face="monospace, monospace">          \
bl = (x*10,         y*10)</font></div><div><font face="monospace, monospace">         \
tl = (x*10       , y*10 + 10)</font></div><div><font face="monospace, monospace">     \
tr = (x*10 + 10, y*10 + 10)</font></div><div><font face="monospace, monospace">       \
br = (x*10 + 10, y*10)</font></div><div><font face="monospace, monospace">            \
polyDef = [bl, tl, tr, br, bl]</font></div><div><font face="monospace, monospace">    \
poly = QtGui.QPolygonF([QtCore.QPoint<wbr>F(x, y) for (x, y) in \
polyDef])</font></div><div><font face="monospace, monospace">                        \
item = MyPolygon(poly, parent = None)</font></div><div><font face="monospace, \
monospace">                        item.setPen(blackPen) #polygon \
border</font></div><div><font face="monospace, monospace">                        \
self.addItem(item)</font></div><div><font face="monospace, \
monospace"><br></font></div><div><font face="monospace, monospace">class \
MyQMLScene(QQuickPaintedItem):</font></div><div><font face="monospace, monospace">    \
def __init__(self, parent = None):</font></div><div><font face="monospace, \
monospace">            super(MyQMLScene, \
self).__init__(parent)</font></div><div><font face="monospace, monospace">            \
self._Scene = MyScene(parent = self)</font></div><div><font face="monospace, \
monospace">             </font></div><div><font face="monospace, monospace">      def \
paint(self, painter):</font></div><div><font face="monospace, monospace">            \
self._Scene.render(painter)   # NOTE: comment this out and no problems \
exist!</font></div><div><font face="monospace, monospace">            \
pass</font></div><div><font face="monospace, monospace"><br></font></div><div><font \
face="monospace, monospace">if __name__ == &#39;__main__&#39;:</font></div><div><font \
face="monospace, monospace">      import sys</font></div><div><font face="monospace, \
monospace">      app = QtWidgets.QApplication(sys.arg<wbr>v)</font></div><div><font \
face="monospace, monospace">      QtQml.qmlRegisterType(MyQMLSce<wbr>ne, \
&quot;Heatmap&quot;, 1, 0, &quot;MyHeatmap&quot;)</font></div><div><font \
face="monospace, monospace">      engine = \
QtQml.QQmlApplicationEngine()</font></div><div><font face="monospace, monospace">     \
engine.load(&quot;heatmap.qml&quot;)</font></div><div><font face="monospace, \
monospace">      sys.exit(app.exec_())</font></div><div><font face="monospace, \
monospace"><br></font></div><div><br></div><div><br></div> </div>
</blockquote></div></div>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div \
class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><font \
color="#000099">Russell Warren</font></div><div><font color="#000099">Perspexis \
Technologies Inc.</font></div><div><font color="#000099"><br></font></div><div><font \
color="#000099">This information is confidential and intended solely for the use of \
the individual or entity to whom it is addressed.</font></div><div><span \
style="color:rgb(0,0,153)">If you have received this email in error, please notify \
the sender immediately.</span></div></div></div> </div>


[Attachment #6 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
https://www.riverbankcomputing.com/mailman/listinfo/pyqt

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic