Skip to content

Qt for WebAssembly

Specific issues when using Qt for WebAssembly

464 Topics 1.8k Posts
  • Links for Qt for WebAssembly

    Pinned Unsolved
    6
    7 Votes
    6 Posts
    4k Views
    S
    @tansgumus said in Links for Qt for WebAssembly: Fireofox 76.0 (64-bit) Fireofox 76.0 (64-bit) nooooooooooooooooooo this very bad
  • This topic is deleted!

    Unsolved
    1
    0 Votes
    1 Posts
    5 Views
    No one has replied
  • deleteLater() not deleting QNetworkReply

    Unsolved
    3
    0 Votes
    3 Posts
    55 Views
    F
    The aboutToBlock signal is not launch in wasm because the thread is always running, but the line : QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); Indeed call the delete from the deleteLater() Thank you for the help
  • My Qt Quick Web Assembly app won't to pass over the loading screen

    Unsolved
    6
    0 Votes
    6 Posts
    1k Views
    M
    I think Mesrine is right, this is telling you that your web server isnt configured correctly. In apache you'd add a configuration file like this: <Directory /var/www/html> Order Allow,Deny AllowOverride None Header set Access-Control-Allow-Origin "*" Header set Cross-Origin-Opener-Policy: same-origin Header set Cross-Origin-Embedder-Policy: require-corp </Directory>
  • Wasm apparently doesn't handle keyboard shortcuts

    Unsolved
    12
    0 Votes
    12 Posts
    2k Views
    M
    I figured out some more stuff, including a workaround for Qt 6.9.0 that doesnt require rebuilding the webassembly module from source. I'm able to reproduce this "bug" using just the calendarwidget example, so it at seems to happen in relatively simple situations. Hopefully this is helpful to other people with this same problem. I suspect there are easier ways to accomplish all of this... First off, i discovered that qt-shadow-container is defined in the file qwasmwindow.cpp which you can find in \Src\qtbase\src\plugins\platforms\wasm. From looking at that file I figured out that this div is used to display a "shadow dom" that contains the real Qt content. The importance of this is that when an element in the shadow dom has focus, document.activeElement shows the shadow root (qt-shadow-container) as the activeElement even though it isn't really. So, in fact, it's not true that qt-shadow-container has/needs focus in order for you to receive keyboard events. I discovered that when you press "Tab", the focus ACTUALLY goes to an invisible button element whose class is "hidden-visually-read-by-screen-reader". I think this is actually something of a coincidence: buttons are inherently able to receive tab focus and so this just happens to be what receives the focus when you press tab. And it's part of the shadow dom hierarchy in such a way that, when it has focus, Qt will process the keypress events that it receives. So, what does this all mean? Long story short, you can use javascript to programmatically force the "hidden-visually-read-by-screen-reader" to always have focus, which will ensure that Qt processes all of your keypress events. First problem: when you open your website, no object has focus, so we need an initial action that sets the focus. (Note, i think in Qt 6.10 it DOES initially have focus so you may not need this step) You can do this by pressing "Tab", or you can set it programmatically with javascript. It's a little difficult because the button we want to focus on doesn't exist when you first open the page (it doesnt exist until Qt creates it). So you need to delay focusing on it until you're sure it exists. I solved this by modifying the "onLoaded" callback function in generated html file to look like this: onLoaded: () => { showUi(screen); setTimeout(function() { console.log('setting initial focus'); const shadowContainer = document.getElementById('qt-shadow-container'); if(shadowContainer) { const shadowRoot = document.getElementById('qt-shadow-container').shadowRoot; if (shadowRoot) { console.log('shadow root found'); console.log(document.getElementById('qt-shadow-container')); const targetElement = shadowRoot.querySelector('.hidden-visually-read-by-screen-reader'); console.log(targetElement); targetElement.focus(); } else { console.log('Shadow Root not found or is closed.'); } } }, 1000); }, So, it waits 1 second and then sets the focus. If I dont have it wait then it fails to find the required objects. Second problem: Restore focus to this object any time no object has focus. For this I added another script to the html file that looks like this: <script> document.addEventListener('focusout', function (event) { console.log('Element lost focus:', event.target); console.log('Element gaining focus:', event.relatedTarget); if (event.relatedTarget === null) { const shadowRoot = document.getElementById('qt-shadow-container').shadowRoot; if (shadowRoot) { const targetElement = shadowRoot.querySelector('.hidden-visually-read-by-screen-reader'); console.log(targetElement); targetElement.focus(); } else { console.log('Shadow Root not found or is closed.'); } } }); </script> So, basically the same function but this time it runs when an element loses focus and no new element is gaining focus. Third problem: This one is probably a lot more obscure, but i was running into problems implementing a custom "createEditor" function on QAbstractItemDelegate where the html INPUT object corresponding to the editor never lost focus, even once "destroyEditor" ran (notably, my destroyEditor function did not delete the editor but only hid it). To solve, this, I implemented a javascript function to be called by Qt to force the input to lose focus: #ifdef Q_OS_WASM #include "emscripten.h" EM_JS(void, resetFocus, (), { console.log('removing focus from INPUT'); document.activeElement.blur(); //This takes focus away from the active element, which may be an INPUT, and returns it to the BODY element }); #endif ...then you can just call resetFocus() in any situation where you find the INPUT is keeping focus. This will trigger a focusout even and then the above function takes over. (How do you know if INPUT is keeping focus? FOr debugging i set up a QTimer that runs another javascript function that just does "console.log(document.activeElement)" every few seconds. Then you can watch the console to see what object in the DOM has keyboard focus as you test)
  • Using OpenSSL/Secure Websockets with Qt WebAssembly

    Unsolved
    5
    0 Votes
    5 Posts
    1k Views
    D
    I am having a similar issue. I have a WebAssembly app using Websockets to communication from the WebAssembly app in the client computer browser to an app on the host computer. Works fine with normal http, but we want to go to https. I tried to use the sslechoserver and sslechoclient sample apps in the QtWebSockets example area, but while they work when compiled with normal Qt, when I try to compile the sslechoclient in Qt for WebAssembly (Qt 6.10), I get errors because SSL is not supported. I get the impression you had a possible solution above, but I do not really understand what it was. Do I just use the normal echoclient (built in QtWebAssembly) requesting a wss URL combined with host sslechoserver with the same cert that the web server provides ? Thanks for the help Dale Pennington
  • Excess Static Libs when using QMake

    Solved
    9
    0 Votes
    9 Posts
    158 Views
    Christian EhrlicherC
    When all is in one directory then automoc can find them. It does not search in subdirectories. For additional sources - see target_sources cmake command
  • EM_ASYNC_JS Uncaught Error: undefined when out of the main

    Unsolved
    1
    0 Votes
    1 Posts
    32 Views
    No one has replied
  • wasm64 for Qt

    Unsolved
    1
    0 Votes
    1 Posts
    169 Views
    No one has replied
  • New qtloader

    Unsolved
    3
    0 Votes
    3 Posts
    2k Views
    M
    Hi, this might be covered by the linked to post, but to answer here as well: This was changed in 6.9, the entry/constructor function name is not hardcoded to "createQtAppInstance" any more but is now named after the application, with an "_entry" suffix. For example If you have myapp.js (and load that using e.g. a <script> tag) then you should find the constructor function at window.myapp_entry. This enables support for loading multiple wasm modules (with separate constructor functions) into a single web page, at the cost of having to name the entry function in the html code.
  • Setting up a .pro file that works for wasm_singlethread and wasm_multithread

    Unsolved
    4
    0 Votes
    4 Posts
    718 Views
    S
    Now I understand a little better what you are asking. I am not sure if there is such a thing as querying if a module exists. I'm also not using wasm and don't know if you can actually distinguish between singlethreaded and multithreaded. Here is the easiest workaround that comes to mind: Create a CONFIG variable like singlethreaded. Then you can check for it: CONFIG(singlethreaded): { } else: { QT += concurrent } On the "command line" you just add qmake CONFIG+=singlethreaded ... to your call to qmake. In QtCreator under "Projects" for the wasm_singlethreaded kit you just add CONFIG+=singlethreaded as "Additional arguments" under the qmake build step.
  • Problem to find main.qml

    Unsolved
    3
    0 Votes
    3 Posts
    744 Views
    Q
    @Christian-Ehrlicher thank you, so the working solution is SOLVED: <!DOCTYPE RCC> <RCC> <qresource prefix="/"> <file>qml/main.qml</file> </qresource> </RCC> and #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QUrl> #include <QDirIterator> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:qml/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); } I am happy!!!
  • How to decode QR Code on wasm ?

    Solved
    7
    0 Votes
    7 Posts
    5k Views
    L
    @Mesrine Thanks, I also realize it is this problem and am trying to compile multi-threaded Opencv-wasm library
  • wasm-ld: error: duplicate symbol from libqt6core

    Unsolved
    3
    0 Votes
    3 Posts
    531 Views
    KyefK
    Thank you @jsulm for the response. Here is my CMakeLists.txt below: CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(demoApp VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(QT_QML_GENERATE_QMLLS_INI ON) find_package(Qt6 6.4 REQUIRED COMPONENTS Quick Network Sql WebSockets ) # find_package(MySQL REQUIRED) qt_standard_project_setup(REQUIRES 6.4) qt_policy(SET QTP0001 NEW) qt_add_executable(appdemoApp main.cpp ) qt_add_qml_module(appdemoApp URI demoApp VERSION 1.0 RESOURCE_PREFIX / SOURCES mainworker.h mainworker.cpp applogger.h applogger.cpp icons/Resource.qrc QML_FILES Main.qml Login.qml Userreg.qml ) # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. # If you are developing for iOS or macOS you should consider setting an # explicit, fixed bundle identifier manually though. set_target_properties(appdemoApp PROPERTIES # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appdemoApp MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) target_link_libraries(appdemoApp PRIVATE Qt6::Quick PRIVATE Qt6::Network PRIVATE Qt6::Sql PRIVATE Qt6::WebSockets ) include(GNUInstallDirs) install(TARGETS appdemoApp BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) I was thinking I could be linking to a wrong library and mysql include directory however, Cmake runs the configurations very well and indicated MYSQL:MYSQL is found.
  • Qt Widgets Application

    Solved
    5
    0 Votes
    5 Posts
    682 Views
    SGaistS
    @davidweisgerber hi, Since you dived in already, I would encourage you to submit a patch to improve the documentation on that aspect.
  • Importing a C++ types declared using the QML_ELEMENT return module is not installed

    Unsolved
    2
    0 Votes
    2 Posts
    792 Views
    S
    I think I might have a similar problem. Any update on your original issue?
  • Loading external web images...

    Unsolved
    3
    0 Votes
    3 Posts
    820 Views
    1
    @mv-whw Thanks for answering Yes, that is the solution, putting inside my hosting public www folder all my resources: index.html main.wasm images/image0.png images/image1.png inside the wasm code: Image { source: "images/image0.png" } That worked well... and is very nice, this saves a lot of loading times..
  • webassembly does not display picture urls from web

    Solved
    7
    0 Votes
    7 Posts
    2k Views
    1
    @Jan-Bakker Hey, sorry for answering an answered qustion. Justo happy to read it, so, it is possible to load external images in Your web app so your wasm file is smaller?
  • RangeMemory: could not allocate memory on startup

    Unsolved
    2
    0 Votes
    2 Posts
    646 Views
    JonBJ
    @Caro You might start by Googling webassembly memory () could not allocate memory and read through the other reports and comments.
  • Simple WASM demo source

    Unsolved
    1
    0 Votes
    1 Posts
    489 Views
    No one has replied