Qt - 确定绝对小部件和光标位置

时间:2010-12-15 13:51:21

标签: c++ qt

我有一个包含多个孩子的QWidget。最终目标是能够从一个窗口小部件拖放到另一个窗口小部件,在窗口小部件之间移动。我有一个信号被激发到我的父窗口小部件的控制器,并可以确定拖动何时正确开始和结束。我目前的问题是确定鼠标在鼠标上方是否位于目标小部件之上。

当我在文档中看到underMouse时,我很兴奋,但在拖放事件期间它不起作用(当我测试时,它似乎返回不正确的值)。如果做不到这一点,我的目标是找到包含目标小部件的矩形,并查找它是否包含鼠标上的鼠标坐标。我不能简单地使用contentsRect,因为它返回相对于调用它的小部件的位置。我认为mapToGlobal会给我绝对的屏幕像素值,但它也会一直失败。我尝试在父窗口小部件的窗口上调用mapTo,但这似乎也失败了。

下面的代码显示了我用各种方法获得的各种QRects和QPoints。也许其中一个有一个简单的错误,所以我已经提供了所有这些错误。

QRect relativeWidgetRect = targetWidget->contentsRect();
QRect *absoluteWidgetRect = new QRect(QWidget::mapToGlobal(relativeWidgetRect.topLeft()), QWidget::mapToGlobal(relativeWidgetRect.bottomRight()));
QRect *widgetRect = new QRect(mapTo(window(), relativeWidgetRect.topLeft()), mapTo(window(), relativeWidgetRect.bottomRight()));
QPoint relativeMousePos = QCursor::pos();
QPoint absoluteMousePos = QWidget::mapToGlobal(relativeMousePos);
QPoint widgetMousePos = mapTo(window(), relativeMousePos);

mapToParent不能用于我的目的,因为目标小部件实际上是顶级父级的子级的父级。

更新以下是最终解决的代码。在我的顶级窗口小部件(它是源窗口小部件和目标窗口小部件的祖先)中,我添加了这个:

QRect widgetRect = targetWidget->Geometry();
QPoint mousePos = targetWidget->mapFromGlobal(QCursor::pos());
if(widgetRect.contains(mousePos))
{
// Logic
}

3 个答案:

答案 0 :(得分:35)

如前所述,在这种特殊情况下,您应该使用targetWidget->geometry()代替contentsRect()

接下来我想知道你发布的代码属于哪个类。应该从您的坐标相对的QWidget调用方法QWidget::mapToGlobal()。如果我找对你,那应该是这样的:

QRect widgetRect = targetWidget->geometry();
widgetRect.moveTopLeft(targetWidget->parentWidget()->mapToGlobal(widgetRect.topLeft()));

然后注意QCursor::pos()已经返回全局屏幕坐标,因此无需在此处映射任何内容:

if (widgetRect.contains(QCursor::pos())) {
    /* swap widgets */
}

编辑:可能最好不将rect映射到全局,而是将全局光标位置映射到小部件:

if (targetWidget->rect().contains(targetWidget->mapFromGlobal(QCursor::pos()))) {
    /* do stuff */
}

答案 1 :(得分:2)

也许您在QWidget中寻找geometry()frameGeometry()。有关详细信息,请参阅here

答案 2 :(得分:0)

如果鼠标位置在窗口小部件的矩形内,此PyQt方法将返回True - 包括例如鼠标在组合视图里面窗口小部件

>
def underMouse(self):
    pos = QtGui.QCursor.pos()
    rect = self.rect()
    leftTop     = self.mapToGlobal(QtCore.QPoint(rect.left(),rect.top()))
    rightBottom = self.mapToGlobal(QtCore.QPoint(rect.right(),rect.bottom()))
    globalRect = QtCore.QRect(leftTop.x(), leftTop.y(), rightBottom.x(), rightBottom.y() )
    return globalRect.contains(self.mapToGlobal(pos))