PyQt5: обернутый объект c / c ++ был удален - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь создать свой собственный графический элемент с кружком и надписью в центре.

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)

Теперь в моем основном gui список кругов хранится как circleList, и я пытаясь добавить элемент круга как

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

, но это возвращает

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

help?

это должно помочь при минимальном воспроизводимом примере

примечание: 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_())

1 Ответ

1 голос
/ 17 февраля 2020

Graphics View Framework не требует удаления и добавления элементов. В вашем случае при использовании clear () вы удаляете элементы со сцены и удаляете их из памяти, поэтому у circleList будут переменные, которые больше не выделяют память.

С другой стороны, если вам нужен пользовательский QGraphicsItem, в котором dr aws кружок и текст в центре, тогда у 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())
...