Search code examples
pythonqtpyqtqt4pyside

Is it possible to paint a QGraphicsItem inside the paint() method?


I'm creating a subclass of QGraphicsItem, and this subclass has different places that the user can click. My idea is for each component clicked to create a subclass of QGraphicsItem with mousePressEvent replaced. The problem is how can I merge this component into a subclass of QGraphicItem.

Here's the code I'm trying, but I do not know how to show all the components in the paint method.

# -*- coding: utf-8 -*-
from PySide import QtGui, QtCore

class GraphicItemMain(QtGui.QGraphicsItem):
    
    def __init__(self, x, y):
        super(GraphicItemMain, self).__init__()
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, False)
        self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
        self.setAcceptsHoverEvents(True)
        self.x = x
        self.y = y

    def boundingRect(self):
        return QtCore.QRectF(self.x, self.y, 100, 100)

    def paint(self, painter, option, widget):
        textComponent = GraphicItemTextClicked(5+self.x, 5+self.y)
        ellipseComponent = GraphicItemEllipseClicked(5+self.x, 50+self.y)
        # How do I print this components?

class GraphicItemTextClicked(QtGui.QGraphicsItem):
    
    def __init__(self, x, y):
        super(GraphicItemTextClicked, self).__init__()
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, False)
        self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
        self.setAcceptsHoverEvents(True)
        self.x = x
        self.y = y

    def mousePressEvent(self, event):
        #Do something
        QtGui.QGraphicsItem.mousePressEvent(self, event)

    def boundingRect(self):
        return QtCore.QRectF(self.x, self.y, 80, 30)

    def paint(self, painter, option, widget):
        painter.setPen(QtGui.QPen(QtGui.QColor(255, 0, 0), 1))
        font = QtGui.QFont()
        font.setPointSize(12)
        painter.setFont(font)
        painter.drawText(QtCore.QPointF(3+self.x, self.y), "Same Text")

class GraphicItemEllipseClicked(QtGui.QGraphicsItem):
    
    def __init__(self, x, y):
        super(GraphicItemEllipseClicked, self).__init__()
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, False)
        self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
        self.setAcceptsHoverEvents(True)
        self.x = x
        self.y = y

    def mousePressEvent(self, event):
        #Do other thing
        QtGui.QGraphicsItem.mousePressEvent(self, event)

    def boundingRect(self):
        return QtCore.QRectF(self.x, self.y, 25, 25)

    def paint(self, painter, option, widget):
        painter.setPen(QtGui.QPen(QtGui.QColor(0, 255, 0), 1))
        painter.drawEllipse(self.x, self.y, 25, 25)   
        

Solution

  • Thanks @SimonHibbs , the solution was to call textComponent.setParentItem(self) and ellipseComponent.setParentItem(self) on init method.

    Solution:

    from PySide import QtGui, QtCore
    
    class GraphicItemMain(QtGui.QGraphicsItem):
    
        def __init__(self, x, y):
            super(GraphicItemMain, self).__init__()
            self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
            self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, False)
            self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
            self.setAcceptsHoverEvents(True)
            self.x = x
            self.y = y
            textComponent = GraphicItemTextClicked(5+self.x, 5+self.y)
            textComponent.setParentItem(self)
            ellipseComponent = GraphicItemEllipseClicked(5+self.x, 50+self.y)
            ellipseComponent.setParentItem(self)
    
        def boundingRect(self):
            return QtCore.QRectF(self.x, self.y, 100, 100)
    
        def paint(self, painter, option, widget):
            # Paint samething
    
    class GraphicItemTextClicked(QtGui.QGraphicsItem):
    
        def __init__(self, x, y):
            super(GraphicItemTextClicked, self).__init__()
            self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
            self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, False)
            self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
            self.setAcceptsHoverEvents(True)
            self.x = x
            self.y = y
    
        def mousePressEvent(self, event):
            # Do something
            QtGui.QGraphicsItem.mousePressEvent(self, event)
    
        def boundingRect(self):
            return QtCore.QRectF(self.x, self.y, 80, 30)
    
        def paint(self, painter, option, widget):
            painter.setPen(QtGui.QPen(QtGui.QColor(255, 0, 0), 1))
            font = QtGui.QFont()
            font.setPointSize(12)
            painter.setFont(font)
            painter.drawText(QtCore.QPointF(3+self.x, self.y), "Same Text")
    
    class GraphicItemEllipseClicked(QtGui.QGraphicsItem):
    
        def __init__(self, x, y):
            super(GraphicItemEllipseClicked, self).__init__()
            self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
            self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, False)
            self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
            self.setAcceptsHoverEvents(True)
            self.x = x
            self.y = y
    
        def mousePressEvent(self, event):
            # Do other thing
            QtGui.QGraphicsItem.mousePressEvent(self, event)
    
        def boundingRect(self):
            return QtCore.QRectF(self.x, self.y, 25, 25)
    
        def paint(self, painter, option, widget):
            painter.setPen(QtGui.QPen(QtGui.QColor(0, 255, 0), 1))
            painter.drawEllipse(self.x, self.y, 25, 25)