Skip to content

Qt for WebAssembly

Specific issues when using Qt for WebAssembly

452 Topics 1.8k Posts
QtWS25 Last Chance
  • Backspace key does nothing in text inputs, only on Android

    Unsolved
    3
    2 Votes
    3 Posts
    356 Views
    JasonWongJ

    I think this issue is the similar as being unable to input Chinese characters. Currently, there are input issues when using Qt with WebAssembly. You can refer to this problem, which has seen no progress, T.T

    https://bugreports.qt.io/browse/QTBUG-107139

  • Failed to show GUI in WASM after JavaScript call

    Solved
    8
    0 Votes
    8 Posts
    565 Views
    8Observer88

    I wrote an example that play a sound using Web Audio API in Qt WebAssembly. It is a 2D sound but Web Audio API can play 3D sounds too. There are two buttons in this example: "Run" and "Play". The "Run" button must be pressed first and next the "Play" button must be pressed. You can run it by one click: https://replit.com/@8Observer8/play-audio-with-web-audio-api-qt6-cpp

    a4eaf8a3-6b99-4c83-a597-8a85d1b4a559-image.png

    main.cpp

    #include <QtWidgets/QApplication> #include <QtWidgets/QPushButton> #include <QtWidgets/QVBoxLayout> #include <QtWidgets/QWidget> #include <emscripten.h> EM_JS(void, call_init, (), { my_init(); }) EM_JS(void, call_run, (), { my_run(); }) EM_JS(void, call_play, (), { playSound(); }) class Widget : public QWidget { Q_OBJECT public: Widget() { call_init(); runButton = new QPushButton("Run"); playButton = new QPushButton("Play"); playButton->setEnabled(false); QVBoxLayout *vbox = new QVBoxLayout(); vbox->addWidget(runButton); vbox->addWidget(playButton); vbox->addStretch(); setLayout(vbox); connect(runButton, &QPushButton::pressed, this, &Widget::runButtonClick); connect(playButton, &QPushButton::pressed, this, &Widget::playButtonClick); } private slots: void runButtonClick() { call_run(); runButton->setEnabled(false); playButton->setEnabled(true); } void playButtonClick() { call_play(); } private: QPushButton *runButton; QPushButton *playButton; }; #include "main.moc" int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }

    my_script.js

    let audioContext, decideArrayBuffer, decideAudioBuffer; async function my_init() { console.log("init"); const decideResponse = await fetch("assets/sounds/decidemp3-14575.mp3"); decideArrayBuffer = await decideResponse.arrayBuffer(); } async function my_run() { console.log("my run"); audioContext = new window.AudioContext(); decideAudioBuffer = await audioContext.decodeAudioData(decideArrayBuffer); } function play(audioBuffer, isLoop = false) { const source = audioContext.createBufferSource(); source.buffer = audioBuffer; source.loop = isLoop; const gain = audioContext.createGain(); source.connect(gain).connect(audioContext.destination); gain.gain.value = 0.3; source.start(); return source; } function playSound() { play(decideAudioBuffer); }
  • 0 Votes
    6 Posts
    520 Views
    A

    @8Observer8 Thank you for your response. I'll keep an eye on the bug report.

  • 0 Votes
    7 Posts
    643 Views
    8Observer88

    I found a temporary solution that is good for me for now. I just deleted the sampling:

    OpenGLWidget() { // QSurfaceFormat surfaceFormat; // surfaceFormat.setMajorVersion(3); // surfaceFormat.setMinorVersion(0); // surfaceFormat.setSamples(4); // setFormat(surfaceFormat); }

    In this case I don't need to use GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER to read a pixel color using glReadPixels():

    void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); // // Set draw buffer to be fbo. Read buffer is already the default one // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo->handle()); // // Blit from the default MSAA buffer to non-MSAA fbo // glBlitFramebuffer(0, 0, m_fbo->width(), m_fbo->height(), // 0, 0, m_fbo->width(), m_fbo->height(), // GL_COLOR_BUFFER_BIT, GL_NEAREST); // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context()->defaultFramebufferObject()); // // Set read buffer // glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo->handle()); // Read the pixel GLubyte pixel[4]; glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); // Set read buffer back to default // glBindBuffer(GL_READ_FRAMEBUFFER, context()->defaultFramebufferObject()); qDebug() << pixel[0] / 255.f << pixel[1] / 255.f << pixel[2] / 255.f; emit showPixelColorSignal(QVector3D(pixel[0] / 255.f, pixel[1] / 255.f, pixel[2] / 255.f)); }

    My applications works correctly on Android and WebAssembly. It read a pixel with green color (0, 1, 0):

    Android:

    a0b95b4f-30f1-4a9f-8c1f-d726fd90577e-image.png

    WebAssembly:

    730c5fca-dd06-454c-9f10-2320426c8a0a-image.png

  • Where is the em++ compiler located? How to install it?

    Solved
    4
    3 Votes
    4 Posts
    633 Views
    8Observer88

    I deleted the C:\emsdk folder and I deleted the C:\emsdk from Path. I run a new CMD. Typed this command:

    git clone https://github.com/emscripten-core/emsdk.git

    And this one: "emsdk.bat" install 3.1.37

    The emsdk was installed without problems:

    C:\emsdk>"emsdk.bat" install 3.1.37 Resolving SDK version '3.1.37' to 'sdk-releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit' Installing SDK 'sdk-releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'.. Installing tool 'node-16.20.0-64bit'.. Downloading: C:/emsdk/downloads/node-v16.20.0-win-x64.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v16.20.0-win-x64.zip, 28623474 Bytes Unpacking 'C:/emsdk/downloads/node-v16.20.0-win-x64.zip' to 'C:/emsdk/node/16.20.0_64bit' Done installing tool 'node-16.20.0-64bit'. Installing tool 'python-3.9.2-nuget-64bit'.. Downloading: C:/emsdk/downloads/python-3.9.2-4-amd64+pywin32.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/python-3.9.2-4-amd64+pywin32.zip, 14413267 Bytes Unpacking 'C:/emsdk/downloads/python-3.9.2-4-amd64+pywin32.zip' to 'C:/emsdk/python/3.9.2-nuget_64bit' Done installing tool 'python-3.9.2-nuget-64bit'. Installing tool 'java-8.152-64bit'.. Downloading: C:/emsdk/downloads/portable_jre_8_update_152_64bit.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/portable_jre_8_update_152_64bit.zip, 69241499 Bytes Unpacking 'C:/emsdk/downloads/portable_jre_8_update_152_64bit.zip' to 'C:/emsdk/java/8.152_64bit' Done installing tool 'java-8.152-64bit'. Installing tool 'releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'.. Downloading: C:/emsdk/downloads/7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-wasm-binaries.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2/wasm-binaries.zip, 419522512 Bytes Unpacking 'C:/emsdk/downloads/7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-wasm-binaries.zip' to 'C:/emsdk/upstream' Done installing tool 'releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'. Done installing SDK 'sdk-releases-7c905cfc1ca6699f6ccb288ae174902cfbdcf0a2-64bit'.

    I activated the 3.1.37 version: "emsdk.bat" activate 3.1.37

    I added the C:\emsdk path to Qt Creator here: Edit -> Preferences... -> Devices -> WebAssembly

    812f3135-61de-48ac-aa90-b4bd11f8f687-image.png

    I created a new project and it works!

    7f997f8b-9ed0-4b9f-9d47-704c0be1209b-image.png

    main.cpp

    #include <QtWidgets/QApplication> #include <QtWidgets/QWidget> #include <QtWidgets/QLabel> #include <QtWidgets/QVBoxLayout> class Widget : public QWidget { public: Widget() { QLabel *label = new QLabel("Hello, WebAssemlym, from Qt!"); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(label); setLayout(layout); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); Widget w; w.show(); return app.exec(); }

    pro

    QT += core gui widgets CONFIG += c++17 SOURCES += \ main.cpp
  • Qt Widget for WASM and CMake command line..

    Unsolved
    11
    0 Votes
    11 Posts
    1k Views
    1

    @Mesrine i will try using linux and comment..
    thanks.

  • using qtquick but see nothing on browser

    Unsolved
    3
    0 Votes
    3 Posts
    310 Views
    1

    @lorn-potter hi, my apologies for long time non responding...

    you know im Miguel Marambio, the one that have summit a bug report here:

    https://bugreports.qt.io/browse/QTBUG-119327

    Thanks.

  • Widget can't move after set the windowFlag to Qt::Window

    Solved
    4
    0 Votes
    4 Posts
    367 Views
    GaoboG

    @jsulm
    thanks;

    If you want to show it as a window then do not set a parent.

    Under windows, it show as a window when i not set parent for form. but under web(browser), it doesn't show. why?

    What difference between Qt::window and Qt::widget?

    when i set Qt::Dialog to windowFlat, widget become moveable. why?

    and i set it to dialog and set parent, form can normally show and move. why?

  • How to enable WebAssembly debugging?

    Unsolved
    1
    0 Votes
    1 Posts
    191 Views
    No one has replied
  • zip binaries

    Unsolved
    5
    0 Votes
    5 Posts
    649 Views
    JasonWongJ

    Do not manually compress these files; you can leave it to Nginx to handle automatically. After adding these configurations to my Nginx conf file, automatic compression is enabled:

    gzip on; gzip_min_length 32k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain text/css text/xml application/xml application/json text/javascript application/javascript application/octet-stream;

    You can visit this address to see the compression effect. Open the F12 console in Chrome, and you will notice that the wasm file has been compressed.
    https://web.jasonserver.com:10035/JQClock/JQClock.html

  • This topic is deleted!

    Unsolved
    1
    0 Votes
    1 Posts
    10 Views
    No one has replied
  • 0 Votes
    8 Posts
    2k Views
    V

    Just found here after tearing my hair out with this exact problem using Qt 6.5.1

    It's there even in the LTS T_T

  • GTK issues with Webassembly builds ?

    Unsolved
    1
    0 Votes
    1 Posts
    332 Views
    No one has replied
  • 0 Votes
    3 Posts
    257 Views
    G

    @JKSH Thank You !

  • WebAssembly - Qt 6.6.0 - Embind

    Unsolved
    2
    1 Votes
    2 Posts
    390 Views
    J

    I realized that I can easily get access to my JavascriptPublicInterface again, by slightly modifying the generated myapp.html :
    so from :

    async function init() { const spinner = document.querySelector('#qtspinner'); const screen = document.querySelector('#screen'); const status = document.querySelector('#qtstatus'); const showUi = (ui) => { [spinner, screen].forEach(element => element.style.display = 'none'); if (screen === ui) screen.style.position = 'default'; ui.style.display = 'block'; } try { showUi(spinner); status.innerHTML = 'Loading...'; const instance = await qtLoad({

    I updated to :

    var instance = null async function init() { const spinner = document.querySelector('#qtspinner'); const screen = document.querySelector('#screen'); const status = document.querySelector('#qtstatus'); const showUi = (ui) => { [spinner, screen].forEach(element => element.style.display = 'none'); if (screen === ui) screen.style.position = 'default'; ui.style.display = 'block'; } try { showUi(spinner); status.innerHTML = 'Loading...'; instance = await qtLoad({

    so now I can call instance.self().setMyProperty("something") .

  • Bitmap cursor

    Unsolved
    1
    0 Votes
    1 Posts
    187 Views
    No one has replied
  • got my app running...

    Unsolved
    4
    0 Votes
    4 Posts
    370 Views
    MesrineM

    @mzimmers
    Normally, those files are distributed over the internet through a web server.
    Like:
    https://eddytheco.github.io/NftMinter/
    Github uses a server to distribute those files to clients(browsers).

    But if your client downloads those files and serves them under his own server, it is the same.

    They can invoke the application locally in the same way you do when testing and developing. By running emrun, or with a python webserver, in general, using a web server. Some applications must use https(secure environment).

  • Error while running XaoS as a web application in Qt6

    Solved
    5
    1 Votes
    5 Posts
    565 Views
    Z

    After fixing the Emscripten version, this problem is solved.

  • This topic is deleted!

    Unsolved
    1
    0 Votes
    1 Posts
    1 Views
    No one has replied
  • 0 Votes
    1 Posts
    255 Views
    No one has replied