QT Widgets not responding to touch event sometimes
-
wrote on 17 May 2022, 17:21 last edited by
Hi @JoeCFD ,
I'm sorry, but I don't understand how your solution applies to my problem. I fail to see what additional code to handle Mouse events should help when my problem is that no more mouse events at all are generated at some point.Cheers, Michael.
-
Hi @JoeCFD ,
I'm sorry, but I don't understand how your solution applies to my problem. I fail to see what additional code to handle Mouse events should help when my problem is that no more mouse events at all are generated at some point.Cheers, Michael.
wrote on 17 May 2022, 19:39 last edited by JoeCFD@MicHes My Qt version is 5.15.2 as well. Add event filter to your QMainWindow(I have a QDialog). Then you can catch all events
and simply take touch and mouse events out to handle. You can print out all events to see what is going on when you touch the screen or press mouse. All types are here: https://doc.qt.io/qt-5/qevent.html -
wrote on 18 May 2022, 07:20 last edited by MicHes
Hi @JoeCFD,
that is exactly what we are already doing (1); the log lines quoted above are from an event filter routine. We only know because of this very event filter that the touch events are no longer synthesized into mouse events .What we still don't know is:
- why this is happening, and
- how we can change that behaviour in any way, shape or form so that we get Button press events consistently.
Our UI mostly consists of QPushButtons, and if they don't get pressed anymore, the application becomes pretty much useless.
I hope this clears things up.
Cheers, Michael.
(1) = To be precise, we have overloaded the notify() call of the QApplication class as follows:
bool Application::notify(QObject *receiver, QEvent *event) { switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: // case QEvent::MouseMove: handleMouseEvent(receiver, event); break; case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: handleHoverEvent(receiver, event); break; case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneMouseRelease: case QEvent::GraphicsSceneMouseDoubleClick: case QEvent::GraphicsSceneHoverEnter: case QEvent::GraphicsSceneHoverMove: case QEvent::GraphicsSceneHoverLeave: handleGraphicsSceneEvent(receiver, event); break; case QEvent::NonClientAreaMouseMove: case QEvent::NonClientAreaMouseButtonPress: case QEvent::NonClientAreaMouseButtonRelease: handleNonClientEvent(receiver, event); break; case QEvent::TabletMove: case QEvent::TabletPress: case QEvent::TabletRelease: handletTableEvent(receiver, event); break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: case QEvent::TouchCancel: handleTouchEvent(receiver, event); break; case QEvent::GrabMouse: case QEvent::UngrabMouse: handleGrabEvent(receiver, event); break; } return QApplication::notify(receiver, event); }
The handleXYZ() routines do straightforward logging, here's two examples:
void Application::handleTouchEvent(QObject *receiver, QEvent *event) { QAbstractButton* pushButton = qobject_cast<QAbstractButton*>(receiver); logger->log(DEBUG, QString("Type=%1, objectName=%2, isButton=%3") .arg(typeToString(event)) .arg(receiver->objectName()) .arg(pushButton != nullptr ? "true" : "false")); } void Application::handleMouseEvent(QObject *receiver, QEvent *event) { QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event); QAbstractButton* pushButton = qobject_cast<QAbstractButton*>(receiver); QString moreText; if (mouseEvent != nullptr) { QString eventSource = "?"; switch (mouseEvent->source()) { case 0: eventSource = "MouseEventNotSynthesized"; break; case 1: eventSource = "MouseEventSynthesizedBySystem"; break; case 2: eventSource = "MouseEventSynthesizedByQt"; break; case 3: eventSource = "MouseEventSynthesizedByApplication"; break; } moreText = QString("xPos=%1, yPos=%2, source=%3") .arg(mouseEvent->globalX()) .arg(mouseEvent->globalY()) .arg(eventSource); } logger->log(DEBUG,QString("Type=%1, objectName=%2, isButton=%3, [%4]") .arg(typeToString(event)) .arg(receiver->objectName()) .arg(pushButton != nullptr ? "true" : "false") .arg(moreText)); }
-
wrote on 18 May 2022, 16:22 last edited by JoeCFD
I do not know the reasons and also did not spend time to debug into the Qt code for the check. There could be reasons like: drivers, Qt bugs, etc. I have only one dialog for exit option with 4 buttons. The following code(plus marking the button with enter event) works fine for this purpose.
if ( QEvent::MouseButtonPress == event->type() || QEvent::TouchBegin == event->type() ) { handle button press event return true; } return QDialog::eventFilter(obj, event);
-
wrote on 18 May 2022, 16:49 last edited by
Hi @JoeCFD,
depending on which window is active, the can be any number of buttons (from zero to several dozen) pretty much anywhere on screen, so the main task would be to find the PushButton under the TouchEvent. How would one go about that? -
wrote on 18 May 2022, 16:59 last edited by
bool ExitDialog::eventFilter( QObject *obj, QEvent *event) { if ( QEvent::Enter == event->type() && this != obj ) { ui->selectedButton = dynamic_cast< QPushButton * >( obj ); } if ( QEvent::Leave == event->type() && this != obj ) { ui->selectedButton = nullptr; } if ( QEvent::MouseButtonPress == event->type() || QEvent::TouchBegin == event->type() ) { bool ok{ false }; if ( obj == ui->exitButton || ui->selectedButton == ui->exitButton ) { handle exit button press event ok = true; } return ok; } return QDialog::eventFilter(obj, event); }
-
wrote on 18 May 2022, 17:28 last edited by
Hi @JoeCFD ,
this is just for one specific button (ui->exitButton), right?and where you write
handle exit button press event
I should generate a ButtonPressed event for my widget?
I'm not sure how to scale this properly; I have about 15 QMainWindows with north of 150 QPushButtons in total, and simply cannot manually add handling code for each and every one of them, because that's not maintainable.
Cheers, Michael.
-
wrote on 18 May 2022, 17:34 last edited by
I do not know how you layout your windows. I guess you will have one bool eventFilter( QObject *obj, QEvent *event) for each main window. A loop over 150 buttons to find the index of the pressed button is pretty fast. You do not worry about it.
-
wrote on 19 May 2022, 06:54 last edited by
Hi @JoeCFD,
speed is not the main issue here - I meant that code you need to change every time you add or remove a button would not be maintainable. There would need to be an routine that automatically finds the button (if any) a touch event belongs to, otherwise it will cause more problems down the line.Greetings, Michael.
-
-
Hi @JoeCFD,
speed is not the main issue here - I meant that code you need to change every time you add or remove a button would not be maintainable. There would need to be an routine that automatically finds the button (if any) a touch event belongs to, otherwise it will cause more problems down the line.Greetings, Michael.
wrote on 11 Nov 2024, 06:45 last edited by@MicHes said in QT Widgets not responding to touch event sometimes:
Hi @JoeCFD,
speed is not the main issue here - I meant that code you need to change every time you add or remove a button would not be maintainable. There would need to be an routine that automatically finds the button (if any) a touch event belongs to, otherwise it will cause more problems down the line.Greetings, Michael.
or use static cast for find button name and apply code for that when find it.
14/14