Search code examples
pythonpyqt5qgraphicsviewqgraphicssceneqgraphicstextitem

Removing QGraphicsSimpleTextItem from QGraphicsView's Scene not working


As part of my pet project, I would need to add & remove text from QGraphicsScene. However for some reason I am unable to remove QGraphicsSimpleTextItems in the same manner as one would remove polygons, namely creating them with a pointer, and using scene.removeItem(item_name).

Please find a minimum reproducible example below to replicate the problem that I'm having with removing QGraphicsSimpleTextItems from the screen.

Where am I going wrong? Thanks!

import sys

from PyQt5.QtGui import QBrush,QPen,QColor
from PyQt5.QtWidgets import QApplication, QGraphicsScene, QGraphicsView, QGraphicsSimpleTextItem



def main():
    app = QApplication(sys.argv)

    items = {}
    colors_rgb = [[8, 247, 254], [254, 83, 187], [255, 170, 1], [86, 10, 134], [117, 213, 253],
                  [255, 34, 129], [128, 255, 0], [2, 184, 166]]

    positions_ = [[100,200],[10,200],[120,503],[150,400],[300,150],[150,230],[530,20],[400,200]]
    text_ =["textitem_1","textitem_2","textitem_3","textitem_4","textitem_5","textitem_6","textitem_7","textitem_8"]
    scene = QGraphicsScene()
    view = QGraphicsView(scene)
    for i in range(len(text_)):
        txt_ = QGraphicsSimpleTextItem(text_[i])
        txt_.setPos(positions_[i][0],positions_[i][1])
        txt_.setPen(QPen(QColor(0,0,0)))
        txt_.setBrush(QBrush(QColor(colors_rgb[i][0],colors_rgb[i][1],colors_rgb[i][2])))
        items[i] = scene.addItem(txt_)
        scene.removeItem(items[i])


    view.resize(640, 480)
    view.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Edit

I found that if add the QGraphicsSimpleTextItem itself to dictionary, instead of using a pointer, I am able to remove the items without a problem. Why is this the case?

    for i in range(len(text_)):
    txt_ = QGraphicsSimpleTextItem(text_[i])
    txt_.setPos(positions_[i][0],positions_[i][1])
    txt_.setPen(QPen(QColor(0,0,0)))
    txt_.setBrush(QBrush(QColor(colors_rgb[i][0],colors_rgb[i][1],colors_rgb[i][2])))
    scene.addItem(txt_)
    items[i] = txt_


for i in range(len(text_)):
    scene.removeItem(items.get(i))

Solution

  • Only the basic shape add*() functions return an item (addRect(), addLine(), etc), since they are used to create new items.

    addItem() adds an existing item, and it returns None (there's no point in returning an object that is the argument of the function), then the problem is here (I added a print statement to show the result):

    items[i] = scene.addItem(txt_)
    print(items[i])
    

    As you can see, you're actually adding None as dictionary values, and then trying to remove nothing from the scene, so the items actually remain on the scene.

    You need to add the item to the dictionary, as you did in your second example.