CinnaKenToast
CinnaKenToast

Reputation: 1

How do I add a custom QGraphicsItem to my QGraphicsScene

I have this widget that I would like to add to my qgraphicsscene but it isn't working exactly how I want it to. I think the problem has to do with the parent of the widget. My goal is to be able to add the widget to the scene and move it freely.

I have this widget called twoPin that looks like this.

Custom Widget

And here is the code that I had generated from QtDesigner and updated.

class Ui_Form(QtWidgets.QGraphicsItem):
    def __init__(self, Form):
        super().__init__()
        Form.setObjectName("Form")
        Form.resize(150, 95)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
        Form.setSizePolicy(sizePolicy)
        Form.setMinimumSize(QtCore.QSize(150, 95))
        Form.setMaximumSize(QtCore.QSize(168, 16777215))
        self.label_name = QtWidgets.QLabel(Form)
        self.label_name.setGeometry(QtCore.QRect(0, 0, 150, 20))
        self.label_name.setMinimumSize(QtCore.QSize(0, 20))
        self.label_name.setMaximumSize(QtCore.QSize(16777215, 20))
        self.label_name.setAlignment(QtCore.Qt.AlignCenter)
        self.label_name.setObjectName("label_name")
        self.frame = QtWidgets.QFrame(Form)
        self.frame.setGeometry(QtCore.QRect(0, 20, 150, 75))
        self.frame.setMinimumSize(QtCore.QSize(150, 50))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.lable_image = QtWidgets.QLabel(self.frame)
        self.lable_image.setGeometry(QtCore.QRect(0, 0, 150, 75))
        self.lable_image.setText("")
        self.lable_image.setScaledContents(True)
        self.lable_image.setObjectName("lable_image")
        self.btn_pin0 = QtWidgets.QPushButton(self.frame)
        self.btn_pin0.setGeometry(QtCore.QRect(0, 0, 75, 75))
        self.btn_pin0.setStyleSheet("")
        self.btn_pin0.setText("")
        self.btn_pin0.setObjectName("btn_pin0")
        self.btn_pin1 = QtWidgets.QPushButton(self.frame)
        self.btn_pin1.setGeometry(QtCore.QRect(75, 0, 75, 75))
        self.btn_pin1.setStyleSheet("")
        self.btn_pin1.setText("")
        self.btn_pin1.setObjectName("btn_pin1")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

        self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label_name.setText(_translate("Form", "Component Name"))

    def boundingRect(self):
        return QtCore.QRectF(0, 0, 150, 95)

    def paint(self, painter, options, widget):
        painter.drawRect(0, 0, 150, 95)

I have my main window that consists of a qgraphicsview and qgraphicsscene and I want to add my custom widget to it. When I try to add the widget, I don't know which component to make its parent. If I try to make the graphicsview the parent, I can see the boundingbox in the scene but the widget itself is stuck to the top corner of the window without being able to move it. Here is the code and an image to show.

Main Window

from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import (QCoreApplication, QPropertyAnimation, QDate, QDateTime, QMetaObject, QObject, QPoint, QRect, QSize, QTime, QUrl, Qt, QEvent)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont, QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter, QPixmap, QRadialGradient)
from PySide2.QtWidgets import *

import twoPin

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        self.scene = QtWidgets.QGraphicsScene()
        self.scene.setSceneRect(QtCore.QRectF(0.0, 0.0, 5000.0, 5000.0))
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.graphicsView = QtWidgets.QGraphicsView(self.scene, self.centralwidget)
        self.graphicsView.setObjectName("graphicsView")
        self.verticalLayout.addWidget(self.graphicsView)
        MainWindow.setCentralWidget(self.centralwidget)

        redBrush = QtGui.QBrush(QtCore.Qt.red)
        blackPen = QtGui.QPen(QtCore.Qt.black)
        blackPen.setWidth(4)

        ellipse = self.scene.addEllipse(2300, 2300, 200, 200, blackPen, redBrush)
        ellipse.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
        ellipse.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable)
        ellipse.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable)

        self.form = QtWidgets.QWidget(self.graphicsView)
        self.widget = twoPin.Ui_Form(self.form)
        self.form.setGeometry(QtCore.QRect(0, 0, 150, 95))
        self.scene.addItem(self.widget)
        self.widget.moveBy(2500, 2500)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Upvotes: 0

Views: 979

Answers (1)

eyllanesc
eyllanesc

Reputation: 244291

You should not modify the code generated by Qt Designer, for more information read QtDesigner changes will be lost after redesign User Interface.

So you have to restore both files and the second file I will assume is called main_ui.py. As I point out in the other post, you must create classes that inherit from the appropriate widgets. And finally you must add the widget using the addWidget() method of the scene.

from PySide2 import QtCore, QtGui, QtWidgets

from twoPin import Ui_Form
from main_ui import Ui_MainWindow


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.scene = QtWidgets.QGraphicsScene()

        self.ui.graphicsView.setScene(self.scene)

        self.scene.setSceneRect(QtCore.QRectF(0.0, 0.0, 5000.0, 5000.0))

        redBrush = QtGui.QBrush(QtCore.Qt.red)
        blackPen = QtGui.QPen(QtCore.Qt.black)
        blackPen.setWidth(4)

        ellipse = self.scene.addEllipse(2300, 2300, 200, 200, blackPen, redBrush)
        ellipse.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
        ellipse.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable)
        ellipse.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable)

        self.scene.addWidget(Widget())


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Upvotes: 1

Related Questions