C++ Qt - 确定绝对小部件和光标位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4450595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Qt - Determine absolute widget and cursor position
提问by Dave McClelland
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.
我有一个包含多个孩子的 QWidget。最终目标是能够从一个小部件拖放到另一个小部件,在小部件之间移动一些东西。我有一个信号被发送到我的父小部件的控制器,并且可以确定拖动何时正确开始和结束。我当前的问题是确定鼠标是否在鼠标向上时的目标小部件上方。
I got excited when I saw underMousein 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 mapToGlobalwould 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.
当我在文档中看到underMouse时我很兴奋,但它在拖放事件期间不起作用(当我测试时,它似乎返回了不正确的值)。如果失败,我的目标是找到包含目标小部件的矩形,并查找它是否包含鼠标向上时的鼠标坐标。我不能简单地使用contentsRect,因为它返回相对于它被调用的小部件的位置。我认为mapToGlobal会给我绝对的屏幕像素值,但它也一直失败。我尝试在父小部件的窗口上调用 mapTo ,但这似乎也失败了。
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.
下面的代码显示了我使用各种方法获得的各种 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);
mapToParentwon't work for my purposes, since the target widget is actually parented by a child of the top-level parent.
mapToParent不适用于我的目的,因为目标小部件实际上是由顶级父级的子级作为父级的。
UpdateHere'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
}
回答by Elrohir
As already said you should rather use targetWidget->geometry()
instead of contentsRect()
in this special case.
如前所述targetWidget->geometry()
,contentsRect()
在这种特殊情况下,您应该使用而不是使用。
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:
接下来我想知道您发布的代码属于哪个类。该方法QWidget::mapToGlobal()
应该从您的坐标相对于的 QWidget 调用。如果我猜对了,它应该是这样的:
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:
然后注意QCursor::pos()
已经返回全局屏幕坐标,所以不需要在这里映射任何东西:
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:
编辑:最好不要将 rect 映射到全局,而是将全局光标位置映射到小部件:
if (targetWidget->rect().contains(targetWidget->mapFromGlobal(QCursor::pos()))) {
/* do stuff */
}
回答by yasouser
回答by flipthefrog
This PyQt method will return True if the mouse position is within the widget's rect - includingcases such as the mouse being over a combo view insidethe widget
如果鼠标位置在小部件的矩形内,则此 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))