Internal C++ object (PlotCurveItem) already deleted after several runs

374 views
Skip to first unread message

Daniel Thiem

unread,
Mar 26, 2020, 10:56:32 AM3/26/20
to pyqtgraph
Hi,

I am running a plot in an Application where I add data regularly. After a certain time I get the following error:

Traceback (most recent call last):
 
File "D:\Programs\Miniconda3\envs\FreezingQtApp\lib\site-packages\pyqtgraph\graphicsItems\ViewBox\ViewBox.py", line 75, in boundingRect
   
return self.mapRectFromParent(self.parentItem().boundingRect())
RuntimeError: Internal C++ object (ChildGroup) already deleted.
Traceback (most recent call last):
 
File "C:/Users/xxxx/.PyCharm2019.2/config/scratches/scratch.py", line 27, in run
   
self.plotdata.setData(data)
 
File "D:\Programs\Miniconda3\envs\FreezingQtApp\lib\site-packages\pyqtgraph\graphicsItems\PlotDataItem.py", line 466, in setData
   
self.updateItems()
 
File "D:\Programs\Miniconda3\envs\FreezingQtApp\lib\site-packages\pyqtgraph\graphicsItems\PlotDataItem.py", line 492, in updateItems
   
self.curve.setData(x=x, y=y, **curveArgs)
 
File "D:\Programs\Miniconda3\envs\FreezingQtApp\lib\site-packages\pyqtgraph\graphicsItems\PlotCurveItem.py", line 335, in setData
   
self.updateData(*args, **kargs)
 
File "D:\Programs\Miniconda3\envs\FreezingQtApp\lib\site-packages\pyqtgraph\graphicsItems\PlotCurveItem.py", line 369, in updateData
   
self.prepareGeometryChange()
RuntimeError: Internal C++ object (PlotCurveItem) already deleted.

I've broken the code down to the minimal example:

import sys
import time
from PySide2 import QtGui, QtCore

import pyqtgraph as pg
import numpy as np

from PySide2.QtCore import QThread



app
= QtGui.QApplication([])
w
= pg.PlotWidget()

class Worker(QThread):

   
def __init__(self, plotdata: pg.PlotDataItem):
       
QThread.__init__(self)
       
self.plotdata = plotdata
       
self.raw_data = []

   
def run(self):
       
for i in range(1, 10001):
            newdata
= np.random.normal(loc=10,scale=2)
           
self.raw_data.append((time.time(),newdata))
            data
= np.array(self.raw_data)
           
self.plotdata.setData(data)
            time
.sleep(0.01)

plotdata
= w.plot(x=[],y=[])
w
.show()

worker
= Worker(plotdata)
worker
.start()


sys
.exit(app.exec_())

I just don't know where I could have released an object that is now being deleted by the gc.

Kenneth Lyons

unread,
Mar 26, 2020, 11:00:41 PM3/26/20
to pyqtgraph
I'm not certain, but I believe you're running into this: https://doc.qt.io/qt-5/threads-qobject.html#qobject-reentrancy

The following is a minor change from the code you have and it should work. Instead of updating the PlotDataItem directly from the thread, emit a signal from the thread and connect it to the PlotDataItem.setData method. That would then run on the main thread so the object is kept alive.

import sys
import time
from PySide2 import QtGui, QtCore

import pyqtgraph as pg
import numpy as np

from PySide2.QtCore import QThread

app
= QtGui.QApplication([])
w
= pg.PlotWidget()

class Worker(QThread):


    sigUpdated
= QtCore.Signal(object)


   
def __init__(self, plotdata: pg.PlotDataItem):
       
QThread.__init__(self)
       
self.plotdata =
plotdata
       
self.sigUpdated.connect(self.plotdata.setData)

       
self.raw_data = []

   
def run(self):
       
for i in range(1, 10001):
            newdata
= np.random.normal(loc=10,scale=2)
           
self.raw_data.append((time.time(),newdata))
            data
= np.array(self.raw_data)

           
self.sigUpdated.emit(data)

            time
.sleep(0.01)

plotdata
= w.plot(x=[],y=[])
w
.show()

worker
= Worker(plotdata)
worker
.start()


sys
.exit(app.exec_())
Reply all
Reply to author
Forward
0 new messages