PyQt5:包装的 c/c++ 对象已被删除

PyQt5 : Wrapped c/c++ object has been deleted

我正在尝试创建我自己的带有圆圈及其中心标签的图形项。

class circle(QGraphicsItem):
    def __init__(self, radius=None, name=None, x=None, y=None, parent=None):
        super(circle, self).__init__(parent)
        self.radius = radius if radius else random.random()*500
        self.label = name if name else "cirA"
        self.x = x if x else random.randint(0, 900)
        self.y = y if y else random.randint(0, 600)
        # self.center = complex(self.x, self.y)

    def boundingRect(self):
        penWidth = 1.0
        return QRectF(-self.x - penWidth / 2, -self.y - penWidth / 2,
                      self.x + penWidth, self.y + penWidth)

    def paint(self, painter, option, widget):
        painter.drawEllipse(0, 0, self.radius, self.radius)
        painter.drawText(self.label)

现在在我的主图形用户界面中,一个圈子列表保存为 circleList,我正在尝试将圈子项添加为

for cir in self.circleList:
            self.painter.addItem(cir)

但是这个returns

RuntimeError: wrapped C/C++ object of type circle has been deleted

帮助?

这应该可以解决最小可重现示例

注意:需要 FBS,项目应使用

启动
fbs startproject

圆圈也将与以下内容一起添加

from fbs_runtime.application_context.PyQt5 import ApplicationContext
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class gui(QDialog):
    def __init__(self, parent=None):
        super(gui, self).__init__(parent)
        self.painter = QGraphicsScene(10, 10, 900, 600)
        self.canvas = QGraphicsView(self.painter)
        mainLayout = QGridLayout()
        mainLayout.addWidget(self.canvas, 0, 0, 6, 2)
        self.setLayout(mainLayout)
        self.circleList = []

    def drawCircle(self):
        pen = QPen(Qt.black, 2, Qt.SolidLine)
        self.painter.clear()
        for cir in self.circleList:
            self.painter.addItem(cir)
        self.painter.update()
        self.canvas.update()
        self.update()

    def newCircle(self, cir):
        self.circleList.append(cir)
        self.drawCircle()

    def addCircle(self):
        return self.newCircle(circle())

if __name__ == "__main__":
    app = ApplicationContext()
    test = gui()
    test.show()
    exit(app.app.exec_())

Graphics View Framework 不需要您删除和添加项目。在你的例子中,当使用 clear() 时,你正在从场景中删除项目并将它们从内存中删除,因此 circleList 将具有不再分配内存的变量。

另一方面,如果您想要一个自定义的 QGraphicsItem,它在中心绘制一个圆和一个文本,那么 boundingRect 的大小必须与圆内切的矩形相同。

综合以上,解决方案如下:

class Circle(QGraphicsItem):
    def __init__(self, radius=None, name="", x=0, y=0, parent=None):
        super(Circle, self).__init__(parent)
        self.radius = radius or random.random() * 500
        self.label = name if name else "cirA"
        self.setPos(x or random.randint(0, 900), y or random.randint(0, 900))

    def boundingRect(self):
        return QRectF(0, 0, self.radius, self.radius)

    def paint(self, painter, option, widget):
        painter.drawEllipse(0, 0, self.radius, self.radius)
        painter.drawText(0, 0, self.radius, self.radius, Qt.AlignCenter, self.label)
class Gui(QDialog):
    def __init__(self, parent=None):
        super(Gui, self).__init__(parent)
        self.painter = QGraphicsScene(10, 10, 900, 600)
        self.canvas = QGraphicsView(self.painter)
        mainLayout = QGridLayout(self)
        mainLayout.addWidget(self.canvas)

    @property
    def circleList(self):
        return [item for item in self.painter.items() if isinstance(item, Circle)]

    def newCircle(self, cir):
        self.painter.addItem(cir)
        return cir

    def addCircle(self):
        return self.newCircle(Circle())