Item::contains
似乎总是返回true:
import QtQuick 2.3
Rectangle {
width: 400
height: 400
color: "green"
Rectangle {
id: block
width: 50
height: 50
color: "red"
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
var pnt = mapToItem( block, mouse.x, mouse.y );
console.log( "pnt x:", pnt.x, "y:", pnt.y );
if ( block.contains( pnt ) ) {
console.log( "Inside" );
} else {
console.log( "Outside" );
}
}
}
}
运行它并随机点击会得到如下输出:
qml: pnt x: 104 y: 102
qml: Inside
qml: pnt x: -113 y: -101
qml: Inside
qml: pnt x: -105 y: 111
qml: Inside
qml: pnt x: 120 y: -62
qml: Inside
正如您所见,即使输入位于内部块之外,也会打印Inside
。有什么我不理解Item::contains
吗?
如果我将一个基本的矩形contains
方法放在一起:
function myContains( pnt ) {
return pnt.x >= 0 && pnt.x < block.width &&
pnt.y >= 0 && pnt.y < block.height;
}
它工作正常,因此block
位置和大小没有任何问题。默认的QQuickItem::contains(..)
方法应该只使用基本的局部坐标矩形测试,如上所述。
正如@Mitch所指出的那样,object
返回的Item::mapToItem(..)
似乎没有转换为C ++端的QPointF
。解决方案是在调用Qt.point
之前将转换后的坐标推送到Item::contains
:
...
if ( block.contains( Qt.point( pnt.x, pnt.y ) ) ) {
...
答案 0 :(得分:1)
它看起来像一个bug。如果您向QQuickItem::contains()
添加调试语句,则可以看到该点未正确转换为{0, 0}
:
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -6922,6 +6922,7 @@ void QQuickItem::setKeepTouchGrab(bool keep)
bool QQuickItem::contains(const QPointF &point) const
{
Q_D(const QQuickItem);
+ qDebug() << Q_FUNC_INFO << point;
return QRectF(0, 0, d->width, d->height).contains(point);
}
输出:
qml: pnt x: 79 y: 74
bool __thiscall QQuickItem::contains(const class QPointF &) const QPointF(0,0)
qml: Inside
不幸的是(并且非常令人惊讶地)测试不会解释这一点,因为他们only test是一个自定义contains
函数,并且在C ++中这样做。