Missing touch events in QWidget
-
I have a problem with touch events in Qt 6.8.2 (on Windows). I created a new Qt Widgets Application project in QtCreator and changed the resulting mainwindow.cpp file to this:
#include <QPointerEvent> #include "mainwindow.hpp" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setAttribute(Qt::WA_AcceptTouchEvents); resize(800, 800); } MainWindow::~MainWindow() {} bool MainWindow::event(QEvent* event) { switch (event->type()) { case QEvent::TouchBegin: qDebug() << "TOUCH BEGIN"; break; case QEvent::TouchEnd: qDebug() << "TOUCH END"; break; case QEvent::TouchUpdate: for (const auto& point : static_cast<QTouchEvent*>(event)->points()) { qDebug() << point.id() << point.state(); } break; case QEvent::TouchCancel: qDebug() << "TOUCH CANCEL"; break; default: break; } return true; }
I then run this code with the following touch sequence:
- Touch and hold with two fingers
- Release first finger
- Again touch first finger
- Release second finger
And these are the resulting printouts:
TOUCH BEGIN 0 QEventPoint::Stationary 1 QEventPoint::Pressed 0 QEventPoint::Released 1 QEventPoint::Stationary 1 QEventPoint::Updated 1 QEventPoint::Updated 1 QEventPoint::Updated 1 QEventPoint::Updated 1 QEventPoint::Updated 1 QEventPoint::Updated 2 QEventPoint::Pressed 1 QEventPoint::Stationary TOUCH END
After point 4, I am still touching the QWidget with the first finger (and can move it around) but there are no more events delivered and so that touch can no longer be tracked. What am I doing wrong? What do I need to change to have all the touch events delivered?
-
I have a problem with touch events in Qt 6.8.2 (on Windows). I created a new Qt Widgets Application project in QtCreator and changed the resulting mainwindow.cpp file to this:
#include <QPointerEvent> #include "mainwindow.hpp" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setAttribute(Qt::WA_AcceptTouchEvents); resize(800, 800); } MainWindow::~MainWindow() {} bool MainWindow::event(QEvent* event) { switch (event->type()) { case QEvent::TouchBegin: qDebug() << "TOUCH BEGIN"; break; case QEvent::TouchEnd: qDebug() << "TOUCH END"; break; case QEvent::TouchUpdate: for (const auto& point : static_cast<QTouchEvent*>(event)->points()) { qDebug() << point.id() << point.state(); } break; case QEvent::TouchCancel: qDebug() << "TOUCH CANCEL"; break; default: break; } return true; }
I then run this code with the following touch sequence:
- Touch and hold with two fingers
- Release first finger
- Again touch first finger
- Release second finger
And these are the resulting printouts:
TOUCH BEGIN 0 QEventPoint::Stationary 1 QEventPoint::Pressed 0 QEventPoint::Released 1 QEventPoint::Stationary 1 QEventPoint::Updated 1 QEventPoint::Updated 1 QEventPoint::Updated 1 QEventPoint::Updated 1 QEventPoint::Updated 1 QEventPoint::Updated 2 QEventPoint::Pressed 1 QEventPoint::Stationary TOUCH END
After point 4, I am still touching the QWidget with the first finger (and can move it around) but there are no more events delivered and so that touch can no longer be tracked. What am I doing wrong? What do I need to change to have all the touch events delivered?
@EmilFors said in Missing touch events in QWidget:
What do I need to change to have all the touch events delivered?
The short answer is: Use only one finger.
Qt stops delivering touch events, when the hardware doesn't send any more.
This is what happens on my touch screen (on Linux):
1: Touch event created
2: Touch hot spot shrinks to half its size (first finger lifted)
3: creates a new hardware touch signal at finger 1's position. This is ignored, because there is already a touch in progress on the same widget.
4: Touch event ends, while finger 1 is still ignored -
@EmilFors said in Missing touch events in QWidget:
What do I need to change to have all the touch events delivered?
The short answer is: Use only one finger.
Qt stops delivering touch events, when the hardware doesn't send any more.
This is what happens on my touch screen (on Linux):
1: Touch event created
2: Touch hot spot shrinks to half its size (first finger lifted)
3: creates a new hardware touch signal at finger 1's position. This is ignored, because there is already a touch in progress on the same widget.
4: Touch event ends, while finger 1 is still ignored@Axel-Spoerl said in Missing touch events in QWidget:
The short answer is: Use only one finger.
Unfortunately that's not an option as one of the use cases is pinch-to-zoom, which obviously requires two fingers. If this behaviour is caused by the hardware that means I can't do anything about it which is fine. I wanted to understand whether I was doing something wrong, like perhaps not setting something up correctly.
On my machine, the new touch point in step 3 is not ignored (it appears as a touch point with id == 2 in the log above). My problem is with understanding why point #2 ceases to be reported because point #1 is released.
-
After further testing, I don't think this is a hardware issue. Most of the time, this happens (the remaining touch is lost after the second finger touch is released), but it doesn't happen every time. What I can see is that every time it does happen, the still touching finger reports "Stationary" in the same event as the initially released finger is brought back to touching the screen. I.e., the final two lines in the log:
2 QEventPoint::Pressed 1 QEventPoint::Stationary
Every time the remaining finger is NOT lost, the second line there reported "Updated" or "Released" depending on how fast I was with lifting the finger. Is there something in the Qt touch event handler that might cause this problem only when the touch point for the second finger is reported as "Stationary" in the same event as the first finger is reported as "Pressed"?