Reputation: 312
I want to plot some data stored in a list of numpy arrays and be able to click on a plotted line. After clicking a line that line needs to be removed from my data and everything else cleared and redrawn.
Just removing the line from the plot pw.getPlotItem().removeItem(curve)
is not an option, sometimes I need to clear everything.
So the question is how to avoid the annoying RuntimeError: wrapped C/C++ object of type PlotCurveItem has been deleted
error? Here is the minimum example of what I am talking about.
# -*- coding: utf-8 -*-
from pyqtgraph.Qt import QtGui
import numpy as np
import pyqtgraph as pg
app = pg.mkQApp()
mw = QtGui.QMainWindow()
mw.resize(800, 800)
cw = QtGui.QWidget()
mw.setCentralWidget(cw)
l = QtGui.QVBoxLayout()
cw.setLayout(l)
pw = pg.PlotWidget()
l.addWidget(pw)
mw.show()
lines = [np.random.normal(size=5) for _ in range(5)]
curves_list = []
def clicked(curve):
idx = pw.getPlotItem().items.index(curve)
del lines[idx]
draw()
# this is not an option
# pw.getPlotItem().removeItem(curve)
def draw():
pw.clear()
curves_list.clear()
for line in lines:
curve = pw.plot(line)
curve.curve.setClickable(True)
curve.sigClicked.connect(clicked)
curves_list.append(curve)
draw()
if __name__ == '__main__':
QtGui.QApplication.instance().exec_()
Upvotes: 1
Views: 151
Reputation: 244202
The problem is synchronization since it seems that an instant after the deletion, another code is executed that uses the deleted items, therefore it launches that warning. The solution is to give it a little delay with QTimer.singleShot(0, ...)
:
from pyqtgraph.Qt import QtCore, QtGui
def clicked(curve):
def on_timeout():
curves_list.remove(curve)
pw.removeItem(curve)
draw()
QtCore.QTimer.singleShot(0, on_timeout)
Upvotes: 2