- PVSM.RU - https://www.pvsm.ru -
Qt Everywhere— так именуются архивы с исходниками Qt. В 5.12.0 завезут WebAssembly и WebGL стриминг и everywhere звучит уже по другому. Так и просилось что-нибудь запрототипироват. Был быстро накидан прототип чатика [1] на веб-сокетах, что бы протестировать поддержку сети. Под катом будет инструкция по сборке и запуска проекта на WebAssembly, пример вызова JavaScript из С++.
Сперва нужно поставить toolchain emscripten [2], которым будем собирать Qt. Не забудьте прописать переменные окружения, что бы qmake нашел emcc. Скрипт configure
запускался со следующими параметрами:
./configure
-prefix /home/dmitry/Qt/5.12.0/wasm
-xplatform wasm-emscripten
-confirm-license -opensource
-nomake tests
-c++std c++1z
-nomake examples
-release
-no-dbus
-skip qtxmlpatterns
-skip qttools
Дальше как и везде:
$ make
$ make install
Сборка и запуск проекта
$ ~/Qt/5.12.0/wasm/bin/qmake
$ make
$ emrun chat.html
Зашивать url на котором висит бэкенд не очень хорошо, т.к. захочется запускать на произвольном порту. В случает работы из браузера нужно взять location.hostname
и location.port
что бы определить где запущен бэкенд. Для этого придется немного пописать на JavaScript.
Для любителей дефайнов есть Q_OS_WASM
, я же предпочитаю выносить код в pimpl и отдельные файлы. Pimpl здесь лишний, но код разнесу на разные файлы
Заведем какой-нибудь конфиг
//config.h
#pragma once
#include <QtCore/QUrl>
class Config
{
public:
static QUrl wsUrl();
};
и две реализации
//config.cpp
#include <QtCore/QCoreApplication>
#include <QtCore/QCommandLineParser>
#include "config.h"
QUrl Config::wsUrl()
{
QCommandLineParser parser;
QCommandLineOption wsOption(QStringList() << "u" << "url"
, "WebSocket url"
, "url"
, "ws://localhost:1234");
parser.addOption(wsOption);
parser.process(*QCoreApplication::instance());
return QUrl(parser.value(wsOption));
}
//config_wasm.cpp
#include <QtCore/QByteArray>
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#include "config.h"
QUrl Config::wsUrl()
{
QByteArray buff(1024, 0);
EM_ASM_({
var url = "ws://"+ window.location.hostname + ":" + window.location.port + "/ws";
stringToUTF8(url, $0, $1);
}, buff.data(), buff.size());
return QUrl(QString::fromUtf8(buff));
}
Осталось прописать в pro файле
wasm {
SOURCES += config_wasm.cpp
} else {
SOURCES += config.cpp
}
EM_ASM_
это магия emscripten позволяющая вызывать JavaScript код из C++. Хотя можно это было сделать и без JavaScript
emscripten::val location = emscripten::val::global("location");
auto host = QString::fromStdString(location["host"].as<string>());
auto protocol = QString::fromStdString(location["protocol"].as<string>());
Десктопные браузеры: запускается и работает в Сhrome, Firefox, Safari, Edge(тут пришлось включить экспериментальные функции JavaScript). В зависимости от железа могут быть существенные задержки на компиляции WebAssembly.
В Chrome на Andorid могут пройти минуты на компиляцию WebAssembly. Сразу заметил отсутствия поддержки мобильных браузеров, а именно нет вызова системной клавиатуры, при попытки ввести текст.
Safari на iOS 12 тут приложение падает на этапе компиляции WebAssembly и я не стал дебажить. Теоретически можно перейти на asm.js, но это требует отдельного исследования.
В блоге позиционировался как VNC на веб-сокетах с отрисовкой на WebGL. Из зависимостей [3] Qt WebSockets и Qt собранный с поддержкой OpenGL ES 2 т.е. гонять на железе без GPU будет мучительно. Для её поддержки достаточно поставить Qt WebGL Streaming Plugin в онлайн установщике и запустить приложение с параметром -platform webgl
или -platform webgl:port=80
, если нужно указать порт.
Но у этой технологии есть свои ограничения:
Так же я заметил проседание fps при анимации StackView на переходах между экранами. Достоинство WebGL стриминга:
Альтернатива Wt [4] когда есть готовое приложение на C++ и к нему нужно прикрутить веб-интерфейс. Например web-интерфейс к torrent качалке.
Web интерфейс для какого-нибудь умного дома. Не даром в Qt завезли MQTT, а на msorvig/qt-webassembly-examples [5] пример mqtt_simpleclient [6]. Можно иметь общий код UI который работает на планшете и в браузере.
Код доступен на GitHub [1], подготовленные бинарники там же [7]
Автор: RPG18
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/qt-2/300264
Ссылки в тексте:
[1] чатика: https://github.com/RPG-18/qt-wasm-chat-example/tree/master/frontend
[2] emscripten: https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
[3] зависимостей: https://doc-snapshots.qt.io/qt5-5.12/webgl.html
[4] Wt: https://www.webtoolkit.eu/
[5] msorvig/qt-webassembly-examples: https://github.com/msorvig/qt-webassembly-examples/
[6] mqtt_simpleclient: https://github.com/msorvig/qt-webassembly-examples/tree/master/mqtt_simpleclient
[7] там же: https://github.com/RPG-18/qt-wasm-chat-example/releases
[8] Источник: https://habr.com/post/430954/?utm_campaign=430954
Нажмите здесь для печати.