Generate QTouchEvents to simulate touches
-
I have a multitouch input device that sends touch coordinates to my application through a databus. I want these touch coordinates to generate touches in my QtQuick application.
I successfully receive the coordinates into my cpp application but can't seem to generate touch events that are picked up by a MultiPointTouchArea in the qml layer.
To test this out i created a class that simply sends two QTouchEvents (TouchBegin and TouchEnd in an infinite loop) with fixed touchpoint coordinates to a simple qml ui to see if the touches were picked up by the MultiPointTouchArea. Please see the code below.
It works fine with mouse events (commented out in the code) but not with touch events. Any help would be appreciated.c++ class that is run as a QThread to generate clicks:
@
#include "touchtest.h"void TouchTest::run()
{
point0.setId(0);
m_touchPoints.append(point0);
//get top level widget
QWidgetList List = QApplication::topLevelWidgets();
QWidget *active = List[0];
int x = 50;
int y = 50;
point0.setPos(QPoint(x, y));
// create different events
QTouchDevice *screen = new QTouchDevice();
QTouchEvent *tEvent1 = new QTouchEvent(QEvent::TouchBegin, screen, Qt::NoModifier, Qt::TouchPointPressed, m_touchPoints);
QTouchEvent *tEvent2 = new QTouchEvent(QEvent::TouchEnd, screen, Qt::NoModifier, Qt::TouchPointPressed, m_touchPoints);
// QMouseEvent mEvent1(QEvent::MouseButtonPress, QPoint(x, y), Qt::LeftButton, 0, 0);
// QMouseEvent mEvent2(QEvent::MouseButtonRelease, QPoint(x, y), Qt::LeftButton, 0, 0);
// create loop to simulate touching
while(true)
{
// start touch
qDebug("TouchBegin");
QApplication::sendEvent(active, tEvent1);
// QApplication::sendEvent(active, &mEvent1);
sleep(2);
// end touch
qDebug("TouchEnd");
QApplication::sendEvent(active, tEvent2);
// QApplication::sendEvent(active, &mEvent2);
sleep(2);
}
}
@header file:
@
#ifndef TOUCHTEST_H
#define TOUCHTEST_H
#include <QThread>
#include <unistd.h>
#include <QCoreApplication>
#include <QtWidgets>
#include <QTouchEvent>class TouchTest : public QThread
{
Q_OBJECT
private:
QListQTouchEvent::TouchPoint m_touchPoints;
QTouchEvent::TouchPoint point0;protected:
void run();
};#endif // TOUCHTEST_H
@main.cpp:
@
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <unistd.h>
#include <QCoreApplication>
#include <QtWidgets>
#include <QQuickWidget>
#include "touchtest.h"int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQuickWidget *viewer = new QQuickWidget;
viewer->setSource(QUrl::fromLocalFile("qml/ClickTest/main.qml"));
viewer->show();
viewer->setWindowTitle("- TouchTest -");
viewer->setAttribute(Qt::WA_AcceptTouchEvents, true);
//initiate thread
TouchTest *thethread = new TouchTest();
thethread->start();
//initiate application
return app.exec();
}
@qml file with a red square following the touch point and a text rotating upon touch:
@
import QtQuick 2.3Rectangle {
width: 400
height: 400
Text {
id: thetext
text: qsTr("Hello World")
anchors.centerIn: parent
}
MultiPointTouchArea {
id: mpta1
anchors.fill: parent
touchPoints: [
TouchPoint { id: point1}
]
onTouchUpdated: {
thetext.rotation = thetext.rotation + 5;
thetext.text = "F--K YEAH!";
}
}
Rectangle {
width: 20; height: 20
color: "red"
x: point1.x
y: point1.y
}
}
@ -
Hi and welcome to devnet,
I can't comment about whether your idea will work or not, however after a quick look at QTouchEvent's documentation, it seems wrong to instantiate your own QTouchDevice. It's the platform plugin that should do that
-
Hi, thank you.
What do you mean by the platform plugin? I assumed that QTouchEvents could be used just like QMouseEvents.Any other ideas on how to create an interface for a custom touch device?
-
Qt uses QPA the Q Platform Abstraction concept to implement support for current/new platform. The platform plugins are build based on that. I didn't say the QTouchEvent couldn't be used like that. Just that the QTouchDevice you are creating is probably invalid since it's the QPA part that will create one if a touch device is available
-
Ok, I see. The touch device I'm trying to connect does not have a standard interface so it can not be automatically recognized as a touch device.
The computer communicating with the device receives the coordinates of touchpoints via serial interface and are then sent to my Qt app over dBus.Maybe writing a custom plugin using the QPA API is the only way. Anyone who has got any experience or thoughts on this approach?
-
If it's already working through D-Bus then you can use the QtDBus module to write a helper class that will send the coordinates through D-Bus. Doing so you can keep your current implementation the same and not fiddle with low-level stuff
-
Yes, it's already working with dBus. I'm using the QtDBus module to receive the coordinates in a helper class, but how do I generate the touches in the qml layer. That's what I need help with, and that's why I wrote the test code above to try to generate touch events. Or is it possible to generate an event directly via qbus?
-
Ok, all right, I misunderstood you, sorry.
For your last question, no it's not. From your test code, I would remove the QTouchDevice, since there are non, giving an "invalid" one could sabotage the event processing.
Next, I wouldn't use a while loop, you can use a worker object, and give it to a QThread if needed, to implement the event generation.
-
Use QWindowSystemInterface::handleTouchEvent to inject touches into the QPA event system. Unlike the sendEvent approach shown above, it is also thread-safe.
-
Hi agocs,
I cant seem to find any documentation on QWindowSystemInterface. How do I import the class?
I can only find old examples from <2010 and I'm using Qt 5.3. Is QWindowSystemInterface still valid? -
You'll have to dig in the sources, it's part of the QPA (QPlatform Abstraction) which isn't application API. You can find it under src/gui/kernel
-
After several attempts to inject QTouchEvents I gave up and went for another solution. By defining a new qml element in C++ that emits a signal (touchActive) when the coordinates are changed and listening to this signal in qml layer (onTouchActive).
The drawback is that every multi-touch gesture will have to be interpreted in the C++ class; pinch, zoom etc.
For reference see:
http://qt-project.org/doc/qt-4.8/qtbinding.html#defining-new-qml-elements