I'm making a widget to access and modify QGraphicsRectItem properties(scale, rotation, etc.). The main idea is to show a widget on clicking on an item. When you click on another item, this widget should be deleted and replaced by another(showing properties of another item.)
I've implemented this using QFocusEvent and unfortunately, it gives me a SIGSEGV error. I fully understand why it happens but can`t make out how to do it in another way.
Here's a python sketch:
from PySide2 import QtWidgets, QtCore, QtGui
import sys, shiboken2
class graphicsView(QtWidgets.QGraphicsView):
def __init__(self, scene, parent=None):
super(graphicsView, self).__init__(parent)
self.scene = scene
self.setScene(self.scene)
def wheelEvent(self, event):
factor = 1.41 ** (-event.delta() / 240)
self.scale(factor, factor)
class boxItem(QtWidgets.QGraphicsRectItem):
def __init__(self, parent):
super(boxItem, self).__init__()
self.setFlags(QtWidgets.QGraphicsItem.ItemIsSelectable
| QtWidgets.QGraphicsItem.ItemIsMovable
| QtWidgets.QGraphicsItem.ItemIsFocusable)
self.rect = QtCore.QRectF(0, 0, 200, 200)
self.setRect(self.rect)
self.parent = parent
def focusInEvent(self, event:QtGui.QFocusEvent):
self.pBox = propBox()
self.parent.layout.addWidget(self.pBox)
self.pBox.r_box.setValue(self.rotation())
self.pBox.r_box.valueChanged.connect(self.setRotationAngle)
def focusOutEvent(self, event:QtGui.QFocusEvent):
# Here's a shiboken(equivalent to sip in PyQt) deletes c++ object and a python wrapper
# It works as expected but because of focusOutEvent it deletes the widget when i click on it
# There's when the error appears.
self.parent.layout.removeWidget(self.pBox)
shiboken2.delete(self.pBox)
def setRotationAngle(self, degrees):
br = self.boundingRect()
self.setTransformOriginPoint(QtCore.QPointF(br.width() / 2, br.height() / 2))
self.setRotation(-degrees)
self.update()
class propBox(QtWidgets.QWidget):
def __init__(self, parent=None):
super(propBox, self).__init__(parent)
self.layout = QtWidgets.QVBoxLayout()
self.layout.setAlignment(QtCore.Qt.AlignTop)
self.setLayout(self.layout)
self.r_label = QtWidgets.QLabel("Rotation:", self)
self.r_box = QtWidgets.QSpinBox(self)
self.r_layout = QtWidgets.QHBoxLayout()
self.r_layout.addWidget(self.r_label)
self.r_layout.addWidget(self.r_box)
self.s_label = QtWidgets.QLabel("Scale:")
self.s_box = QtWidgets.QSpinBox(self)
self.s_layout = QtWidgets.QHBoxLayout()
self.s_layout.addWidget(self.s_label)
self.s_layout.addWidget(self.s_box)
self.layout.addLayout(self.r_layout)
self.layout.addLayout(self.s_layout)
class mainWidget(QtWidgets.QWidget):
def __init__(self):
super(mainWidget, self).__init__()
self.layout = QtWidgets.QHBoxLayout()
self.setLayout(self.layout)
box1 = boxItem(self)
box1.setRotation(45)
box2 = boxItem(self)
self.scene = QtWidgets.QGraphicsScene(self)
self.scene.setSceneRect(0, 0, 500, 300)
self.scene.addItem(box1)
self.scene.addItem(box2)
self.view = graphicsView(self.scene)
self.pBox = propBox(self)
self.layout.addWidget(self.view)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = mainWidget()
window.show()
sys.exit(app.exec_())