Mouse and QMenuBar
-
Hello, I would like to know if there is any to disable the mouse events that occur when clicking on one of the menu options. As you can see in the image I have a white square that highlights the options of my menubar but when this happens if I move the mouse and place it on top of some option of my menubar and click to open the submenu as seen in the image. I would like this not to happen.
-
Hi
You want the top menus, NOT open the sub menu when clicked ?
How will user then access the sub item ? -
Hi,
Why not just disable the menu ?
-
Can you give more details so that we can devise a solution ?
-
@SGaist My application has two access modes: the conventional one with mouse and keyboard, and sweep mode where the menu options are highlighted with a QRubberband. For the second mode I use the preesmouseevent method so that the menus are displayed or an action is executed, that is why I want the conventional mouse events to not work when the user is in this mode.
-
Then one possible way would be to have a transparent widget on top of your UI that would block the interaction when in your swipe mode.
-
Hi
You can use
https://doc.qt.io/qt-5/qwidget.html#grabMouse
to have all events go to some widget, effectively making it impossible to click on anything else.
However, it offers no control of what can is eaten. and if you fail to to ungrab as many times as you grab,
it will still be grapped. Also docs says:
"Warning: Bugs in mouse-grabbing applications very often lock the terminal. Use this function with extreme caution, and consider using the -nograb command line option while debugging."Not the best solution, imho.
So another solution is to use an event filter.
// the filter class #include <QEvent> #include <QMouseEvent> class MouseEater : public QObject { Q_OBJECT bool sweepmodeActive{0}; protected: bool eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) { QMouseEvent *mp = static_cast<QMouseEvent *>(event); qDebug() << "MouseButtonPress detected" << sweepmodeActive; if ( mp->button() == Qt::LeftButton ) { return sweepmodeActive; // say we handled it (true) } } return QObject::eventFilter(obj, event);// normal forward } public slots: void SweepModeToggle( bool status) { sweepmodeActive = status; qDebug() << "sweepmode" << status; } }; // in main window MouseEater *me = new MouseEater(); connect(ui->pushButton, &QPushButton::toggled, me, &MouseEater::SweepModeToggle ); // to toogle sweep mode ui->menubar->installEventFilter(me); // put filter ont he menubar
the result is this.
-
@mrjj
I have two buttons in the Sweep mode action, one of them activates the sweep mode where I install the filter so that the options are not displayed, that works well for me as you can see in the gif.But when I click Direct mode where I uninstall the filter but it doesn't work for me and the menus are still blocked.
void MainWindow::on_actionModo_Barrido_2_triggered() { modoBarrido = 0; topFiller = new QWidget; QVBoxLayout *box = new QVBoxLayout; QPushButton *mododirecto = new QPushButton(tr("ModoDirecto")); QPushButton *modobarrido = new QPushButton(tr("ModoBarrido")); // layout->setContentsMargins(0, 40, 40, 40); box->addWidget(mododirecto); box->addWidget(modobarrido); topFiller->setLayout(box); topFiller->setGeometry(500,200,400,400); topFiller->setStyleSheet("background-color:rgb(23, 255, 240)"); topFiller->show(); connect(mododirecto,SIGNAL(clicked()),this,SLOT(botondirecto())); connect(modobarrido,SIGNAL(clicked()),this,SLOT(botonbarrido())); } int MainWindow::botonbarrido() { main = new MainWindow(); modoBarrido=0; if(modoBarrido==0){ timeoutMenuPrincipal(); topFiller->close(); ui->menubar->installEventFilter(main); } return modoBarrido; } int MainWindow::botondirecto() { main = new MainWindow(); ui->menubar->removeEventFilter(main); modoBarrido=1; if(modoBarrido==1){ Highlight->~QRubberBand(); timer.stop(); timer2.stop(); timer.disconnect(&timer, SIGNAL(timeout()), this, SLOT(BarridoMenuPrincipal())); timer2.disconnect(&timer2, SIGNAL(timeout()), this, SLOT(BarridoSubMenu())); topFiller->close(); } return modoBarrido; }
-
Hi
it seems to me that inint MainWindow::botondirecto() { main = new MainWindow(); <<< make new window . its not the old one from botonbarrido() ui->menubar->removeEventFilter(main); <<< remove the filter but did we ever put one On as main seems new to me
So did i drink from the night pot or
did you mean to use removeEventFilter on the "main" we created in botonbarrido() ?Also do notice if you are using my code for the filter, then you can
call
SweepModeToggle(true) to have it filter and SweepModeToggle(false) to allow all.
So you dont have to go and install and remove it.