Изменение размера/перемещение окна QML

Я разрабатываю простое приложение QML прямо сейчас, и я заметил, что изменение размера и перемещение окна QML генерирует уродливое мерцание по сравнению с окном QtWidgets, например.

Итак, я создал 2 тестовых приложения, чтобы показать разницу:

QWidgets:

enter image description here

QML:

enter image description here

Как видите, версия приложения QML мерцает довольно уродливо, а QtWidgets - чистая. Теперь это становится довольно уродливым, когда ваш пользовательский интерфейс растет с трудом.

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

Ответ 1

Вы можете попробовать следующее:

int main(int argc, char* argv[]) {
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
or
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);

Первый вариант использует библиотеку углов OpenGl2DirecX (например, Google Chrome).

Второй использует эмуляцию OpenGL с помощью программного обеспечения... для небольших программ работает очень хорошо и на 100% совместимо со старой ОС, такой как Windows XP.

Примечание. Вы можете попробовать с Qt 5.7, а новый Qtquick.Controls 2.0... работает намного лучше... https://blog.qt.io/blog/2016/06/10/qt-quick-controls-2-0-a-new-beginning/

Ответ 2

В моем случае я решил это, добавив следующий флаг:

QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);

Но это добавит другие проблемы с рендерингом. Или нет.

Ответ 3

Проблема с изменением размера приложений QML заключается в обновлении окна с устаревшей геометрией. Исправление будет заключаться в синхронизации обновлений и изменения размера.

Так как могут быть внезапные обновления от таймера обновления для визуализации графа сцены, который может обновлять окно в любое время, это вызывает рисование содержимого с устаревшей геометрией. https://bugreports.qt.io/browse/QTBUG-46074

Для синхронизации изменения размера и обновления окна следует использовать либо базовую, либо расширенную синхронизацию. В настоящее время базовая синхронизация используется и реализована в Qt, но все же необходимо синхронизировать обновления окна (из таймера) с событиями изменения размера из Windows Manager.

Но, как всегда, есть список вопросов:

Проблема наблюдается, когда размер окна изменяется слишком быстро. Поскольку синхронизация событий (от WM) должна отправляться последовательно, следующий за предыдущим:

  1. <= _NET_WM_SYNC_REQUEST отправлено с WM, размер сейчас меняется.

  2. _NET_WM_SYNC_REQUEST получено и обработано приложением.

  3. <= получены некоторые другие события, например новая геометрия.

  4. .. обновить содержимое, swapBuffers.

  5. => Отправлено _NET_WM_SYNC_REQUEST_COUNTER обратно в WM.

  6. <= _NET_WM_SYNC_REQUEST снова отправляется с WM, размер меняется.

  7. .. swapBuffers//здесь проблема, обновление выполняется, когда окно меняет свою геометрию.

  8. _NET_WM_SYNC_REQUEST получен и обработан снова.

Таким образом, проблема возникает, когда (7) swapBuffers появляется после того, как _NET_WM_SYNC_REQUEST отправлено, но еще не получено/обработано.

И напоследок вывод:

  • Фактическое изменение размера окна начинается сразу после отправки _NET_WM_SYNC_REQUEST Диспетчером окон. И не когда приложение получит его. В это время окно может быть даже обновлено, когда запрос на синхронизацию отправляется, но еще не обрабатывается приложением. Который будет рисовать контент с устаревшей геометрией.
  • _NET_WM_FRAME_DRAWN может помочь в синхронизации между изменением размера и обновлениями, но также может не поддерживаться (и предполагаю, что это не так) диспетчером окон.

Другими словами, базовая или расширенная синхронизация не помогает (по крайней мере, без _NET_WM_FRAME_DRAWN), потому что нет способа узнать, когда фактическое изменение размера выполнено.

Расширенный протокол синхронизации - это попытка справиться с этим, но поскольку фактическое изменение геометрии выполняется без синхронизации с клиентом, как я вижу, без _NET_WM_FRAME_DRAWN всегда есть возможность обновить окно устаревшей геометрией.

https://lists.freedesktop.org/archives/xcb/2019-February/011280.html