运行 pyqtgraph 第二次出现 RuntimeError

RuntimeError happens when running pyqtgraph second time

我定义了一个函数来使用 pyqtgraph 来切片数据。在关闭main window 并再次运行ning 函数时,我遇到了RuntimeError: wrapped C/C++ object of type ViewBox has been deleted。我的函数如下:

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]

我在 Jupyter 实验室中 运行 以下命令:

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

谁能告诉我如何解决这个问题?

问题是当使用 nonlocal 时,您正在创建一个额外的范围,因此关闭 window 处理某些项目的 python 对象不会被销毁,因为它们被认为是全局变量,所以在下一个执行它们被使用但 C++ 对象不再存在导致该错误。一种可能的解决方案是在不使用非本地的情况下实现逻辑,例如使用 类.

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]