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. Qt apps basic functionality
Forum Updated to NodeBB v4.3 + New Features

Qt apps basic functionality

Scheduled Pinned Locked Moved Solved General and Desktop
24 Posts 8 Posters 1.5k 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.
  • tomyT Offline
    tomyT Offline
    tomy
    wrote on last edited by
    #1

    Hi all,

    Here in this Fortune Client example we have main.cpp as follows:

    #include <QApplication>
    #include "client.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        QApplication::setApplicationDisplayName(Client::tr("Fortune Client"));
        Client client;
        client.show();
        return app.exec();
    }
    

    No supplementary thread is created in the project and by default we have the main thread for the GUI part, and the worker thread for the processes and computations, right?

    Is it right the the main thread starts by client.show(); and the worker thread by app.exec();?

    JonBJ 1 Reply Last reply
    0
    • tomyT tomy

      @mrjj
      I'm confused by what you said.
      You firstly say QTimer will be called later. Then you say, calling the function will happen right now!

      @JKSH

      If you call f1(), your debug output will print "Hello" before "World".

      So, apparently my first assumption mentioned here more than one time was correct. That is, that QTimer postpones the execution of the method inside it (requestNewFortune), until all next lines inside the function (void Client::readFortune()), are executed. And then at the end when there is no line to execute, QTimer calls its function. Right?

      @KroMignon

      This means requestNewFortune() will be executed some time later, when all other previous event in the QEventLoop have been executed.

      This is on the contrary to the code @JKSH offered above, because there, the function inside the QTimer is called when all other next lines are called.

      The subject presumably is not that convoluted but I don't know why I understand your posts differently! :(

      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by JKSH
      #21

      @tomy said in Qt apps basic functionality:

      QTimer postpones the execution of the method inside it (requestNewFortune), until all next lines inside the function (void Client::readFortune()), are executed. And then at the end when there is no line to execute, QTimer calls its function. Right?

      Almost right.

      QTimer does not call requestNewFortune(). QTimer puts requestNewFortune() in the event loop.

      The event loop calls the requestNewFortune() after readFortune() finishes all its lines and returns.

      @tomy said in Qt apps basic functionality:

      This means requestNewFortune() will be executed some time later, when all other previous event in the QEventLoop have been executed.

      This is on the contrary to the code @JKSH offered above, because there, the function inside the QTimer is called when all other next lines are called.

      @KroMignon's description matches the code that I wrote. It is not contrary.

      The sequence is this:

      1. The event loop calls f1(). f1() starts running, so it blocks the event loop.
      2. The QTimer in f1() puts triggeredFunc() in the event loop queue.
      3. f1() prints "Hello".
      4. f1() returns. The event loop can now proceed to the next task.
      5. The event loop checks its queue. It sees triggeredFunc() in the queue, so the event loop calls triggeredFunc(). triggeredFunc() starts running, so it blocks the event loop.
      6. triggeredFunc() prints "World".
      7. triggeredFunc() returns. The event loop can now proceed to the next task.
      8. The event loop checks its queue. If there is nothing in the queue, the event loop waits for the next event.

      With f2(), the sequence is this:

      1. The event loop calls f2(). f2() starts running, so it blocks the event loop.
      2. f2() calls triggeredFunc() directly. triggeredFunc() starts running, so it blocks f2().
      3. triggeredFunc() prints "World".
      4. triggeredFunc() returns. f2() can now proceed to the next line.
      5. f2() prints "World".
      6. f2() returns. The event loop can now proceed to the next task.
      7. The event loop checks its queue. If there is nothing in the queue, the event loop waits for the next event.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      tomyT 1 Reply Last reply
      4
      • tomyT tomy

        Hi all,

        Here in this Fortune Client example we have main.cpp as follows:

        #include <QApplication>
        #include "client.h"
        
        int main(int argc, char *argv[])
        {
            QApplication app(argc, argv);
            QApplication::setApplicationDisplayName(Client::tr("Fortune Client"));
            Client client;
            client.show();
            return app.exec();
        }
        

        No supplementary thread is created in the project and by default we have the main thread for the GUI part, and the worker thread for the processes and computations, right?

        Is it right the the main thread starts by client.show(); and the worker thread by app.exec();?

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

        @tomy
        Don't really understand what your question is here? I had a glance at that code, there are no "suplementary" threads, there is no "worker" thread. There is just one main process with one thread: it will do the GUI (during app.exec()), meanwhile (in the same one thread) asynchronous calls receive data from the server. The client do not block the client: they use signals & slots to handle data when it arrives. client.show() shows the dialog on the main thread, and app.exec() (also on the main thread) allows the Qt main event loop to run to interact with the dialog.

        Does that explain?

        tomyT 1 Reply Last reply
        3
        • JonBJ JonB

          @tomy
          Don't really understand what your question is here? I had a glance at that code, there are no "suplementary" threads, there is no "worker" thread. There is just one main process with one thread: it will do the GUI (during app.exec()), meanwhile (in the same one thread) asynchronous calls receive data from the server. The client do not block the client: they use signals & slots to handle data when it arrives. client.show() shows the dialog on the main thread, and app.exec() (also on the main thread) allows the Qt main event loop to run to interact with the dialog.

          Does that explain?

          tomyT Offline
          tomyT Offline
          tomy
          wrote on last edited by
          #3

          @jonb

          The main thread is accountable for GUI; the worker thread is accountable for the computations.
          https://doc.qt.io/qt-5/thread-basics.html

          1 Reply Last reply
          0
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @tomy said in Qt apps basic functionality:

            the worker thread is accountable for the computations.

            But the Fortune Client Example does not use any thread apart the main thread - so what's your question?

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            tomyT 2 Replies Last reply
            4
            • Christian EhrlicherC Christian Ehrlicher

              @tomy said in Qt apps basic functionality:

              the worker thread is accountable for the computations.

              But the Fortune Client Example does not use any thread apart the main thread - so what's your question?

              tomyT Offline
              tomyT Offline
              tomy
              wrote on last edited by tomy
              #5

              @christian-ehrlicher

              I believe the questions are asked clearly in the question body on top!
              Where does that main thread start from, in the main.cpp?

              What's the difference between client.show(); and app.exec();?

              1 Reply Last reply
              0
              • Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @tomy said in Qt apps basic functionality:

                Where does that main thread start from

                The main thread is started from the OS when it executes the executable. So it's already there when main is called - in which thread should run main() otherwise?
                What you maybe want to know is when the main Qt eventloop is started. But this is clearly stated in the QCoreApplication::exec() documentation.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                3
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  Hi,

                  The show method just schedules the fact that a graphical object should be shown. As @Christian-Ehrlicher pointed, the exec call starts the Qt event loop.

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

                  1 Reply Last reply
                  2
                  • Christian EhrlicherC Christian Ehrlicher

                    @tomy said in Qt apps basic functionality:

                    the worker thread is accountable for the computations.

                    But the Fortune Client Example does not use any thread apart the main thread - so what's your question?

                    tomyT Offline
                    tomyT Offline
                    tomy
                    wrote on last edited by tomy
                    #8

                    @christian-ehrlicher

                    But the Fortune Client Example does not use any thread apart the main thread - so what's your question?

                    So if there were any other thread it should have been declared using QThread, and since there is no such a line, we only have the main thread in that project. Right?

                    stated in the QCoreApplication::exec() documentation

                    in QCoreApplication::exec() documentation, it says:
                    To make your application perform idle processing (by executing a special function whenever there are no pending events), use a QTimer with 0 timeout. More advanced idle processing schemes can be achieved using processEvents().

                    That QTimer is also used in the following function of the project:

                    void Client::readFortune()
                    {
                        in.startTransaction();
                    
                        QString nextFortune;
                        in >> nextFortune;
                    
                        if (!in.commitTransaction())
                            return;
                    
                        if (nextFortune == currentFortune) {
                            QTimer::singleShot(0, this, &Client::requestNewFortune);
                            return;
                        }
                    
                        currentFortune = nextFortune;
                        statusLabel->setText(currentFortune);
                        getFortuneButton->setEnabled(true);
                    }
                    

                    I think the function requestNewFortune will be called when there is no pending events. But what does that mean in practice?
                    We have a number of instructions above and below that line!

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      No, the call is queued to be run at the first occasion.

                      The rest of the method might generate other events to be processed by the event loop but it's not the case for all lines.

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

                      tomyT 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        No, the call is queued to be run at the first occasion.

                        The rest of the method might generate other events to be processed by the event loop but it's not the case for all lines.

                        tomyT Offline
                        tomyT Offline
                        tomy
                        wrote on last edited by tomy
                        #10

                        @sgaist
                        The subject is still ambiguous for me! :| Probably if the questions below get answered I will figure out the case.

                        1. What are the events which are handled by the Even Loop in the method above (Client::readFortune())?

                        2. How are they handled/carried out? One after another, in order, from top ( in.startTransaction();) to down (getFortuneButton->setEnabled(true);)?

                        3. Where/When is that first occasion the call to the method in QTimer is run?

                        mrjjM 1 Reply Last reply
                        0
                        • tomyT tomy

                          @sgaist
                          The subject is still ambiguous for me! :| Probably if the questions below get answered I will figure out the case.

                          1. What are the events which are handled by the Even Loop in the method above (Client::readFortune())?

                          2. How are they handled/carried out? One after another, in order, from top ( in.startTransaction();) to down (getFortuneButton->setEnabled(true);)?

                          3. Where/When is that first occasion the call to the method in QTimer is run?

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by
                          #11

                          Hi

                          1. What are the events which are handled by the Even Loop in the method above (Client::readFortune())?

                          the network class readyRead() signal is connected to Client::readFortune() so when
                          data comes, the signal is emitted and this function called.

                          1. How are they handled/carried out? One after another, in order, from top ( in.startTransaction();) to down (getFortuneButton->setEnabled(true);)?
                            Yes, line by line.
                            the use of the QDataStream transaction is explained in the docs.
                            https://doc.qt.io/qt-5/qtnetwork-fortuneclient-example.html
                            Basically it is used to ensure we get all data since the network sends data in thunks.
                            Its explained in detail under the function in the sample>

                          2. Where/When is that first occasion the call to the method in QTimer is run?

                          When user clicks the button the process is started by calling requestNewFortune

                          connect(getFortuneButton, &QAbstractButton::clicked,
                          this, &Client::requestNewFortune);

                          The requestNewFortune will make the network send the readReady signal which calls
                          readFortune which will then call the timer when the if is true.

                          1 Reply Last reply
                          2
                          • tomyT Offline
                            tomyT Offline
                            tomy
                            wrote on last edited by
                            #12

                            @mrjj
                            Thank you for your time, but these were not what I was hoping to reach!
                            To summarise, I don't want to delve into the entire project to figure out the whole process; I got bogged merely down in that QTimer line and what it does and why it's necessary.
                            The full project is pretty straightforward and mostly worry-free to pursue.

                            Stating from question #1, supposedly the whole void Client::readFortune() function is one event. The instructions inside it are commands to be accomplished, one of which is the line QTimer::singleShot(0, this, &Client::requestNewFortune); we want to concentrate.

                            I surmise, requestNewFortune within the timer, is called when the event loop is idle and they're no pending events. That is, it will be called after all when nothing is waiting to be performed. Right until here?

                            Hence, I deduce that requestNewFortune within the timer is called at the end of the function, after executing the last expression getFortuneButton->setEnabled(true);.

                            I'm not sure if my thoughts are right and won't be astonished if you totally disagree! :)
                            but, at least, you know what the issue is I'm talking about.

                            KroMignonK 1 Reply Last reply
                            0
                            • tomyT tomy

                              @mrjj
                              Thank you for your time, but these were not what I was hoping to reach!
                              To summarise, I don't want to delve into the entire project to figure out the whole process; I got bogged merely down in that QTimer line and what it does and why it's necessary.
                              The full project is pretty straightforward and mostly worry-free to pursue.

                              Stating from question #1, supposedly the whole void Client::readFortune() function is one event. The instructions inside it are commands to be accomplished, one of which is the line QTimer::singleShot(0, this, &Client::requestNewFortune); we want to concentrate.

                              I surmise, requestNewFortune within the timer, is called when the event loop is idle and they're no pending events. That is, it will be called after all when nothing is waiting to be performed. Right until here?

                              Hence, I deduce that requestNewFortune within the timer is called at the end of the function, after executing the last expression getFortuneButton->setEnabled(true);.

                              I'm not sure if my thoughts are right and won't be astonished if you totally disagree! :)
                              but, at least, you know what the issue is I'm talking about.

                              KroMignonK Offline
                              KroMignonK Offline
                              KroMignon
                              wrote on last edited by KroMignon
                              #13

                              @tomy I don't really understand what problem you are talking about.

                              This program is relativ simple to understand:

                              • There is only 1 QThread, which is created/assigned by creating QApplication . There is no other thread.
                              • This QThread has a message queue / QEventLoop instance which will wait until signals are emitted. Each stored message will the be executed in the same order as they are been received
                              • By calling client.show(), the QDialog class will emit some signals, which are store in the main event loop
                              • By calling app.exec(), the QEventLoop processing is started. And the stored signals in main event queue will be executed.
                              • The main thread will ends, when the main event loop is stopped.

                              There is no magic nothing really complicated to understand.

                              Take a look at QThread documentation for more details

                              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                              1 Reply Last reply
                              3
                              • tomyT Offline
                                tomyT Offline
                                tomy
                                wrote on last edited by
                                #14

                                Just reread my prior post!!
                                My question is about QTimer mostly! I think I said that clearly.

                                Let me ask that, another way: what is the difference between QTimer::singleShot(0, this, &Client::requestNewFortune); and calling requestNewFortune() directly without the timer?

                                mrjjM JKSHJ KroMignonK 3 Replies Last reply
                                0
                                • tomyT tomy

                                  Just reread my prior post!!
                                  My question is about QTimer mostly! I think I said that clearly.

                                  Let me ask that, another way: what is the difference between QTimer::singleShot(0, this, &Client::requestNewFortune); and calling requestNewFortune() directly without the timer?

                                  mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #15

                                  @tomy
                                  Hi
                                  Yes there is.
                                  The Qtimer puts on the event queue and will be called later meaning
                                  the execution continues to the next line.

                                  Calling the requestNewFortune will happen right now and the next line is not processed before this function ends.

                                  1 Reply Last reply
                                  2
                                  • tomyT tomy

                                    Just reread my prior post!!
                                    My question is about QTimer mostly! I think I said that clearly.

                                    Let me ask that, another way: what is the difference between QTimer::singleShot(0, this, &Client::requestNewFortune); and calling requestNewFortune() directly without the timer?

                                    JKSHJ Offline
                                    JKSHJ Offline
                                    JKSH
                                    Moderators
                                    wrote on last edited by JKSH
                                    #16

                                    @tomy said in Qt apps basic functionality:

                                    what is the difference between QTimer::singleShot(0, this, &Client::requestNewFortune); and calling requestNewFortune() directly without the timer?

                                    Here is a simple illustration:

                                    void triggeredFunc()
                                    {
                                        qDebug("World");
                                    }
                                    
                                    void f1()
                                    {
                                        QTimer::singleShot(0, &triggeredFunc);
                                        qDebug("Hello");
                                    }
                                    
                                    void f2()
                                    {
                                        triggeredFunc();
                                        qDebug("Hello");
                                    }
                                    

                                    Assuming that your application has an event loop,

                                    • If you call f1(), your debug output will print "Hello" before "World".
                                    • If you call f2(), your debug output will print "World" before "Hello".

                                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                    tomyT 1 Reply Last reply
                                    3
                                    • tomyT tomy

                                      Just reread my prior post!!
                                      My question is about QTimer mostly! I think I said that clearly.

                                      Let me ask that, another way: what is the difference between QTimer::singleShot(0, this, &Client::requestNewFortune); and calling requestNewFortune() directly without the timer?

                                      KroMignonK Offline
                                      KroMignonK Offline
                                      KroMignon
                                      wrote on last edited by
                                      #17

                                      @tomy As try to explain to you calling QTimer::singleShot(0, this, &Client::requestNewFortune); will post event into the QEventLoop of the QThread used by this.
                                      This means requestNewFortune() will be executed some time later, when all other previous event in the QEventLoop have been executed.
                                      This also ensure, requestNewFortune() will be executed in the thread on which this is running.
                                      And, to be exhaustive, requestNewFortune() will be executed, when attached Thread has an QEventQueue and the thread is running.

                                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                      1 Reply Last reply
                                      2
                                      • JKSHJ JKSH

                                        @tomy said in Qt apps basic functionality:

                                        what is the difference between QTimer::singleShot(0, this, &Client::requestNewFortune); and calling requestNewFortune() directly without the timer?

                                        Here is a simple illustration:

                                        void triggeredFunc()
                                        {
                                            qDebug("World");
                                        }
                                        
                                        void f1()
                                        {
                                            QTimer::singleShot(0, &triggeredFunc);
                                            qDebug("Hello");
                                        }
                                        
                                        void f2()
                                        {
                                            triggeredFunc();
                                            qDebug("Hello");
                                        }
                                        

                                        Assuming that your application has an event loop,

                                        • If you call f1(), your debug output will print "Hello" before "World".
                                        • If you call f2(), your debug output will print "World" before "Hello".
                                        tomyT Offline
                                        tomyT Offline
                                        tomy
                                        wrote on last edited by
                                        #18

                                        @mrjj
                                        I'm confused by what you said.
                                        You firstly say QTimer will be called later. Then you say, calling the function will happen right now!

                                        @JKSH

                                        If you call f1(), your debug output will print "Hello" before "World".

                                        So, apparently my first assumption mentioned here more than one time was correct. That is, that QTimer postpones the execution of the method inside it (requestNewFortune), until all next lines inside the function (void Client::readFortune()), are executed. And then at the end when there is no line to execute, QTimer calls its function. Right?

                                        @KroMignon

                                        This means requestNewFortune() will be executed some time later, when all other previous event in the QEventLoop have been executed.

                                        This is on the contrary to the code @JKSH offered above, because there, the function inside the QTimer is called when all other next lines are called.

                                        The subject presumably is not that convoluted but I don't know why I understand your posts differently! :(

                                        KroMignonK JKSHJ 2 Replies Last reply
                                        0
                                        • mrjjM Offline
                                          mrjjM Offline
                                          mrjj
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #19

                                          @tomy said in Qt apps basic functionality:

                                          You firstly say QTimer will be called later. Then you say, calling the function will happen right now!

                                          Ok let me make it clear.

                                          QTimer::singleShot(0, this, &Client::requestNewFortune); ---> later called


                                          requestNewFortune(); ---> called right here. right now.

                                          And in this context. Later means when event loop gets around to it.

                                          1 Reply Last reply
                                          0
                                          • tomyT tomy

                                            @mrjj
                                            I'm confused by what you said.
                                            You firstly say QTimer will be called later. Then you say, calling the function will happen right now!

                                            @JKSH

                                            If you call f1(), your debug output will print "Hello" before "World".

                                            So, apparently my first assumption mentioned here more than one time was correct. That is, that QTimer postpones the execution of the method inside it (requestNewFortune), until all next lines inside the function (void Client::readFortune()), are executed. And then at the end when there is no line to execute, QTimer calls its function. Right?

                                            @KroMignon

                                            This means requestNewFortune() will be executed some time later, when all other previous event in the QEventLoop have been executed.

                                            This is on the contrary to the code @JKSH offered above, because there, the function inside the QTimer is called when all other next lines are called.

                                            The subject presumably is not that convoluted but I don't know why I understand your posts differently! :(

                                            KroMignonK Offline
                                            KroMignonK Offline
                                            KroMignon
                                            wrote on last edited by KroMignon
                                            #20

                                            @tomy said in Qt apps basic functionality:

                                            This is on the contrary to the code @JKSH offered above, because there, the function inside the QTimer is called when all other next lines are called.
                                            The subject presumably is not that convoluted but I don't know why I understand your posts differently! :(

                                            Dear @tomy, it seems my explanation are not that clear as I supposed. So I do another try:

                                            1. QThread owns a QEventLoop
                                            2. When starting a QThread, the thread will wait until a new event is stored in the event loop, take it and execute the function with the attached parameters
                                            3. When calling QTimer::singleShot(0, this, &Client::requestNewFortune);, what happen is that a temporary QTimer instance is created and started. When the passed delay is elapsed (in this case 0 milliseconds), the function/slots (in this case &Client::requestNewFortune) is stored in the event loop from the thread used by the receiver QObject instance (in this case this)

                                            I think I can't explain it more clearly and hope now you have understand the difference between QTimer::singleShot(0, this, &Client::requestNewFortune); and calling directly requestNewFortune().

                                            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                            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