Skip to content

Qt for WebAssembly

Specific issues when using Qt for WebAssembly

455 Topics 1.8k Posts
  • emscripten_set_mousedown_callback does not call the callback function

    Unsolved
    6
    0 Votes
    6 Posts
    685 Views
    8Observer88
    The Emscripten issue: emscripten_set_mousedown_callback does not call the callback function from Qt Creator
  • emscripten_request_pointerlock() returns EMSCRIPTEN_RESULT_UNKNOWN_TARGET

    Solved
    5
    0 Votes
    5 Posts
    602 Views
    8Observer88
    The bug report was closed because You need to handle this in a javascript mouse event and not a Qt mouse event. I will continue here: https://forum.qt.io/topic/157373/emscripten_set_mousedown_callback-does-not-call-the-callback-function
  • 0 Votes
    6 Posts
    655 Views
    8Observer88
    Lorn Potter added a comment in the bug report The mouse cursor is owned by the browser, and apparently setting mouse position in the browser is not allowed due to security issues. I will continue to find another way to lock a mouse cursor in the following topic: emscripten_request_pointerlock() returns EMSCRIPTEN_RESULT_UNKNOWN_TARGET
  • Configuring Qt for WebAssembly and Emscripten

    Unsolved webassembly qt 5.15 emscripten compiler error
    3
    1 Votes
    3 Posts
    2k Views
    8Observer88
    pro: wasm: INCLUDEPATH += "C:\emsdk\upstream\emscripten\cache\sysroot\include" Settings for Qt 6.6.3: [image: cfcca9e8-504f-4829-bdc6-ce7012964b63.png]
  • Unable to open WebSocket with a request parameter

    Unsolved
    5
    0 Votes
    5 Posts
    976 Views
    8Observer88
    I had a problem with connection with the server on the free Glitch hosting from WASM. I solved it by setting User-Agent. I use Qt 6.6.3. Maybe it will help: QUrl url("wss://merciful-regal-soursop.glitch.me"); QNetworkRequest request; request.setUrl(url); request.setRawHeader(QByteArray("User-Agent"), QByteArray("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36")); m_webSocket.open(request); And I had another problem with connection from Android. I was solved it like this: Get data with Qt client from deployed Node.js server using WebSockets
  • Detecting a mobile browser with Qt WebAssembly

    Solved
    4
    0 Votes
    4 Posts
    695 Views
    8Observer88
    I have replaced the follwing line in the code example above: #ifdef Q_OS_ANDROID with this one to detect iOS too: #if defined Q_OS_ANDROID || defined Q_OS_IOS
  • emscripten.h: No such file or directory

    Solved
    3
    0 Votes
    3 Posts
    692 Views
    8Observer88
    Solution is to add the following INCLUDEPATH: QT += core gui widgets INCLUDEPATH += "C:\emsdk\upstream\emscripten\cache\sysroot\include" CONFIG += c++17 SOURCES += \ main.cpp To avoid conflicting declaration do not compile for Desktop. Compile for WebAssembly.
  • Using IndexedDB in QWebAssembly

    Solved
    1
    0 Votes
    1 Posts
    240 Views
    No one has replied
  • how to view all linker errors instead of a few while using qmake for wasm

    Unsolved
    5
    0 Votes
    5 Posts
    774 Views
    O
    This worked for me: QMAKE_LFLAGS += -Wl,-error-limit=0
  • run Qt WASM across private network

    Unsolved
    3
    0 Votes
    3 Posts
    782 Views
    B
    Hello @jhayar, It seems like you're facing issues with accessing a Qt application running as WebAssembly (WASM) from other devices within the same private network. Ensure your Qt application is configured to listen on localhost (127.0.0.1) and try accessing it from another device using the host machine's IP address instead of localhost. Double-check your network configuration to ensure that devices within the same subnet can communicate. If your Qt application is served through a web server like Nginx or Apache, ensure that CORS headers are correctly set to allow access from other IP addresses within your private network. Although HTTPS is recommended for security, if it's not feasible for your private setup, consider alternatives like configuring your network or application to allow HTTP connections securely within your private environment.
  • configuring QT with webassembly issue: failed on Qt6ProtobufTools, WrapProtoc not found

    Unsolved
    4
    0 Votes
    4 Posts
    2k Views
    S
    @semlanik said in configuring QT with webassembly issue: failed on Qt6ProtobufTools, WrapProtoc not found: -skip qtgrpc also can help in this case, if you don't need it in your Qt build. Yep - or uninstall Qt Protobuf component using the maintaince tool.
  • how to enable JSPI to use QSettings::WebIndexedDBFormat

    Unsolved
    4
    0 Votes
    4 Posts
    1k Views
    L
    @jsulm Thank you for your answer. I forgot to mention it. In fact, my chrome has enabled JSPI, but the error is as mentioned above...
  • 3D With Web Assembly

    Unsolved
    4
    0 Votes
    4 Posts
    927 Views
    lorn.potterL
    Probably not, as Qt3D makes liberal use of threads, and webassmbly (WebGL) only works in the main thread (WebWorker)
  • 1 Votes
    3 Posts
    586 Views
    S
    With normal caveats regarding "threads" (web workers in web parlance) you could just run your data simulation in a thread and then use the main thread to update your VBO and render.
  • Qt Creator runs WebAssembly in Internet Explorer

    Solved
    3
    0 Votes
    3 Posts
    553 Views
    8Observer88
    It works now on Chrome. I just have restarted Qt Creator.
  • How to include 3rd party library

    Unsolved
    6
    0 Votes
    6 Posts
    901 Views
    8Observer88
    @Saju I didn't use OpenCV. But try these steps that I use for another libraries: Add C:\emsdk\upstream\emscripten to the Path variable cd opencv-1.2.3 && mkdir build && cd build emcmake cmake .. emmake make INCLUDEPATH += "E:/libs/opencv-1.2.3/include" LIBS += -L"E:/libs/opencv-1.2.3/build/lib" LIBS += -lopencv
  • Problem using QFileDialog::saveFileContent on Chrome

    Unsolved
    3
    0 Votes
    3 Posts
    807 Views
    R
    Hello, @ryan1969. The problem was the saveFileContent function was being called at the end of a procedure that took a long time. I guess the browser could not link the function with the click event as you said. So I had to add another button for the user to click when the procedure finishes. This made everything work OK. Thank you for the help.
  • Qt6.7 Drag and Drop on WebAssembly

    Unsolved
    7
    0 Votes
    7 Posts
    971 Views
    JonBJ
    @PEPSoares said in Qt6.7 Drag and Drop on WebAssembly: QFile cannot open the file because the file does not exist.... That does not surprise me. One would assume that the file is clearly a temporary file, valid somehow during the drag & drop, then removed. That is why I asked only if you could access the directory, not the file. Btw: QDir can access "/qt/tmp" The question was for //qt/tmp, not /qt/tmp.
  • How to use fileDialog with QML for Web Assembly

    Unsolved
    5
    0 Votes
    5 Posts
    1k Views
    J
    @Gilboonet it's been a while since you've asked the question, but as I found it then I'll just reply for future generations :) Basically you can't directly access any files on your devices from WASM. You need to use Browser API to achieve this, so the only option is to call native browser file picker for open & browser download for saving. You can pick which file to open, but when you save, then it's gonna be downloaded by a browser like any other file from a web (yes, it'll be saved in Downloads folder). It seems that Qt also supports file picking on WASM but unfortunately I didn't have a chance to test it yet: https://doc.qt.io/qt-6/qfiledialog.html#getOpenFileContent Here's a great example on how to use native file picker in Qt project: https://github.com/msorvig/qt-webassembly-examples/tree/master/gui_localfiles Here's my code, heavily based on above example, if you're interested: std::function<void(const QByteArray &, const QString &)> fileDataReadyCallback; extern "C" EMSCRIPTEN_KEEPALIVE void wasmFileDataReadyCallback(char *content, size_t contentSize, const char *fileName) { if (fileDataReadyCallback == nullptr) return; QByteArray data(content, contentSize); free(content); fileDataReadyCallback(data, QString::fromUtf8(fileName)); fileDataReadyCallback = nullptr; } void WasmPlatformIntegration::openFile() { openFile("*", [](const QByteArray &content, const QString &fileName) { qDebug() << "load file" << fileName << "size" << content.size(); }); } void WasmPlatformIntegration::openFile(const QString &fileNameFilter, std::function<void(const QByteArray &, const QString &)> fileDataReady) { if (::fileDataReadyCallback) puts("Warning: Concurrent loadFile() calls are not supported. Cancelling " "earlier call"); ::fileDataReadyCallback = nullptr; ::wasmFileDataReadyCallback(nullptr, 0, nullptr); ::fileDataReadyCallback = fileDataReady; EM_ASM_( { const fileNameFilter = UTF8ToString($0); // Crate file file input which whil display the native file dialog let fileElement = document.createElement("input"); document.body.appendChild(fileElement); fileElement.type = "file"; fileElement.style = "display:none"; fileElement.accept = fileNameFilter; fileElement.onchange = function(event) { const files = event.target.files; // Read files for (var i = 0; i < files.length; i++) { const file = files[i]; var reader = new FileReader(); reader.onload = function() { const name = file.name; let contentArray = new Uint8Array(reader.result); const contentSize = reader.result.byteLength; const heapPointer = _malloc(contentSize); const heapBytes = new Uint8Array(Module.HEAPU8.buffer, heapPointer, contentSize); heapBytes.set(contentArray); // Null out the first data copy to enable GC reader = null; contentArray = null; // Call the C++ file data ready callback ccall("wasmFileDataReadyCallback", null, [ "number", "number", "string" ], [ heapPointer, contentSize, name ]); }; reader.readAsArrayBuffer(file); } // Clean up document document.body.removeChild(fileElement); }; // onchange callback // Trigger file dialog open fileElement.click(); }, fileNameFilter.toUtf8().constData()); } void WasmPlatformIntegration::saveFile(const QByteArray &content, const QString &fileNameHint) { EM_ASM_( { const contentPointer = $0; const contentLength = $1; const fileNameHint = UTF8ToString($2); const fileContent = Module.HEAPU8.subarray(contentPointer, contentPointer + contentLength); const arrayBuffer = fileContent.slice(); const uint8Array = new Uint8Array(arrayBuffer); uint8Array.fill(255); const fileblob = new Blob([arrayBuffer]); // Create a hidden download link and click it programatically let link = document.createElement("a"); document.body.appendChild(link); link.download = fileNameHint; link.href = window.URL.createObjectURL(fileblob); link.style = "display:none"; link.click(); document.body.removeChild(link); }, content.constData(), content.size(), fileNameHint.toUtf8().constData()); }
  • QtLoader is deprecated in qt6.6.0

    Unsolved
    7
    0 Votes
    7 Posts
    2k Views
    E
    If you want to fetch your wasm file from a server using the new Qt 6.6 qt loader api you can do it like this: const wasmPromise = WebAssembly.compileStreaming(fetch(url)); const instance = await qtLoad({ qt: { onLoaded: () => { loadingScreen.style.display = "none"; }, onExit: exitData => { console.log(exitData); }, entryFunction: window.createQtAppInstance, containerElements: [mainScreen], module: wasmPromise, } });