Как я могу опубликовать событие рисования с приоритетом?

У меня проблемы с производительностью программы, которую я создаю с помощью Qt. Проблема связана с большим количеством растровых изображений, которые я обновляю каждые 16 мс; для их обновления требуется около 300 мс. Я не доволен этим, но большая проблема заключается в задержке, которую это создает в остальной части пользовательского интерфейса. Я хотел бы иметь возможность снизить приоритет обновлений, чтобы огромное количество paintEvents не блокировало цикл событий для остальной части пользовательского интерфейса, но у меня возникают трудности. Поскольку update() и repaint() не имеют параметра приоритета, я попытался использовать QCoreApplication::postEvent(), но, похоже, мне не разрешено вызывать paintEvent таким образом, потому что я получаю это сообщение об ошибке:

QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setOpacity: Painter not active
QPainter::setFont: Painter not active
QWidget::paintEngine: Should no longer be called

Вот источник моих проблем, массив из 240 QLabels, которые я обновляю сразу каждые 16 мс:

if (ui->objectSlotTabs->currentIndex() == 1) {
    for (int c = 0; c < 240; c++) {
        QEvent* event = new QEvent(QEvent::Paint);
        QCoreApplication::postEvent((*(ui->mArray))[c], event, -1);} }

РЕДАКТИРОВАТЬ: Вот пример изображения того, что делает программа и почему так важны QLabels (Моя программа - это окно слева):

пример


person knockonwood    schedule 22.05.2015    source источник
comment
Кроме того, мне пришлось отформатировать сообщение об ошибке как код, потому что в противном случае это не позволило бы мне опубликовать вопрос.   -  person knockonwood    schedule 22.05.2015
comment
Вы публикуете события для ярлыков, которые, возможно, не изменились?   -  person inetknght    schedule 22.05.2015
comment
Нет, я даю им новые данные прямо перед этим.   -  person knockonwood    schedule 22.05.2015
comment
Мне кажется, что вы пытаетесь решить не ту проблему, проблема в том, что вы пытаетесь обновить 240 QLabels... Может быть, вы должны показать нам, зачем вам нужны все эти QLabels?   -  person cmannett85    schedule 22.05.2015
comment
Это в основном весь смысл программы; Я использую его для обновления в реальном времени 240 объектов (представленных небольшими растровыми изображениями) в другом процессе. Поскольку другой процесс — это игра, которая работает со скоростью 60 кадров в секунду, я должен обновлять все QLabels с одинаковой частотой.   -  person knockonwood    schedule 22.05.2015
comment
Итак, другой процесс отправляет вам растровые изображения? Как растровые изображения расположены на экране - можете выложить скриншот?   -  person cmannett85    schedule 22.05.2015
comment
Нет, я загружаю все растровые изображения, которые я использую, в QPixmaps и масштабирую их при запуске программы, поэтому я подумал, что их рисование не будет таким ресурсоемким. Это делает его намного быстрее, но отставание по-прежнему остается большой проблемой. Также добавлен скриншот программы кстати.   -  person knockonwood    schedule 22.05.2015
comment
Вы действительно профилировали его и знаете, что события рисования являются реальной проблемой? Вы уверены, что вам нужно обновлять метки с каждым кадром (я сомневаюсь, что пользователь сможет так быстро заметить изменения), а не с каждым N кадром?   -  person Frank Osterfeld    schedule 22.05.2015
comment
мне не удалось заставить QML Profiler работать (я действительно писал об этом некоторое время назад, но не получил ответов: stackoverflow.com/questions/30200747/). Однако, когда я не запускаю этот цикл обновления, задержки вообще нет, поэтому я почти уверен, что причина в этом, тем более что QPixmaps уже существуют. Я пытался обновлять реже, но, поскольку все обновления идут последовательно, он все еще ненадолго запаздывает всякий раз, когда обновляются метки.   -  person knockonwood    schedule 22.05.2015
comment
Поскольку вы здесь не используете QML, профилировщик qml в любом случае не поможет, я бы попробовал codersnotes.com/ сонный   -  person Frank Osterfeld    schedule 22.05.2015
comment
Я запустил его, но не совсем уверен, как интерпретировать результаты... imgur.com/GYyHGa9   -  person knockonwood    schedule 22.05.2015


Ответы (1)


Есть два решения (среди многих):

  1. Пока вы обновляете метки, отключите обновления в родительском виджете меток. Повторно включите обновления, когда закончите обновление ярлыков.

  2. Используйте QGraphicsView и поместите в него QGraphicsPixmapItem вместо меток.

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

person Kuba hasn't forgotten Monica    schedule 22.05.2015
comment
Я не уверен, что понимаю преимущества (1); задержит ли это обновления до подходящего времени? Что касается (2), QGraphicsView работает лучше? Если да, то обязательно поменяю. Кроме того, идея предоставления обновлениям пониженного приоритета заключалась в том, чтобы позволить другим событиям, таким как нажатие флажков или кнопок, опережать события рисования в очереди и позволить пользовательскому интерфейсу, по крайней мере, работать гладко. Не знаю, если мое мышление ошибочно. - person knockonwood; 22.05.2015