Search code examples
pythonqtqgraphicsitemqgraphicstextitem

Qt QGraphicsTextItem Set Item To Stick To Dragged Position


I'm trying position a text and I want it to stick to where ever the user has dragged it for example bottom right it will stay there and when the view gets resized the text item stays bottom right, so it dynamically changes position with the view.

I've tried to SetPos but I think due to the maths I'm having a hard time to figure out how to set the correct POS for the text as the view is resizing. I've created a simpler version of the code I have that allows text dragging, if anyone has solved this in their project I would love to hear how, thanks.

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QGraphicsScene, QGraphicsView, QGraphicsTextItem
from PyQt5.QtCore import Qt


class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        layout = QVBoxLayout()
        self.setLayout(layout)

        # Create a QGraphicsScene
        self.scene = QGraphicsScene()

        # Create a QGraphicsTextItem and add it to the scene
        self.text_item = QGraphicsTextItem("Hello, World!")
        self.text_item.setTextInteractionFlags(Qt.TextEditorInteraction)
        self.text_item.setFlags(QGraphicsTextItem.ItemIsSelectable | QGraphicsTextItem.ItemIsMovable | QGraphicsTextItem.ItemIsFocusable)

        self.scene.addItem(self.text_item)

        # Set initial font size
        self.font_size = 12

        # Create a QGraphicsView and set the scene
        self.view = QGraphicsView(self.scene)
        layout.addWidget(self.view)


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


Solution

  • I was able to find a way to keep the items inside a QGraphicsView always in the position where you've dragged it, relative to the size of the view.

    self.view.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
    

    This positions all the scene rect items and resizes them, just make sure to have it in the resize event to work when resizing, hopefully this saves you some time.