2017-02-02 18 views
0

Моя проблема - простой, но раздражающий пользовательский интерфейс, повреждающий один. Я пытаюсь показать огромные суммы (10 тысяч) пользовательских QGraphicsItem s на QGraphicsScene. Мне также понадобится QGraphicsLayout, но, насколько мне известно, нельзя было просто разместить макет на сцене, так как макет должен быть установлен на QGraphicsWidget, а затем добавлен виджет в сцену.Отзывчивый QGraphicsWidget

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

Цель: добавить какой-то управление компоновкой сцены -> {подготовить пункт -> добавить элемент в макете -> Дисплей -> подготовить пункт ->} повторить ...

Но что У меня есть: {подготовить товар -> подготовить другой предмет ->} повторить ... -> добавить все в макет -> установить управление макетом на сцене -> показать

Итак, вопрос: какой способ создать отзывчивый макет/контейнер для сцены, который будет перерисовываться после добавления нового ребенка?

ответ

0

Из Qt инструкции:

При смене эпизодов, (например, когда элемент перемещается или преобразуется) QGraphicsScene излучает сигнал изменяется().

В нем не упоминается о addItem() и removeItem(). Надеюсь, они также охвачены.

Если да ваш может применить следующие:

обработчик

сигнал может «поймать» изменение и просит перекрасить (например, с помощью Invalidate()) сцены. (Un-) К счастью, это не сразу перерисовывает сцену (с ее родительским представлением), но делает очередь события перерисовки. Таким образом, фактическая перерисовка не выполняется до тех пор, пока цикл события не будет принят снова.

(Петля события является частью QApplication Если вы остановите приложение внутри команды, инициированной пользовательского интерфейсом вы найдете в стеке вызовов что-то вроде этого:.

Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) 
Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) 
Qt5Cored.dll!QCoreApplication::exec() 

)

You может заставить это вызвать функцию QApplication :: processEvents(). (Это даже статично.) AFAIK, обычно нет проблем, если петли событий вложены, потому что они подготовлены для этого (пока не сформирована неконцевая рекурсия).

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

+0

Спасибо за подсказку с сигнальным слотом, я воспользуюсь им. Хотя по моей проблеме это не помогло – czimbortibor

0

Удалось найти ошибку. Это было в пользовательском макете, который я создал для QGraphicsWidget.

Как doc говорит о создании макета:

Все виджеты, которые в настоящее время под управлением макет или все его субкомпоновками, автоматически становятся к этому элементу. Затем макет недействителен, а геометрия дочерних виджета настраивается в соответствии с геометрией этого объекта() и содержимымMargins(). Дети, которые явно не управляются макетом, остаются без изменений по макету после того, как он был назначен этому виджету.

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

Вызов QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem* newItem)link на каждый элемент, вставленный в макет, решил мою проблему.