Как получить виджеты (QGraphicsProxyWidget) из QGraphicsScene?

Я использую QGraphicsScene и я добавляю обычные виджеты (QLineEdit, QComboBoxи т. д.) к нему через неявно созданный QGraphicsProxyWidget объекты:

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

В настоящее время я ищу способ позже извлечь эти виджеты со сцены для обработки, но не могу найти.

Я уже попробовал следующие подходы:

  1. Поскольку я не могу передать графическую сцену в качестве родителя конструктору виджета, извлечение виджетов осуществляется с помощью m_pGraphicsScene->findChildren(QLineEdit*) не работает, так как нет прямой связи.
  2. Графическая сцена имеет QGraphicsSceneBspTreeIndex ребенок, но это не является частью официального API Qt, и поэтому полагаться на него нельзя.

Итог: как я могу получить все QGraphicsProxyWidget объекты из графической сцены Qt? Можно ли это сделать в стандарте Qt или мне нужно создать подкласс QGraphicsScene и попробовать самостоятельно управлять виджетами?

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
    }
}   

Если кто-то знает более простой / быстрый метод, я был бы рад услышать об этом. До тех пор я буду использовать подход, изложенный выше.

Итог: Как я могу получить все объекты QGraphicsProxyWidget из графической сцены Qt?

Получить список всех предметов в сцене через 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 позвони, просто сохрани где-нибудь.

Другие вопросы по тегам