shz
shz

Reputation: 159

RuntimeError happens when running pyqtgraph second time

I defined a function to use pyqtgraph to slicing data. When closing the main window and running the function again, I encountered a RuntimeError: wrapped C/C++ object of type ViewBox has been deleted. My function is as follows:

import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
def dp_select(dp):
    app = pg.mkQApp("NBED selection")
    ## Create window with two ImageView widgets
    win = QtGui.QMainWindow()
    win.resize(800, 300)
    # win.setWindowTitle('pyqtgraph example: DataSlicing')
    cw = QtGui.QWidget()
    win.setCentralWidget(cw)
    l = QtGui.QGridLayout()
    cw.setLayout(l)
    imv1 = pg.ImageView()
    imv2 = pg.ImageView()
    l.addWidget(imv1, 0, 0)
    l.addWidget(imv2, 0, 1)
    win.show()
    roi = pg.RectROI(pos=[5, 5], size=[10, 10], pen='r')
    # roi = pg.LineSegmentROI([[10, 64], [120,64]], pen='r')
    imv1.addItem(roi)
    def update():
        nonlocal dp, imv1, imv2
        d2 = roi.getArrayRegion(dp, imv1.imageItem, axis=(0, 1))
        imv2.setImage(d2)
    roi.sigRegionChanged.connect(update)
    ## Display the data
    imv1.setImage(dp)
    pg.mkQApp().exec_()
    app.closeAllWindows()
    y0, x0 = [int(i) for i in roi.pos()]
    dy, dx = [int(i) for i in roi.size()]
    y1 = y0 + dy
    x1 = x0 + dx
    return dp[y0:y1, x0:x1]

I run the following command in Jupyter lab:

data = np.random.rand(50, 50)
dp = dp_select(data)

Could anyone tell me how to solve the problem?

Upvotes: 1

Views: 133

Answers (1)

eyllanesc
eyllanesc

Reputation: 244202

The problem is that when using nonlocal you are creating an additional scope so closing the window the python object that handles some items are not destroyed since they are considered global variables so in a next execution they are used but the C++ objects no longer exist causing that error. A possible solution is to implement the logic without using nonlocal such as using classes.

import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg


class MainWindow(QtGui.QMainWindow):
    def __init__(self, dp, parent=None):
        super().__init__(parent)

        self.dp = dp

        self.resize(800, 300)
        cw = QtGui.QWidget()
        self.setCentralWidget(cw)
        l = QtGui.QGridLayout(cw)

        self.imv1 = pg.ImageView()
        self.imv2 = pg.ImageView()

        l.addWidget(self.imv1, 0, 0)
        l.addWidget(self.imv2, 0, 1)

        self.roi = pg.RectROI(pos=[5, 5], size=[10, 10], pen="r")
        self.imv1.addItem(self.roi)
        self.roi.sigRegionChanged.connect(self.handle_regionChanged)

        self.imv1.setImage(self.dp)

    def handle_regionChanged(self):
        d2 = self.roi.getArrayRegion(self.dp, self.imv1.imageItem, axis=(0, 1))
        self.imv2.setImage(d2)


def dp_select(dp):
    app = pg.mkQApp("NBED selection")
    ## Create window with two ImageView widgets
    win = MainWindow(dp)
    win.show()
    pg.mkQApp().exec_()
    app.closeAllWindows()
    roi = win.roi
    y0, x0 = [int(i) for i in roi.pos()]
    dy, dx = [int(i) for i in roi.size()]
    y1 = y0 + dy
    x1 = x0 + dx
    return dp[y0:y1, x0:x1]

Upvotes: 1

Related Questions