开发者

Qt - Determine absolute widget and cursor position

I have a QWidget that contains multiple children. The ultimate goal is to be able to drag and drop from one widget to the other, moving something between widgets. I've got a signal being fired to my parent widget's controller and can determine when the drag is starting and ending correctly. My current problem is determining whether or not the mouse is above the target widget on mouse up.

I got excited when I saw underMouse in the docs, but it doesn't work during drag and drop events (when I tested, it seemed to return incorrect values). Failing this, my goal was to find the rectangle containing the target widget and find whether it contained the mouse coordinates on a mouse up. I can't simply use contentsRect, since it returns positions relative to the widget it is being called on. I thought that mapToGlobal wo开发者_如何转开发uld give me absolute screen pixel values, but it keeps failing as well. I tried calling mapTo on the parent widget's window, but that also seemed to fail.

Below is code showing the various QRects and QPoints I've gotten with the various methods. Maybe there's a simple error with one of them, so I've provided them all.

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 won't work for my purposes, since the target widget is actually parented by a child of the top-level parent.

Update Here's the code that ended up working out. In my top-level widget (that was an ancestor to both the source and target widgets), I added this:

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


As already said you should rather use targetWidget->geometry() instead of contentsRect() in this special case.

Next I wonder which class the code you posted belongs to. The method QWidget::mapToGlobal() should be invoked from the QWidget your coordinates are relative to. If I got you right, it should look like something like this:

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

Then note QCursor::pos() is already returning global screen coordinates, so no need to map anything here:

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

EDIT: Probably it's even better to not map the rect to global, but to map the global cursor position to the widget:

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


Maybe you are looking for geometry() or frameGeometry() in QWidget. See here for more details.


This PyQt method will return True if the mouse position is within the widget's rect - including cases such as the mouse being over a combo view inside the widget

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))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜