Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for WebAssembly
  4. Failed to show GUI in WASM after JavaScript call
Forum Update on Monday, May 27th 2025

Failed to show GUI in WASM after JavaScript call

Scheduled Pinned Locked Moved Solved Qt for WebAssembly
8 Posts 2 Posters 601 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 8 Offline
    8 Offline
    8Observer8
    wrote on 16 Jan 2024, 19:14 last edited by
    #1

    Hi,

    I made a minimal example to demonstrate a problem. I try to call alert() before showing GUI (one QLabel with "Hello" text). I see the alert() call but I don't see a QLabel. But if I comment this line: call_alert(); I see the QLabel. Is it a bug?

    #include <QtWidgets/QApplication>
    #include <QtWidgets/QLabel>
    #include <QtWidgets/QVBoxLayout>
    #include <QtWidgets/QWidget>
    #include <emscripten.h>
    
    EM_JS(void, call_alert, (),
          {
              alert("hello");
              throw "all done";
          })
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget()
        {
            call_alert();
            QLabel *label = new QLabel("Hello");
            QVBoxLayout *layout = new QVBoxLayout();
            layout->addWidget(label);
            layout->addStretch();
            setLayout(layout);
        }
    };
    
    #include "main.moc"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
        return a.exec();
    }
    
    J 1 Reply Last reply 16 Jan 2024, 19:17
    0
    • 8 8Observer8
      16 Jan 2024, 19:14

      Hi,

      I made a minimal example to demonstrate a problem. I try to call alert() before showing GUI (one QLabel with "Hello" text). I see the alert() call but I don't see a QLabel. But if I comment this line: call_alert(); I see the QLabel. Is it a bug?

      #include <QtWidgets/QApplication>
      #include <QtWidgets/QLabel>
      #include <QtWidgets/QVBoxLayout>
      #include <QtWidgets/QWidget>
      #include <emscripten.h>
      
      EM_JS(void, call_alert, (),
            {
                alert("hello");
                throw "all done";
            })
      
      class Widget : public QWidget
      {
          Q_OBJECT
      
      public:
          Widget()
          {
              call_alert();
              QLabel *label = new QLabel("Hello");
              QVBoxLayout *layout = new QVBoxLayout();
              layout->addWidget(label);
              layout->addStretch();
              setLayout(layout);
          }
      };
      
      #include "main.moc"
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          Widget w;
          w.show();
          return a.exec();
      }
      
      J Offline
      J Offline
      JonB
      wrote on 16 Jan 2024, 19:17 last edited by
      #2

      @8Observer8
      You don't see the label at all, or you mean you don't see it till after you have dismissed the alert()?
      Are you wanting to test throw, or can that be removed from your example?

      8 2 Replies Last reply 16 Jan 2024, 19:30
      1
      • J JonB
        16 Jan 2024, 19:17

        @8Observer8
        You don't see the label at all, or you mean you don't see it till after you have dismissed the alert()?
        Are you wanting to test throw, or can that be removed from your example?

        8 Offline
        8 Offline
        8Observer8
        wrote on 16 Jan 2024, 19:30 last edited by
        #3

        @JonB said in Failed to show GUI in WASM after JavaScript call:

        You don't see the label at all

        Yes. I can see a label only if I comment this line call_alert(); It is not a problem with dismissing alert(). I replaced alert() with console.log(). I don't see a label but I see "hello" in the console:

        EM_JS(void, call_alert, (),
              {
                  console.log("hello");
                  throw "all done";
              })
        

        5a8b1763-dad5-48c1-8af7-04269b377311-image.png

        But if I comment call_alert(); like this:

            Widget()
            {
                // call_alert();
                QLabel *label = new QLabel("Hello");
                QVBoxLayout *layout = new QVBoxLayout();
                layout->addWidget(label);
                layout->addStretch();
                setLayout(layout);
            }
        

        I see the label:

        355462aa-7782-426e-b12a-4d62db3a0949-image.png

        1 Reply Last reply
        0
        • J JonB
          16 Jan 2024, 19:17

          @8Observer8
          You don't see the label at all, or you mean you don't see it till after you have dismissed the alert()?
          Are you wanting to test throw, or can that be removed from your example?

          8 Offline
          8 Offline
          8Observer8
          wrote on 16 Jan 2024, 19:34 last edited by
          #4

          @JonB said in Failed to show GUI in WASM after JavaScript call:

          Are you wanting to test throw, or can that be removed from your example?

          I don't know why I should call throw "all done"; I found it in the Emscripten docs. I tried to comment it:

          EM_JS(void, call_alert, (),
                {
                    console.log("hello");
                    // throw "all done";
                })
          

          I see a label now:

          71707517-c339-4d2e-bddf-0e2c65d82aa0-image.png

          It solved. Thank you very much!

          J 1 Reply Last reply 16 Jan 2024, 19:37
          0
          • 8 8Observer8 has marked this topic as solved on 16 Jan 2024, 19:35
          • 8 8Observer8
            16 Jan 2024, 19:34

            @JonB said in Failed to show GUI in WASM after JavaScript call:

            Are you wanting to test throw, or can that be removed from your example?

            I don't know why I should call throw "all done"; I found it in the Emscripten docs. I tried to comment it:

            EM_JS(void, call_alert, (),
                  {
                      console.log("hello");
                      // throw "all done";
                  })
            

            I see a label now:

            71707517-c339-4d2e-bddf-0e2c65d82aa0-image.png

            It solved. Thank you very much!

            J Offline
            J Offline
            JonB
            wrote on 16 Jan 2024, 19:37 last edited by JonB
            #5

            @8Observer8
            Well, that's why I asked about the throw! That causes a JS error and aborts the script. I don't know how that then impacts whatever state the WASM is in (I don't use), but it perhaps does not even return into your calling program?

            8 1 Reply Last reply 16 Jan 2024, 19:44
            2
            • J JonB
              16 Jan 2024, 19:37

              @8Observer8
              Well, that's why I asked about the throw! That causes a JS error and aborts the script. I don't know how that then impacts whatever state the WASM is in (I don't use), but it perhaps does not even return into your calling program?

              8 Offline
              8 Offline
              8Observer8
              wrote on 16 Jan 2024, 19:44 last edited by 8Observer8
              #6

              @JonB said in Failed to show GUI in WASM after JavaScript call:

              but it perhaps does not even return into your calling program?

              Yes, you are right! When I comment throw "all done" It returns to a calling program:

              EM_JS(void, call_alert, (),
                    {
                        console.log("hello");
                        // throw "all done";
                    })
              
              class Widget : public QWidget
              {
                  Q_OBJECT
              
              public:
                  Widget()
                  {
                      call_alert();
                      qDebug() << "Text in Widget";
              

              a57862ff-2438-4845-bbab-4eed9d240906-image.png
              And with throw "all done" it doesn't return:

              EM_JS(void, call_alert, (),
                    {
                        console.log("hello");
                        throw "all done";
                    })
              
              class Widget : public QWidget
              {
                  Q_OBJECT
              
              public:
                  Widget()
                  {
                      call_alert();
                      qDebug() << "Text in Widget";
              

              71b1f39d-e89c-4714-a035-2e431e1f40fc-image.png

              J 1 Reply Last reply 16 Jan 2024, 20:23
              0
              • 8 8Observer8
                16 Jan 2024, 19:44

                @JonB said in Failed to show GUI in WASM after JavaScript call:

                but it perhaps does not even return into your calling program?

                Yes, you are right! When I comment throw "all done" It returns to a calling program:

                EM_JS(void, call_alert, (),
                      {
                          console.log("hello");
                          // throw "all done";
                      })
                
                class Widget : public QWidget
                {
                    Q_OBJECT
                
                public:
                    Widget()
                    {
                        call_alert();
                        qDebug() << "Text in Widget";
                

                a57862ff-2438-4845-bbab-4eed9d240906-image.png
                And with throw "all done" it doesn't return:

                EM_JS(void, call_alert, (),
                      {
                          console.log("hello");
                          throw "all done";
                      })
                
                class Widget : public QWidget
                {
                    Q_OBJECT
                
                public:
                    Widget()
                    {
                        call_alert();
                        qDebug() << "Text in Widget";
                

                71b1f39d-e89c-4714-a035-2e431e1f40fc-image.png

                J Offline
                J Offline
                JonB
                wrote on 16 Jan 2024, 20:23 last edited by
                #7

                @8Observer8
                Now that you know that, you could protect yourself with "neat" code by enclosing anything in the body of that function inside try ... catch ... (with some warning/alert dialog), so that if it ever does something bad your calling code still continues.

                1 Reply Last reply
                1
                • 8 Offline
                  8 Offline
                  8Observer8
                  wrote on 16 Jan 2024, 21:24 last edited by 8Observer8
                  #8

                  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);
                  }
                  
                  1 Reply Last reply
                  0

                  2/8

                  16 Jan 2024, 19:17

                  6 unread
                  • Login

                  • Login or register to search.
                  2 out of 8
                  • First post
                    2/8
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved