Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How emiting QGraphicsRectItem position?



  • I have a QChart in a QGraphicsScene. I have added a rectangle that can be moved by the mouse. I would like to get the position of the rectangle when I release the mouse button. For this purpose I have subclasses QGraphicsRectItem in order to reimplement the mouseReleaseEvent.
    Because QGraphicsRectItem doesn't support signals and slots how can I propagate the position of the rectangle I get through the mouseReleaseEvent to other classes?

    A small test program showing my implementation can be downloaded from: https://www.dropbox.com/s/guwe42jof8o8bkp/QGraphicsRectItemTest.zip?dl=0



  • Thank you for your suggestion.
    I did the following.
    I sub classed QGraphicsScene to CustomScene and reimplemented the mouseReleasedEvent.
    In CustomScene I have added the signal MouseReleased.

    class CustomScene : public QGraphicsScene
    {
        Q_OBJECT
    public:
        explicit CustomScene(QObject *parent = nullptr);
    
    signals:
        void MouseReleased(void);
    
    protected:
        void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    };
    
    void CustomScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
        emit MouseReleased();
        QGraphicsScene::mouseReleaseEvent(event);
    }
    

    I also made a new QGraphicsItem called Cursor.
    Then in the main class I added the following:

    Cursor *cursor1 = new Cursor();
    scene->addItem(cursor1);
    
    connect(scene, &CustomScene::MouseReleased, [=](){
           if (scene->focusItem()!=nullptr)
            {
            QPointF position = scene->focusItem()->scenePos();
            QPointF posVal = m_chart->mapToValue(position);
                     
            int index;
            QPointF pos2;
            ComputClosestPoint(posVal, &index, &pos2);
            scene->focusItem()->setPos(m_chart->mapToPosition(pos2));
            }
        });
    

    The result is that I now have a cursor which snaps to the closest point if I release the mouse button as shown below.
    9fcb38bb-dd95-412f-9a42-b575e08d0e28-image.png

    The improved version looks like below.
    46ad8a8c-835c-4b63-9473-0a5dd48ade75-image.png

    As I'm a beginner with Qt I don't know if this is the right or recommended way of coding this feature. So I'm not sure I can mark it as solution.



  • @Bert59
    Suggestion: you can access QGraphicsScene *QGraphicsItem::scene() and the QGraphicsScene does inherit QObject/signals+slots so you could emit your own signal from that with necessary parameters?


  • Lifetime Qt Champion

    Hi,

    You can do double inheritance like the QGraphicsObject or use that class as base for your custom item.



  • Thank you for your suggestion.
    I did the following.
    I sub classed QGraphicsScene to CustomScene and reimplemented the mouseReleasedEvent.
    In CustomScene I have added the signal MouseReleased.

    class CustomScene : public QGraphicsScene
    {
        Q_OBJECT
    public:
        explicit CustomScene(QObject *parent = nullptr);
    
    signals:
        void MouseReleased(void);
    
    protected:
        void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    };
    
    void CustomScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
        emit MouseReleased();
        QGraphicsScene::mouseReleaseEvent(event);
    }
    

    I also made a new QGraphicsItem called Cursor.
    Then in the main class I added the following:

    Cursor *cursor1 = new Cursor();
    scene->addItem(cursor1);
    
    connect(scene, &CustomScene::MouseReleased, [=](){
           if (scene->focusItem()!=nullptr)
            {
            QPointF position = scene->focusItem()->scenePos();
            QPointF posVal = m_chart->mapToValue(position);
                     
            int index;
            QPointF pos2;
            ComputClosestPoint(posVal, &index, &pos2);
            scene->focusItem()->setPos(m_chart->mapToPosition(pos2));
            }
        });
    

    The result is that I now have a cursor which snaps to the closest point if I release the mouse button as shown below.
    9fcb38bb-dd95-412f-9a42-b575e08d0e28-image.png

    The improved version looks like below.
    46ad8a8c-835c-4b63-9473-0a5dd48ade75-image.png

    As I'm a beginner with Qt I don't know if this is the right or recommended way of coding this feature. So I'm not sure I can mark it as solution.


  • Lifetime Qt Champion

    The solution does not look bad as is.


Log in to reply