如何获取 QGraphicsScene 的小部件(QGraphicsProxyWidget)?

Posted

技术标签:

【中文标题】如何获取 QGraphicsScene 的小部件(QGraphicsProxyWidget)?【英文标题】:How to get widgets (QGraphicsProxyWidget) of QGraphicsScene? 【发布时间】:2015-09-26 20:35:24 【问题描述】:

我正在使用 QGraphicsScene 并通过隐式创建的 QGraphicsProxyWidget 对象向其添加常规小部件(QLineEditQComboBox 等):

m_pLineEdit = new QLineEdit("", 0);
m_pProxy = m_pGraphicsScene->addWidget(m_pLineEdit);

我目前正在寻找一种方法,以便以后再次从场景中检索这些小部件进行处理,但找不到。

我已经尝试了以下方法:

    由于我无法将图形场景作为父级传递给小部件构造函数,因此无法通过m_pGraphicsScene->findChildren(QLineEdit*) 检索小部件,因为没有直接关系。 图形场景确实有一个 QGraphicsSceneBspTreeIndex 子级,但这不是官方 Qt API 的一部分,因此不能依靠它。

底线:如何从 Qt 图形场景中获取所有 QGraphicsProxyWidget 对象?这可以在 Qt 标准中完成,还是我必须继承 QGraphicsScene 并尝试自己管理小部件?

【问题讨论】:

【参考方案1】:

底线:如何从 Qt 图形场景中获取所有 QGraphicsProxyWidget 对象?

通过 scene->items() 获取场景中所有项目的列表,然后检查它们是否属于正确的类:

// Horrible C++98 code which doesn't even feature algorithms

QList<QGraphicsItem *> items = scene->items();
foreach (QGraphicsItem *item, items) 
    QGraphicsProxyWidget *w;
    if (w = qgraphicsitem_cast<QGraphicsProxyWidget *>(item)) 
        use(w);
    

但是,我想强调的是,您应该真正跟踪您放置在场景中的物品。 (至少,您以后有兴趣使用的那些)。走过现场并检索这样的项目似乎非常脆弱,这是代码质量差和设计差的信号。请注意,您有 addWidget 调用返回的代理,只需将其保存在某处即可。

【讨论】:

【参考方案2】:

在发布问题后,我偶然在 Qt 源代码中找到了解决方案。小部件代理在内部被视为常规 QGraphicsItem 并且可以通过 qgraphicsitem_cast 进行转换:

QList<QGraphicsItem*> graphicsItemList = m_pGraphicsScene->items();
foreach(QGraphicsItem* pGraphicsItems, graphicsItemList)

    QGraphicsProxyWidget* pProxy = qgraphicsitem_cast<QGraphicsProxyWidget*>(pGraphicsItems);
    if(pProxy)
    
        QLineEdit* pLineEdit = qobject_cast<QLineEdit*>(pProxy->widget());
        if(pLineEdit)
            // do stuff
    
   

如果有人知道更简单/更快的方法,我很乐意听到。在此之前,我将使用上述方法。

【讨论】:

以上是关于如何获取 QGraphicsScene 的小部件(QGraphicsProxyWidget)?的主要内容,如果未能解决你的问题,请参考以下文章

在 QGraphicsScene 上为小部件设置系统背景的背景颜色

查看整个 QGraphicsScene

如何在场景 QGraphicsScene 上居中小部件

QGraphicsScene 中的位移

在使用 swiftui 的小部件中如何获取当前位置? [复制]

如何获取具有焦点的小部件