Showing a QMessageBox or QColorDialog disrupts mouse clicks in a QGraphicsScene
-
IIRC, giving it a parent at creation time should take care of that.
-
@SGaist
It does. so 100% working.So change the constructor to include pointer to parent
Circle (QWidget *Parent, .....and store that in variable and use that in
QMessageBox *msgBox=new QMessageBox(Parent) ;And you should be happy.
-
I was thinking of something like
QMessageBox *msgBox=new QMessageBox(this);
-
@SGaist
But its not a QObject ?
no matching function for call to 'QMessageBox::QMessageBox(Circle*)'so a cast will work?
^ -
My bad, I've misread, in that case I'd rather use:
QMessageBox *msgBox=new QMessageBox(scene());
But no, casting will not help at all, since QGraphicsItem is not a QWidget
-
@SGaist
Still it is not really happy
no matching function for call to 'QMessageBox::QMessageBox(QGraphicsScene*)'
But it is a QObject it seems.. ? -
Damn, I've mixed scene and view...
-
aha!
so
QMessageBox *msgBox = new QMessageBox ( scene()->views()[0] ) ;
works even if ugly :)should be
QGraphicsView *Par=scene()->views()[0];
if (!Par) return;
QMessageBox *msgBox = new QMessageBox ( Par) ;for minimum safety.
-
Well for extra safety you should loop on the views to find one that currently shows the item clicked unless you know that you have exactly one view on the scene.
-
Thanks guys, this effectively works
-
I have to reopen this topic. I now want to open a
QColorDialog
when an item is clicked. I first used the static funtionQColorDialog::getColor()
but experienced the same problem as with theQMessageBox
.
A bit wiser now I modified it to mimic the solution for QMessageBox. Below is the "ready to go" code.A problem is that I cannot set the
Qt::WA_DeleteOnClose
attribute on the dialog because I have to retrieve the selected color withselectedColor()
. So I delete the dialog explictely after that. But no help, a second click where ever in the scene triggers a click on the first object. Any ideas?#include <string> #include <QtWidgets/QApplication> #include <QtWidgets/QColorDialog> #include <QtWidgets/QMainWindow> #include <QtWidgets/QGraphicsScene> #include <QtWidgets/QGraphicsView> #include <QtWidgets/QGridLayout> #include <QtWidgets/QGraphicsEllipseItem> using namespace std; class Circle : public QGraphicsEllipseItem { public: Circle::Circle(int Id, const qreal ax, const qreal ay, const qreal wx, const qreal wy, QGraphicsScene *scene, QWidget *parent) : QGraphicsEllipseItem(ax, ay, wx, wy), Id(Id), Parent(parent) { setPen( QPen(QBrush(Qt::black), 1, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin) ); setBrush( QBrush(Qt::gray) ); setRect(ax, ay, wx, wy); setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); scene->addItem(this); } ~Circle(){} void Circle::mousePressEvent(QGraphicsSceneMouseEvent *event) { QColorDialog* ColorDialog{ new QColorDialog( this->brush().color(), Parent ) }; //ColorDialog->setAttribute(Qt::WA_DeleteOnClose); ColorDialog->exec(); QColor ColourPick{ ColorDialog->selectedColor() }; if( ColourPick.isValid() ) setBrush( ColourPick ); delete ColorDialog; } int Id; QWidget *Parent; }; class MainWindowC : public QMainWindow { public: QWidget *baseWidget; QGridLayout *baseWidgetGrid; QGraphicsScene *graphicsScene; QGraphicsView *graphicsView; public: MainWindowC::MainWindowC(QWidget *parent=0) : QMainWindow(parent) { baseWidget = new QWidget(this); baseWidgetGrid = new QGridLayout(baseWidget); graphicsScene = new QGraphicsScene(0, 0, 120, 120); graphicsScene->addRect( 10, 10, 100, 100 ); new Circle( 1, 20, 20, 20, 20, graphicsScene, baseWidget ); new Circle( 2, 75, 75, 20, 20, graphicsScene, baseWidget ); graphicsView = new QGraphicsView(baseWidget); graphicsView->setRenderHint(QPainter::Antialiasing); graphicsView->setScene(graphicsScene); baseWidgetGrid->addWidget(graphicsView, 0, 0, 1, 1); setCentralWidget(baseWidget); } ~MainWindowC(){} }; int main(int argc, char *argv[]) { QApplication ApplicationC(argc, argv); MainWindowC MainWinC; MainWinC.show(); return ApplicationC.exec(); }
-
Hi , its the
ColorDialog->exec(); (makes own event loop)We found out that using open() helped.
Try to see if open() works for ColorDialog ?
Also read docs on "open." you can hook it up to a slot in your code when user
select color and click ok . That way it can work. -
No help, same behaviour. This is the modified code:
#include <string> #include <QtWidgets/QApplication> #include <QtWidgets/QColorDialog> #include <QtWidgets/QMainWindow> #include <QtWidgets/QGraphicsScene> #include <QtWidgets/QGraphicsView> #include <QtWidgets/QGridLayout> #include <QtWidgets/QGraphicsEllipseItem> using namespace std; class Circle : public QGraphicsEllipseItem { public: Circle::Circle(int Id, const qreal ax, const qreal ay, const qreal wx, const qreal wy, QGraphicsScene *scene, QWidget *parent) : QGraphicsEllipseItem(ax, ay, wx, wy), Id(Id), Parent(parent) { setPen( QPen(QBrush(Qt::black), 1, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin) ); setBrush( QBrush(Qt::gray) ); setRect(ax, ay, wx, wy); setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); scene->addItem(this); } ~Circle(){} void Circle::mousePressEvent(QGraphicsSceneMouseEvent *event); int Id; QWidget *Parent; }; class MainWin : public QMainWindow { public: QWidget *baseWidget; QGridLayout *baseWidgetGrid; QGraphicsScene *graphicsScene; QGraphicsView *graphicsView; MainWin::MainWin(QWidget *parent=0) : QMainWindow(parent) { baseWidget = new QWidget(this); baseWidgetGrid = new QGridLayout(baseWidget); graphicsScene = new QGraphicsScene(0, 0, 120, 120); graphicsScene->addRect( 10, 10, 100, 100 ); new Circle( 1, 20, 20, 20, 20, graphicsScene, baseWidget ); new Circle( 2, 75, 75, 20, 20, graphicsScene, baseWidget ); graphicsView = new QGraphicsView(baseWidget); graphicsView->setRenderHint(QPainter::Antialiasing); graphicsView->setScene(graphicsScene); baseWidgetGrid->addWidget(graphicsView, 0, 0, 1, 1); setCentralWidget(baseWidget); } ~MainWin(){} void colorSelected(const QColor & color); }; Circle* CircleClicked; QColorDialog* ColorDialog; MainWin* pMainWindow; void MainWin::colorSelected(const QColor & color){ QColor ColorPick{ color }; CircleClicked->setBrush( QBrush( ColorPick ) ); CircleClicked->update(); ColorDialog->deleteLater(); } void Circle::mousePressEvent(QGraphicsSceneMouseEvent *event) { CircleClicked = this; ColorDialog = new QColorDialog( this->brush().color(), pMainWindow->baseWidget ); pMainWindow->connect( ColorDialog, &QColorDialog::colorSelected, pMainWindow, &MainWin::colorSelected ); ColorDialog->open(); } int main(int argc, char *argv[]) { QApplication Application(argc, argv); MainWin MainWindow; pMainWindow = &MainWindow; MainWindow.show(); return Application.exec(); }
-
@JanLaloux said:
Well the void QDialog::open() seems not the same as
QMessageBox::open
so sadly it still creates a message loop it seems
so it wont work.That what I mean by
"Try to see if open() works for ColorDialog ?"
Did have doc so could not check.So unless ->show() do not create a messageloop , I dont know how you
can make it work.