Unsolved Mouse grabbing not working in menu with qwidgetaction
-
Hello. I have a custom component to edit number (derived from QSpinBox). I grab mouse move for line edit to simulate changing value up and down. When I grabbing mouse movement, I change cursor position to position I saved when enter editing component by mouse clicking. Everything works fine if I add component to main window. However if I have this componet in menu or popup, cursor go out of menu and I don't know why
-
Hi and welcome to devnet,
How are you invoking your pop/menu ?
-
I'm using QPushButton with menu set by setMenu method. Then I click on button and menu popup.
-
spinbox.cpp
#include "spinbox.h" #include <QDebug> #include <QMouseEvent> #include <QLineEdit> #include <QApplication> SpinBox::SpinBox(QWidget* parent) : QSpinBox(parent) { lineEdit()->installEventFilter(this); } void SpinBox::onMouseMoved(QMouseEvent* event) { if (m_pos.isNull()) return; const int delta = (m_pos.y() - event->globalY()) * (event->modifiers().testFlag(Qt::ControlModifier) ? singleStep() * 1 : 10); auto wheelEvent = new QWheelEvent(event->globalPos(), delta, event->buttons(), event->modifiers()); QApplication::postEvent(this, wheelEvent); QCursor::setPos(m_pos); } void SpinBox::onMousePressed(QMouseEvent* event) { lineEdit()->grabMouse(); grabKeyboard(); QApplication::setOverrideCursor(Qt::SizeVerCursor); m_pos = event->globalPos(); } bool SpinBox::eventFilter(QObject* watched, QEvent* event) { if (watched != lineEdit()) return QSpinBox::eventFilter(watched, event); switch (event->type()) { case QEvent::MouseMove: onMouseMoved(static_cast<QMouseEvent*>(event)); return true; case QEvent::MouseButtonPress: onMousePressed(static_cast<QMouseEvent*>(event)); return true; default: break; } return QSpinBox::eventFilter(watched, event); } void SpinBox::keyPressEvent(QKeyEvent* event) { if (event->key() != Qt::Key_Escape) return QSpinBox::keyPressEvent(event); event->accept(); QApplication::restoreOverrideCursor(); m_pos = { }; lineEdit()->releaseMouse(); releaseKeyboard(); }
mainwindow.cpp
#include "mainwindow.h" #include <QApplication> #include <QDebug> #include <QGuiApplication> #include <QComboBox> #include <QEvent> #include <QHBoxLayout> #include <QMenu> #include <QPushButton> #include <QWidgetAction> #include <QMoveEvent> #include <QTime> #include "spinbox.h" #include "doublespinbox.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { auto spinbox = new SpinBox(this); auto action = new QWidgetAction(nullptr); action->setDefaultWidget(spinbox); auto menu = new QMenu; menu->addAction(action); auto button = new QPushButton(this); button->setText("click me"); button->setMenu(menu); auto widget = new QWidget(this); auto layout = new QHBoxLayout(widget); layout->addWidget(button); layout->addWidget(new SpinBox); setCentralWidget(widget); } MainWindow::~MainWindow() { }
-
One issue I can see here is that you are using different means to grab and release the keyboard and mouse which means that if your user does not press escape before moving around you might get strange behaviours.
On a side note, having a spinbox that changes values just because my mouse hovers over it is counter-intuitive.