查找QGraphicsItem的屏幕位置
Find screen position of a QGraphicsItem
用例:这应该是一个相当常见的问题。在带有QMdiArea的普通QMainWindow中,存在一个带有QGraphicsView的mdiChild。此视图显示一个QGraphicsScene,其中包含QGraphicsItems。右键单击其中一个项目可选择(聚焦)该项目并打开上下文菜单,该菜单可方便地放置在屏幕坐标QGraphicsSceneMouseEvent::screenPos()
处。这正在按预期进行
现在,我想在用户按下某个键(例如Qt::key_menu)时显示相同的上下文菜单。我知道所选(聚焦)项目,我知道显示场景的视图。
所以我的问题是:
获取场景中QGraphicsItem可见表示的位置(在全局屏幕坐标中)的正确方法是什么?
以下是不起作用的:
QGraphicsItem *item = ...; // is the currently selected item next to which the context menu shall be opened
QGraphicsScene *scene = ...; // is the scene that hosts the item
QGraphicsView *graphicsView = ...; // is the view displaying the scene, this inherits from QWidget
// get the position relative to the scene
QPointF sp = item->scenePos();
// or use
QPointF sp = item->mapToScene(item->pos());
// find the global (screen) position of the item
QPoint global = graphicsView->mapToGlobal(graphicsView->mapFromScene(sp));
// now
myContextMenu.exec(global);
// should open the context menu at the top left corner of the QGraphicsItem item, but it goes anywhere
医生说:如果您想知道项目在视口中的位置,可以对项目调用QGraphicsItem::mapToScene(),然后对视图调用QGraphicsView::mapFromScene(
这正是我正在做的,对吧?
刚刚在一个德国论坛上偶然发现了一条线索,暗示:
QGraphicsView *view = item->scene()->views().last();
甚至更好:
QGraphicsView *view;
foreach (view, this->scene()->views())
{
if (view->underMouse() || view->hasFocus()) break;
}
// (use case in the forum thread:) // QMenu *menu = new QMenu(view);
使用它可能会让我的问题得到一个更普遍的答案。。。
我找到了一个有效的解决方案
QGraphicsItem必须在屏幕上可见。(可能是因为视图显示了场景的某个其他点而不可见,则可以将该点限制在视图的视口矩形上。)
// get the screen position of a QGraphicsItem
// assumption: the scene is displayed in only one view or the first view is the one to determine the screen position for
QPoint sendMenuEventPos; // in this case: find the screen position to display a context menu at
QGraphicsItem *pFocusItem = scene()->focusItem();
if(scene() != NULL // the focus item belongs to a scene
&& !scene()->views().isEmpty() // that scene is displayed in a view...
&& scene()->views().first() != NULL // ... which is not null...
&& scene()->views().first()->viewport() != NULL // ... and has a viewport
)
{
QGraphicsView *v = scene()->views().first();
QPointF sceneP = pFocusItem->mapToScene(pFocusItem->boundingRect().bottomRight());
QPoint viewP = v->mapFromScene(sceneP);
sendMenuEventPos = v->viewport()->mapToGlobal(viewP);
}
if(sendMenuEventPos != QPoint())
{
// display the menu:
QMenu m;
m.exec(sendMenuEventPos);
}
使用视图的视口将视图坐标映射到全局坐标非常重要。
上下文菜单键(Qt::key_menu)的检测发生在"主"QGraphicsItem的keyPressEvent()
中(由于我的程序结构)。
代码似乎是正确的。但是上下文菜单的创建可能存在一些问题。
您是否已将QContextMenu的父级设置为MainWindow(或应用程序中的类似设置)??
我认为这可能是你的问题所在。
祝你好运!!
只是在黑暗中捅了一刀,但看看这个http://www.qtcentre.org/threads/36992-Keyboard-shortcut-event-not-received.
在查看Qt文档时,似乎QGraphicsView的使用可能会导致一些与快捷方式有关的异常行为。
看起来可能有一种规范的方式来实现你想要的结果。
根据您实现上下文菜单、快捷方式和QGraphicsView的方式,您可能需要为QGraphicsView适当设置Qt::ContextMenuPolicy,并以不同的方式构建和调用菜单。
我对这个问题很感兴趣,因为我很快就需要做一些类似的事情!
- 将值指定给向量(2D)的向量中的某个位置
- 使用Unreal C++获取VR耳机的世界位置/方向
- 获取网格中心的屏幕位置
- 跳转到通过输入坐标定义的控制台屏幕位置
- 清除屏幕上的特定位置
- UE4在屏幕上的打印位置
- 在屏幕上的确切位置保存和恢复Qt小部件
- SFML 将形状绘制到屏幕上的多个位置
- 创建相对于世界位置而不是屏幕位置的形状
- 根据纬度和经度计算屏幕位置
- 如何将顶点位置传递给顶点着色器.我写了一个着色器,它不会在屏幕上绘制任何内容
- 如何在C ++中以X,Y位置启动CMD屏幕
- 如何在MFC上设置窗口位置以将其定位到屏幕顶部
- 查找QGraphicsItem的屏幕位置
- QML—启动时的主窗口位置(屏幕中心)
- 取消将二维屏幕位置投影到三维世界空间
- Qt 5,获得鼠标在屏幕上的位置
- 是否有可能钩全局窗口的创建,这样我就可以控制窗口放置在屏幕上的位置
- 无法在屏幕上的所需位置绘制矩形
- 获取wxTaskBarIcon的屏幕位置