Заметки по платформе Qt WebAssembly
WebAssembly (или webasm) — это формат байткода, предназначенный для выполнения в виртуальной машине внутри веб-браузера. Это позволяет развернуть приложение на устройстве с совместимым веб-браузером без каких-либо этапов установки. Приложение будет работать внутри защищенной зоны безопасности в веб-браузере. Это подходит для приложений, которым не нужен полный доступ к возможностям устройства, но которые выигрывают от быстрого и простого процесса установки.
Поддерживаемые целевые браузеры и устройства
Рабочий стол
- Chrome
- FireFox
- Safari
- Edge (Chrome)
Если браузер поддерживает WebAssembly, то Qt должен работать.
Примечание: Qt имеет фиксированное требование к WebGL, также и для приложений, которые не используют WebGL напрямую. Браузеры часто добавляют WebGL в черный список для более старых/неподдерживаемых графических процессоров.
Мобильные устройства
- Браузер Android
- Mobile Safari
Примечание: В настоящее время нет поддержки ввода текста с помощью виртуальной клавиатуры. Safari в настоящее время не поддерживает wasm-модули размера, который производит Qt.
Qt не использует функции операционной системы напрямую, и не имеет значения, например, работает ли FireFox на Windows или macOS. Qt использует некоторые адаптации операционной системы, например, для обработки клавиш ctrl/cmd на macOS.
Поддерживаемые модули Qt
Qt для WebAssembly поддерживает подмножество модулей Qt. В списке ниже перечислены текущие протестированные модули. Список можно вставить в качестве аргументов для make.
module-qtbase module-qtdeclarative module-qtquickcontrols2 module-qtwebsockets module-qtsvg module-qtcharts module-qtmqtt
Другие модули не тестировались и могут работать. Не поддерживаются: QtMultimedia и QtWebView
Известные проблемы
Обратитесь к вики.
Известные ограничения
- Отладка: вывод отладки и регистрации Qt печатается в консоли JavaScript, к которой можно получить доступ через «Инструменты разработчика» браузера или аналогичные инструменты.
- Вложенные циклы событий не поддерживаются. Приложения не должны вызывать, например, QDialog::exec() или создавать новый объект QEventLoop.
- Qt отрисовывает содержимое приложения в элемент холста и не использует другие родные DOM-элементы. Это означает, что поддержка доступности (считыватели экрана) не поддерживается, и ввод текста не будет вызывать виртуальную клавиатуру.
- WebGL требуется даже для приложений, которые сами не используют OpenGL. Большинство современных браузеров поддерживают WebGL, но обратите внимание, что некоторые браузеры добавляют в черный список определенные более старые графические процессоры. Загрузчик Qt обнаружит это и отобразит сообщение об ошибке.
- Вложенные окна OpenGL не поддерживаются. Композитор окон (в плагине платформы Qt для Wasm) поддерживает только растровые окна.
- Qt обнаружит поддержку OpenGL как OpenGL ES. На самом деле браузер будет предоставлять WebGL. WebGL основан на ES и очень похож, но есть некоторые несовместимости. См. Различия между WebGL и OpenGL.
- Приложения не имеют доступа к системным шрифтам. Файлы шрифтов должны быть распространены с приложением, например, в ресурсах Qt. Сам Qt для WebAssembly встраивает один такой шрифт.
- Высокое разрешение и масштабирование: Поддерживается рендеринг с высоким разрешением, а также установка общего размера визуального интерфейса с помощью функции масштабирования браузера. Настройки размера (и типа) шрифта браузера не влияют на приложения Qt.
- В некоторых компонентах Qt Quick Controls 2, таких как флажки, могут быть артефакты неинициализированной графической памяти.
- Доступ к сети: веб-песочница ограничивает доступ к сети подмножеством того, что доступно для нативных приложений.
- QNetworkAccessManager запросы HTTP к серверу происхождения веб-страницы или к серверу, который поддерживает CORS.
- Подключения QWebScoket к любому хосту.
- Туннелирование сокетов TCP и UDP через WebSockets с использованием веб-сервера sockify [реализованный Emscripten, не протестирован].
- Websockify v0.8.0 можно использовать для туннелирования TCP-соединений с QT5.12, но ОБЯЗАТЕЛЬНО необходимо указать подпротоколы base64 или двоичные перед вызовом QWebSocket::open().
- Например:
QWebSocket socket;
QUrl url{QString("ws://server:port")};
QNetworkRequest request{url};
request.setRawHeader("Sec-WebSocket-Protocol", "binary");
socket.open(request);
- Ожидаются предупреждения времени связывания вида: «нельзя представить литерал NaN '0x7fdae4bde910' с пользовательским битовым шаблоном».
- Ожидаемый размер (размер загрузки): Wasm-модули, созданные компилятором, могут быть большими, но хорошо сжимаются.
| Пример | gzip | brotli |
|---|---|---|
| helloglwindow (QtCore + QtGui) | 2.8M | 2.1M |
| wiggly widget (QtCore + QtGui + QtWidgets) | 4.3M | 3.2M |
| SensorTag (QtCore + QtGui + QtWidgets + QtQuick + QtCharts) | 8.6M | 6.3M |
Сжатие обычно обрабатывается на стороне веб-сервера с использованием стандартных функций сжатия: сервер сжимает автоматически или выбирает предварительно сжатые версии файлов. Обычно нет необходимости в специальной обработке wasm-файлов.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.14/qtwebassembly-platform-notes.html