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,
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...
-
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...