What is the QQuickItem::mapToItem return type?
-
20-12-2019 - |
Pregunta
The application below outputs coordinates mapped from one QQuickItem
to another. According to the docs:
object mapToItem(Item item, real x, real y)
Maps the point (x, y) or rect (x, y, width, height), which is in this item's coordinate system, to item's coordinate system, and returns an object with x and y (and optionally width and height) properties matching the mapped coordinate.
I expect the output to be something like this:
0 0
1 1
2 2
but I get:
QPointF(9, 6) 100
QPointF(9, 5) 100
QPointF(8, 5) 100
Why is the type of the mapped.x
a QPointF
? I expected it to be a floating-point value. What is an actual mapped
type?
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Window 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
width: 640
height: 480
Rectangle {
anchors.fill: parent
id: r0
color: "green"
Rectangle {
x: 50; y:100; width: 100; height: 100;
id: r
color: "yellow"
MouseArea {
id: mousearea
anchors.fill: parent
hoverEnabled: true
onPositionChanged: {
var mouseP = Qt.point(mouse.x, mouse.y);
var mapped = r.mapToItem(r0, mouseP);
console.log(mapped.x, ' ', mapped.y);
}
}
}
}
}
UPDATE1: QQuickItem has mapToItem
with 2 args and Item has mapToItem
with 3 args. Which one is called in the code above?
Solución
In your case, mapToItem
expects 3 parameters. You don't need to create a point first.
onPositionChanged: {
var mapped = r.mapToItem(r0, mouse.x, mouse.y);
console.log(mapped.x, ' ', mapped.y);
}
Background note: This seems to be kind of a bug, which I just reported.
Your code calls QQuickItem::mapToItem() for two reasons. First, QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const;
is not INVOKABLE, i.e. it is not exposed from C++ to QML. Second, QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const;
returns a QPointF
directly who's internal properties are called xp
and yp
instead of x
and y
(this can be observed using the debugger).
In QQuickItem::mapToItem()
x
and y
are forced by C++ to be of type qreal
, which is an alias for the C++ double
. Even if (v = (*args)[1])->asDouble()
freaks out completely, x
must be
- ordinary double value
- NaN
- +∞
- −∞
- -0
- +0.
In your case it should be NaN
. y = 0
because parameter 3 is not set. Thus a point (NaN, 0)
is created. From that point on, the rest of the calculations don't make any sense but error handling is missing.
There is a new JavaScript engine used from Qt 5.2 on. In 5.1 and before, V8 was used, which returns a NaN
instead of a QPointF
to QML.