I have a very simple QML scene with a blue square (size 100x100) placed in the top left corner (x = 0, y = 0). This square is draggable with a mouse.
import QtQuick
import QtQuick.Window
Window {
id: box
width: 500
height: 500
visible: true
Rectangle {
id: square
objectName: "square"
width: 100
height: 100
x: 0
y: 0
color: "blue"
MouseArea {
anchors.fill: parent
drag.target: square
drag.axis: Drag.XAndYAxis
}
}
}
Then I have a simple main.cpp
in which I instantiate the scene. And then after some delay (100 ms) when the scene is ready, I simulate dragging the square with a mouse.
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include <QtTest>
void testMoving()
{
auto window = QGuiApplication::focusWindow();
Q_ASSERT(window);
auto square = window->findChild<QQuickItem*>("square");
Q_ASSERT(square);
QTest::mousePress(window, Qt::LeftButton, {}, {50, 50});
QTest::mouseMove(window, {250, 250});
QTest::mouseRelease(window, Qt::LeftButton, {}, {250, 250});
qDebug() << square->position();
}
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
&app, []() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("movable", "Main");
QTimer::singleShot(100, &testMoving);
return app.exec();
}
The code in testMoving()
is supposed to simulate mouse press at coordinates (50, 50) and dragging to (250, 250). So the coordinates of the square should change from (0, 0) to (200, 200). But it does not work and the square is not moved. The output from qDebug()
is QPointF(0,0)
.
I experimented with the code a bit, so I changed the lines to:
QTest::mousePress(window, Qt::LeftButton, {}, {50, 50});
QTest::mouseMove(window, {200, 200});
QTest::mouseRelease(window, Qt::LeftButton, {}, {250, 250});
Now the result is surprisingly (for me) QPointF(50,50)
, which is the difference between those 200s and 250s. So the square moved. So I thought "aha!" I must first move the cursor to start of dragging and then release it at the target destination. So I tried:
QTest::mousePress(window, Qt::LeftButton, {}, {50, 50});
QTest::mouseMove(window, {50, 50});
QTest::mouseRelease(window, Qt::LeftButton, {}, {250, 250});
... and the actual result is again QPointF(0,0)
instead of the expected QPointF(200,200)
. WTH is going on? Has anyone an idea how to simulate dragging the square with a mouse using QtTest
?
This comment actually made me realize that this is still a drag operation. And a drag operation requires the mouse to travel a certain minimum distance before it is registered as dragging. Obviously, the distance must be bigger than 10 pixels on his system.
So the explanation is this:
The final dragged distance then will be the distance between points Y and Z.
PS: The minimum required distance can probably be obtained from https://doc.qt.io/qt-6/qstylehints.html#startDragDistance-prop