Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Can not get signal lastWindowClosed when not exec
Forum Updated to NodeBB v4.3 + New Features

Can not get signal lastWindowClosed when not exec

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 4 Posters 717 Views 4 Watching
  • 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.
  • H Offline
    H Offline
    hongzhiyuan
    wrote on last edited by hongzhiyuan
    #1

    I use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec and encountered an issue with lastWindowClosed, and i digged into the code, in file src/gui/kernel/qguiapplication.cpp i found code:

    void QGuiApplicationPrivate::maybeLastWindowClosed()
    {
        if (!lastWindowClosed())
            return;
    
        if (in_exec)
            emit q_func()->lastWindowClosed();
    
        if (quitOnLastWindowClosed && canQuitAutomatically())
            quitAutomatically();
    }
    

    in code above, lastWindowClosed will only be emitted when in_exec is true, could you please tell me why this check is necessary and if this behavior is intentional?

    And i want to know can i use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec?

    JonBJ S 2 Replies Last reply
    0
    • H hongzhiyuan

      I use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec and encountered an issue with lastWindowClosed, and i digged into the code, in file src/gui/kernel/qguiapplication.cpp i found code:

      void QGuiApplicationPrivate::maybeLastWindowClosed()
      {
          if (!lastWindowClosed())
              return;
      
          if (in_exec)
              emit q_func()->lastWindowClosed();
      
          if (quitOnLastWindowClosed && canQuitAutomatically())
              quitAutomatically();
      }
      

      in code above, lastWindowClosed will only be emitted when in_exec is true, could you please tell me why this check is necessary and if this behavior is intentional?

      And i want to know can i use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @hongzhiyuan said in Can not get signal lastWindowClosed when not exec:

      And i want to know can i use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec?

      So far as I know this is a bad idea. I cannot imagine why you don't adjust your code to work with exec().

      H 1 Reply Last reply
      1
      • JonBJ JonB

        @hongzhiyuan said in Can not get signal lastWindowClosed when not exec:

        And i want to know can i use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec?

        So far as I know this is a bad idea. I cannot imagine why you don't adjust your code to work with exec().

        H Offline
        H Offline
        hongzhiyuan
        wrote on last edited by
        #3

        @JonB Thanks. I am working with a nodejs binding of qt. nodejs is a single thread runtime with event loop, so comes the idea I want call qt's QCoreApplication::processEvents inside nodejs event loop.

        The original code in which nodejs's event loop cannot spin:

        const app = new QApplication();
        
        // some ui...
        
        app.exec(); // this is going to block nodejs event loop and no async task can be handled
        

        instead, i use code below:

        const app = new QApplication();
        
        // some ui ...
        
        (async function() {
          while (true) {
            app.processEvents();
            await sleep(0); // this await make nodejs event loop able to spin
          }
        })();
        
        

        Hope this help explaining.

        SGaistS 1 Reply Last reply
        0
        • H hongzhiyuan

          @JonB Thanks. I am working with a nodejs binding of qt. nodejs is a single thread runtime with event loop, so comes the idea I want call qt's QCoreApplication::processEvents inside nodejs event loop.

          The original code in which nodejs's event loop cannot spin:

          const app = new QApplication();
          
          // some ui...
          
          app.exec(); // this is going to block nodejs event loop and no async task can be handled
          

          instead, i use code below:

          const app = new QApplication();
          
          // some ui ...
          
          (async function() {
            while (true) {
              app.processEvents();
              await sleep(0); // this await make nodejs event loop able to spin
            }
          })();
          
          

          Hope this help explaining.

          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi and welcome to devnet,

          Which bindings are you using ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          H 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi and welcome to devnet,

            Which bindings are you using ?

            H Offline
            H Offline
            hongzhiyuan
            wrote on last edited by hongzhiyuan
            #5

            @SGaist I was using https://github.com/nodegui/nodegui. It requires a modified nodejs (https://github.com/nodegui/qodejs) to work with qt. I was trying to make it works with unmodified nodejs.

            1 Reply Last reply
            0
            • H hongzhiyuan

              I use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec and encountered an issue with lastWindowClosed, and i digged into the code, in file src/gui/kernel/qguiapplication.cpp i found code:

              void QGuiApplicationPrivate::maybeLastWindowClosed()
              {
                  if (!lastWindowClosed())
                      return;
              
                  if (in_exec)
                      emit q_func()->lastWindowClosed();
              
                  if (quitOnLastWindowClosed && canQuitAutomatically())
                      quitAutomatically();
              }
              

              in code above, lastWindowClosed will only be emitted when in_exec is true, could you please tell me why this check is necessary and if this behavior is intentional?

              And i want to know can i use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec?

              S Offline
              S Offline
              SimonSchroeder
              wrote on last edited by
              #6

              @hongzhiyuan said in Can not get signal lastWindowClosed when not exec:

              And i want to know can i use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec?

              Qt was written with C++ in mind. And there is usually no reason to replace exec. That's most likely the reason for the extra check inside maybeLastWindowClosed because there is no event loop to further process the events.

              You already figured out that there are (by default) some things that only work within exec. I am not sure if anybody already tried to get rid of exec and can reasonably answer your question. One thing to consider is that repeatedly calling processEvents is a lot slower than using exec directly. You might get really bad performance with this approach.

              Is calling processEvents really necessary? The documentation of nodegui does not mention this. But maybe this is related to the use of qodejs. I don't have any knowledge about nodejs. Most likely there is a reason that they introduced qodejs because they did not find a way to do it properly within regular nodejs. Don't try to outsmart those people.

              JonBJ 1 Reply Last reply
              3
              • S SimonSchroeder

                @hongzhiyuan said in Can not get signal lastWindowClosed when not exec:

                And i want to know can i use QCoreApplication::processEvents in infinite loop to replace QCoreApplication::exec?

                Qt was written with C++ in mind. And there is usually no reason to replace exec. That's most likely the reason for the extra check inside maybeLastWindowClosed because there is no event loop to further process the events.

                You already figured out that there are (by default) some things that only work within exec. I am not sure if anybody already tried to get rid of exec and can reasonably answer your question. One thing to consider is that repeatedly calling processEvents is a lot slower than using exec directly. You might get really bad performance with this approach.

                Is calling processEvents really necessary? The documentation of nodegui does not mention this. But maybe this is related to the use of qodejs. I don't have any knowledge about nodejs. Most likely there is a reason that they introduced qodejs because they did not find a way to do it properly within regular nodejs. Don't try to outsmart those people.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @SimonSchroeder said in Can not get signal lastWindowClosed when not exec:

                One thing to consider is that repeatedly calling processEvents is a lot slower than using exec directly

                @hongzhiyuan
                I would back this statement up from experience. If you are going to do it the way you show, just what does await sleep(0); do? If it takes "no time" then your code will be busy running app.processEvents(); all the time, which is really bad.

                S 1 Reply Last reply
                1
                • H Offline
                  H Offline
                  hongzhiyuan
                  wrote on last edited by
                  #8

                  Thanks for the explanations, I think it sounds helpful and makes sense. But the problem that still exists is that in a single-threaded event-loop-based runtime like nodejs, working with qt requires an unnatural way. I don't think this problem should/could be solved the way I tried above, qodejs provides a nice solution at the cost of using a modified nodejs.

                  And at the same time I also found that python has a similar problem, the solution is to use https://github.com/CabbageDevelopment/qasync

                  Still looking forward an develop experience that doesn't require a modified version of nodejs. It would be nice if this use case can be taken into consideration in the future.

                  1 Reply Last reply
                  0
                  • JonBJ JonB

                    @SimonSchroeder said in Can not get signal lastWindowClosed when not exec:

                    One thing to consider is that repeatedly calling processEvents is a lot slower than using exec directly

                    @hongzhiyuan
                    I would back this statement up from experience. If you are going to do it the way you show, just what does await sleep(0); do? If it takes "no time" then your code will be busy running app.processEvents(); all the time, which is really bad.

                    S Offline
                    S Offline
                    SimonSchroeder
                    wrote on last edited by
                    #9

                    @JonB said in Can not get signal lastWindowClosed when not exec:

                    just what does await sleep(0); do? If it takes "no time" then your code will be busy running app.processEvents(); all the time, which is really bad.

                    The comment states that this will switch over to the nodejs loop. But you are right that this approach will fully employ a single core non-stop. (Most people find that annoying or confusing.) A slightly better version (not sure if this works) is to write an async function that call app.exec() instead. There is a common trick to run a QTimer with a timeout of 0ms which will fire whenever the process is idle. The connected slot should be able to execute the await sleep(0);. As an improvement – in order not to hog a single core entirely – you could run the timer only every few milliseconds. One major problem with your approach or this approach is that the nodejs loop can block the Qt "event loop" for a long period of time. In certain circumstances this might make your app sluggish.

                    @hongzhiyuan said in Can not get signal lastWindowClosed when not exec:

                    It would be nice if this use case can be taken into consideration in the future.

                    As a C++ programmer I honestly hope that this is not the future direction of Qt. I need a good C++ library. Unfortunately, Qt is one of the best libraries out there, but many concepts are a little outdated. I would rather hope that someone learns from Qt and write a new, better library for nodejs instead (I actually would hope the same for C++ as well). Sure, this is a huge amount of work initially. And this is most likely why nobody has done it yet.

                    1 Reply Last reply
                    1

                    • Login

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