1

I am making use of a QGraphicsScene and I am adding regular widgets (QLineEdit, QComboBox, etc.) to it via implicitly created QGraphicsProxyWidget objects:

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

I am currently searching for a way to later retrieve those widgets from the scene again for processing, but am not able to find one.

I tried the following approaches already:

  1. Since I cannot pass the graphics scene as parent to the widget constructor, retrieving the widgets via m_pGraphicsScene->findChildren(QLineEdit*) does not work, since there is no direct relation.
  2. The graphics scene does have a QGraphicsSceneBspTreeIndex child, but that is not part of the official Qt API and therefore relying on it cannot be the way to go.

Bottom-line: How can I get all the QGraphicsProxyWidget objects from a Qt graphics scene? Can this be done in the Qt standard or do I have to subclass QGraphicsScene and try to manage the widgets myself?

Philip Allgaier
  • 3,505
  • 2
  • 26
  • 53

2 Answers2

1

Bottom-line: How can I get all the QGraphicsProxyWidget objects from a Qt graphics scene?

Get the list of all the items in the scene via scene->items() , then check if they're of the right class:

// 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);
    }
}

However, I'd like to stress that you should really keep track of the items you put in the scene. (At least, the ones you're interested in using afterwards). Walking over the scene and retrieving the items like this seems very fragile, and it's a signal of poor code quality and poor design. Note that you have the proxy returned by the addWidget call, just save it somewhere.

peppe
  • 21,934
  • 4
  • 55
  • 70
1

Just after posting the question I by chance found a solution in the Qt source code. The widget proxies are treated as regular QGraphicsItem internally and can be casted via 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
    }
}   

If someone knows a simpler/faster method, I'd be happy to hear about it. Until then I will use the approach outlined above.

Philip Allgaier
  • 3,505
  • 2
  • 26
  • 53