QGraphicsItem and QMessageBox conflicts...



  • Hi Everyone,

    I need to make a quite simple application using QGraphicsScene and QGraphicsItem. I have a button to add QGraphicsItem to my scene. This part is working : no pb. But I want to add the possibility to delete an Item with right click. Just this, it seems to work as expected. But when I add a QMessageBox to ask for confirmation before deleting.... ouch !
    If I press the cancel button, it's strating doing crazy things. If I press Ok : item removed, but I have troubles with selection of remaining items. Any idea ??

    Thanks!

    My mainwindow.cpp :

    #include "myitem.h"
    
    #include <QDebug>
    #include <QGraphicsSceneMouseEvent>
    #include <QGraphicsScene>
    #include <QMessageBox>
    
    MyItem::MyItem(int id)
    {
        Pressed = false;
        Id = id;
        setFlag(ItemIsMovable);
        setFlag(ItemIsSelectable);
    }
    
    QRectF MyItem::boundingRect() const
    {
        // outer most edges
        return QRectF(0, 0, 100, 100);
    }
    
    void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(option)
        Q_UNUSED(widget)
    
        QRectF rect = boundingRect();
    
    //    if(Pressed)
        if(isSelected())
        {
            qDebug() << "Item " << Id << " -> " << this << " is selected\n";
    
            QPen pen(Qt::red, 3);
            painter->setPen(pen);
            painter->drawEllipse(rect);
        }
        else
        {
            qDebug() << "Item " << Id << " -> " << this << " is not selected\n";
    
            QPen pen(Qt::black, 3);
            painter->setPen(pen);
            painter->drawRect(rect);
        }
    }
    
    void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        Pressed = true;
        update();
    
        if (event->button() == Qt::RightButton)
        {
            QMessageBox boxMsg;
            boxMsg.setText("Deletion requested");
            boxMsg.setInformativeText("Are you sure ?");
            boxMsg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
            boxMsg.setDefaultButton(QMessageBox::Cancel);
            if (boxMsg.exec() == QMessageBox::Ok)
            {
                scene()->removeItem(this);
            }
    
            return;
        }
        QGraphicsItem::mousePressEvent(event);
    }
    
    void MyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
        Pressed = false;
        update();
        QGraphicsItem::mouseReleaseEvent(event);
    }
    

    My mainwindow.h :

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    #include <QGraphicsScene>
    #include "myitem.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    public slots:
        void onAddObjectPushButtonReleased(void);
    
    private:
        Ui::MainWindow *ui;
    
        QGraphicsScene *m_scene;
    
        MyItem *item[100];
    
        void _connectSlots(void);
    };
    
    #endif // MAINWINDOW_H
    

    My myitem.cpp :

    #include "myitem.h"
    
    #include <QDebug>
    #include <QGraphicsSceneMouseEvent>
    #include <QGraphicsScene>
    #include <QMessageBox>
    
    MyItem::MyItem(int id)
    {
        Pressed = false;
        Id = id;
        setFlag(ItemIsMovable);
        setFlag(ItemIsSelectable);
    }
    
    QRectF MyItem::boundingRect() const
    {
        // outer most edges
        return QRectF(0, 0, 100, 100);
    }
    
    void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(option)
        Q_UNUSED(widget)
    
        QRectF rect = boundingRect();
    
    //    if(Pressed)
        if(isSelected())
        {
            qDebug() << "Item " << Id << " -> " << this << " is selected\n";
    
            QPen pen(Qt::red, 3);
            painter->setPen(pen);
            painter->drawEllipse(rect);
        }
        else
        {
            qDebug() << "Item " << Id << " -> " << this << " is not selected\n";
    
            QPen pen(Qt::black, 3);
            painter->setPen(pen);
            painter->drawRect(rect);
        }
    }
    
    void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        Pressed = true;
        update();
    
        if (event->button() == Qt::RightButton)
        {
            QMessageBox boxMsg;
            boxMsg.setText("Deletion requested");
            boxMsg.setInformativeText("Are you sure ?");
            boxMsg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
            boxMsg.setDefaultButton(QMessageBox::Cancel);
            if (boxMsg.exec() == QMessageBox::Ok)
            {
                scene()->removeItem(this);
            }
    
            return;
        }
        QGraphicsItem::mousePressEvent(event);
    }
    
    void MyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
        Pressed = false;
        update();
        QGraphicsItem::mouseReleaseEvent(event);
    }
    

    My myitem.h :

    #ifndef MYITEM_H
    #define MYITEM_H
    
    #include <QPainter>
    #include <QGraphicsItem>
    
    class MyItem : public QGraphicsItem
    {
    public:
        MyItem(int id = 0);
    
        QRectF boundingRect() const;
    
        // overriding paint()
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    
        // item state
        bool Pressed;
        int Id;
    
    protected:
        // overriding mouse events
        void mousePressEvent(QGraphicsSceneMouseEvent *event);
        void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    };
    
    #endif // MYITEM_H
    


  • Hi,

    QGraphicsItem::mousePressEvent(event); gets not called if you call cancel in the message box. Maybe just place it before opening the message box.

    -Michael.



  • Hi,

    Just tried your idea, but without any success. If you compile my code and execute it, try to create 3 or 4 objects. Then you move them so they're not one on each other. Click on one of the object to select it (red circle). Then, try right click on one of the other ones : the messagebox appears. Click on cancel, and the qmessagebox closes, and appears again, and again. So, you press Ok to "get rid of it". -> The object is removed + the selected object is still selected .... until you just move your cursor.
    Now, select one object (whichever). you can move it, but if you want to select another one, the former selected object just come on your cursor, and stay selected.

    I don't know if my explanation is really clear, that's why it's better to see it by compiling.

    I'm quite sure I must miss something very obvious, but what...



  • Just for information, I also tried to use show instead of exec (qmessagebox) : doesn't work as well...



  • Found it !

    The problem was :

    When I click on the object to delete it, it opens the qmessage before allowing my main application to receive the releasebutton event.

    This problem occurs on Mac (not Windows), and on the middle and right mouse button.....

    And without this release event, a lot of strange behaviors can happen!

    So the solution : place my code from mousePressEvent to mouseReleaseEvent !

    Have a look :

    https://bugreports.qt.io/browse/QTBUG-36791

    So, my problem is solved...... but the bug is still there...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.