ekdmekdm
ekdmekdm

Reputation: 167

Delete a selected QGraphicsPixmapItem in a scene

I'm trying to make a sort of image viewer in which I put a background image ("Affichage du mur" button) and then I load images with the "Importer l'oeuvre" button (you can load as many images you want). It works fine but I would like that we could delete the images ... in fact I would like the image that we delete is the image selected by the user. I can't get the selected image to be deleted with the "Suppression de l'oeuvre" button ... it seems that there is a selectedItems() method but I don't know how to use it in my code. Can you help me please ? Here is a very simplified code of what I am doing :

import os, sys

try : import Image
except ImportError : from PIL import Image

# Imports PyQt5 -----------------------------------------------------------------------
from PyQt5.QtWidgets import QPushButton, QGridLayout, QGraphicsScene, QGraphicsView, \
                            QGraphicsPixmapItem, QGraphicsItem, QApplication, \
                            QMainWindow, QFileDialog, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QColor, QTransform
# --------------------------------------------------------------------------------------


class TEST(QMainWindow):

    def __init__(self):
        super(TEST, self).__init__()
        
        self.setWindowTitle('TEST')
        
        self.setGeometry(10, 20, 1280, 760)
        self.setMinimumSize(1280, 760)

        # ----------------------------------------
        self.graphe_vue = MonGraphiqueVueMur()
        # ----------------------------------------
        
        bout_visio_mur = QPushButton("Affichage du mur")
        bout_visio_mur.setMaximumWidth(230)
        bout_visio_mur.setMinimumWidth(230)
        
        bout_visio_oeuvre = QPushButton("Importer l'oeuvre")
        bout_visio_oeuvre.setMaximumWidth(230)
        bout_visio_oeuvre.setMinimumWidth(230)
        
        bout_supprimer_oeuvre = QPushButton("Suppression de l'oeuvre")
        bout_supprimer_oeuvre.setMaximumWidth(230)
        bout_supprimer_oeuvre.setMinimumWidth(230)
        
        # ------------------------------------------------------------
        bout_visio_mur.clicked.connect(self.graphe_vue.afficher_mur)
        bout_visio_oeuvre.clicked.connect(self.graphe_vue.afficher_image_oeuvre)
        bout_supprimer_oeuvre.clicked.connect(self.graphe_vue.supprimer_image_oeuvre)
        # ------------------------------------------------------------

        grid = QGridLayout()

        grid.addWidget(self.graphe_vue, 0, 0)
        grid.addWidget(bout_visio_mur, 1, 0)
        grid.addWidget(bout_visio_oeuvre, 2, 0)
        grid.addWidget(bout_supprimer_oeuvre, 3, 0)
        
        widget = QWidget()
        widget.setLayout(grid)
        
        self.setCentralWidget(widget)

        
class MaScene(QGraphicsScene) :
    
    def __init__(self, parent=None) :
        super(MaScene, self).__init__(parent)
        
        
class MonGraphiquePixmapItemMur(QGraphicsPixmapItem) :
    
    def __init__(self, parent=None):
        super(MonGraphiquePixmapItemMur, self).__init__(parent)
        
        
class MonGraphiquePixmapItemOeuvre(QGraphicsPixmapItem) :
    
    def __init__(self, parent=None):
        super(MonGraphiquePixmapItemOeuvre, self).__init__(parent)

        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QGraphicsItem.ItemIsFocusable, True)
        
        self.setAcceptHoverEvents(True) 

    def hoverEnterEvent(self, event):
        print('setAcceptHoverEvents --> Position', event.pos(), type(event.pos()), type(event.pos().x()), type(event.pos().x()))
        print("Position X", event.pos().x(), "Position Y", event.pos().y())
        
        
class MonGraphiqueVueMur(QGraphicsView) :

    backgroundcolor = QColor(100, 100, 100)
    
    def __init__(self, parent=None) :
        super(MonGraphiqueVueMur, self).__init__(parent)

        self.setBackgroundBrush(self.backgroundcolor)

        self.scene  = MaScene()
        self.setScene(self.scene)


    def wheelEvent(self, event):

        zoomInFactor = 1.1
        zoomOutFactor = 1 / zoomInFactor
        
        self.setTransformationAnchor(QGraphicsView.NoAnchor)
        self.setResizeAnchor(QGraphicsView.NoAnchor)

        oldPos = self.mapToScene(event.pos())
    
        if event.angleDelta().y() > 0:
            zoomFactor = zoomInFactor
        else:
            zoomFactor = zoomOutFactor
        self.scale(zoomFactor, zoomFactor)
    
        newPos = self.mapToScene(event.pos())
    
        delta = newPos - oldPos
        self.translate(delta.x(), delta.y())
        
        
    def afficher_mur(self) :
        
        ouv = QFileDialog.getOpenFileName(self, 'Ouvrir une image', os.path.expanduser('~'), 'Images (*.jpg *.jpeg *.JPG *.JPEG *.png *.gif)')[0]
        chemin_fichier = str(ouv)
        
        img_mur = Image.open(chemin_fichier)

        self.scene.clear()
        self.items().clear()

        largeur, hauteur = img_mur.size

        pixmap = QPixmap(chemin_fichier)

        item = MonGraphiquePixmapItemMur(pixmap)

        item.setTransformationMode(Qt.SmoothTransformation)

        self.scene.addItem(item)

        self.setScene(self.scene)

        self.fitInView(item, Qt.KeepAspectRatio)

        x, y = 0, 0
        self.setSceneRect(-x, -y, largeur, hauteur)
        self.centerOn(10, 10)

        self.show()


    def afficher_image_oeuvre(self) :
        
        ouv = QFileDialog.getOpenFileName(self, 'Ouvrir une image', os.path.expanduser('~'), 'Images (*.jpg *.jpeg *.JPG *.JPEG *.png *.gif)')[0]
        chemin_fichier = str(ouv)

        pixmap = QPixmap(chemin_fichier)
        
        pixmap = pixmap.scaled(700, 700, Qt.KeepAspectRatio, Qt.SmoothTransformation)

        item = MonGraphiquePixmapItemOeuvre(pixmap)
        
        item.setTransformationMode(Qt.SmoothTransformation)

        item.setFlag(QGraphicsItem.ItemIsFocusable)

        self.scene.addItem(item)

        self.setScene(self.scene)
        
        ###################################################################################
        iteme = self.scene.selectedItems()
        print("iteme", iteme) # Return []
        ###################################################################################

        self.show()

 
    def supprimer_image_oeuvre(self) :
        
        import sip
        
        tous_items = list(self.scene.items())
        print("len(tous_items)", len(tous_items))
        print("tous_items", tous_items)

        for i in tous_items :
            if str(type(i)) != "<class '__main__.MonGraphiquePixmapItemMur'>" :
                self.scene.removeItem(tous_items[0])
                sip.delete(tous_items[0])

        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = TEST()
    ex.show()
    sys.exit(app.exec_())

Thanks in advance.

I'd have other questions to ask but we'll see that later.

Upvotes: 0

Views: 465

Answers (1)

musicamante
musicamante

Reputation: 48231

You just have to cycle through selectedItems(), there's absolutely no need to use the sip module, nor check the class using the string (which is not a good way to do so).

def supprimer_image_oeuvre(self) :
    for item in self.scene.selectedItems():
        self.scene.removeItem(item)

Upvotes: 1

Related Questions