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. How to update main windows from running thread , the right way

How to update main windows from running thread , the right way

Scheduled Pinned Locked Moved General and Desktop
17 Posts 4 Posters 7.8k Views 1 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.
  • U Offline
    U Offline
    umen242
    wrote on last edited by
    #1

    Hello
    I have simple application that in the main view I have QListview . my flow going like this I need to know if it right

    1. App starts and start single thread , also see signal/slot connect between the thread object and the main app
    2. Thread gets data from remote server as xml format its and sets the data into object container (class that represent the data )
    3. when the data is ready in the object it trigger SIGNAL back to the main app (the signal/slot from section 1)
    4. The SIGNAL invoking update function that sets the formatted data into the QListView via its model (QAbstractListModel)

    The problem is when stage 4 is happening I see some freeze in the application for 2-3 seconds that makes me wonder what is wrong here .

    1 Reply Last reply
    0
    • F Offline
      F Offline
      fluca1978
      wrote on last edited by
      #2

      Sounds correct to me. Is it possible that during 4 the main thread is busy doing some sort of validation or computation?

      1 Reply Last reply
      0
      • U Offline
        U Offline
        umen242
        wrote on last edited by
        #3

        I think im going to check it with "http://www.codersnotes.com/sleepy/":http://www.codersnotes.com/sleepy/
        first then will come back and tell here

        1 Reply Last reply
        0
        • U Offline
          U Offline
          umen242
          wrote on last edited by
          #4

          after profiling the app with sleepy it looks like the delay in the app im not sure but is shows in the Exclusive column very high number 322.35s. in my Thread that calls the http request inside the run method i have this code that cause the thread to pause.

          @void RequestThread::run()
          {
          m_RequestThreadTimer = new QTimer();
          connect(m_RequestThreadTimer, SIGNAL(timeout()),
          this,SLOT(fire(),Qt::DirectConnection));
          QVariant val(GetValFromConfig());
          int interval = val.toInt();
          m_RequestThreadTimer->setInterval(interval);
          m_RequestThreadTimer->start();
          QThread::exec();
          }
          @

          but now is the question how to improve it ?

          1 Reply Last reply
          0
          • S Offline
            S Offline
            stima_ua
            wrote on last edited by
            #5

            Im not sure but mb for first in the method GetValFromConfig() u use some another method from object that was created in main thread. And second, i think that directconnection is not need in this case.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              Well, on that last one, I tend to disagree. The problem is that the slot is defined on the QThread subclass. That is not the recommended way to work with threads. The QThread object itself is in the main thread (and please, don't move the QThread object to the thread itself...). The timer is in the RequestThread however. When the timer fires, the current thread will be the RequestThread. Because the fire() slot is defined on the RequestThread object that lives in the main thread, a queued connection will be used. That is not what umen242 is after, I think. So, a direct connection is on order if you want to use this setup.

              A better way to do this would probably be to create a QObject-derived worker class. Create an instance of that class, create a vanilla QThread instance, and move the worker object to the thread of that QThread object and start the thread. There is no need to subclass QThread, and it usually doesn't do what you expect it to do anyway.

              1 Reply Last reply
              0
              • U Offline
                U Offline
                umen242
                wrote on last edited by
                #7

                GetValFromConfig() is from singleton object that holds the app config does it matter ?
                directconnection is there because i saw recommendations in the net to stick it there

                1 Reply Last reply
                0
                • U Offline
                  U Offline
                  umen242
                  wrote on last edited by
                  #8

                  Thanks Andre for your very informative answer but i must admit , you confused me here ,
                  can you direct me to link that shows me some code , how it suppose to look ?
                  Thanks

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #9

                    [quote author="umen242" date="1325148899"]Thanks Andre for your very informative answer but i must admit , you confused me here ,
                    can you direct me to link that shows me some code , how it suppose to look ?
                    Thanks[/quote]

                    Yeah, sorry, it is a bit confusing.
                    "This wiki article":http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects has a lot of detail on this topic. The code below is lifted from this article:

                    @
                    class Worker : public QObject
                    {
                    Q_OBJECT

                    public slots:
                    void doWork() {
                    /* ... */
                    }
                    };

                    /* ... */
                    QThread *thread = new QThread;
                    Worker *worker = new Worker;
                    connect(obj, SIGNAL(workReady()), worker, SLOT(doWork()));
                    worker->moveToThread(thread);
                    thread->start();
                    @

                    1 Reply Last reply
                    0
                    • U Offline
                      U Offline
                      umen242
                      wrote on last edited by
                      #10

                      Thanks again, im reading the wiki you posted , after implementing this method of thread creation
                      do you think i can still use the pause timer i used in the original thread ?

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on last edited by
                        #11

                        Of course you can! Just create your timer in the worker class itself, and replace the doWork() slot with something that starts that timer.

                        1 Reply Last reply
                        0
                        • U Offline
                          U Offline
                          umen242
                          wrote on last edited by
                          #12

                          i finished to read it , one small thing i didn't understand or didn't noticed what is the "obj" in the :
                          @connect(obj, SIGNAL(workReady()), worker, SLOT(doWork()));@
                          you have idea?

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on last edited by
                            #13

                            It is an object living in the main thread that signals that there is work to be done for the thread.

                            1 Reply Last reply
                            0
                            • U Offline
                              U Offline
                              umen242
                              wrote on last edited by
                              #14

                              Hmm in my case is , i need the thread start when some object is initialized , so i guess i can remove it
                              but when i think about it , what will trigger the DoWork() method ?
                              for example:
                              i have this object and method ApiManager->Init() that inside the Init() i want to start the thread to work so this is what is did :
                              @//Singeltone object
                              ApiManager::ApiManager()
                              {
                              m_Thread = new QThread();
                              m_Worker = new Worker() // is the same as in the wiki example
                              m_Worker->moveToThread(m_Thread);
                              }

                              ApiManager::Init()
                              {
                              m_Thread->start();
                              }@

                              what will trigger me the DoWork here ? or any other method inside the thread ?
                              i dont need here another mechanize to trigger the signal inside the worker . it needs to start when the thread start.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #15

                                So... why don't you connect the thread's started() signal with the doWork() slot? That way, your worker will start to do it's job as soon as the thread starts.

                                However, note that this setup is most useful for situations where the worker can get more than one request to do some piece of work. If you 'just' need a one-of operation to run in a thread, then you probably are better off using a QRunnable or subclassing QThread and reimplementing the run() method (without using slots on the subclassed QThread, of course).

                                1 Reply Last reply
                                0
                                • U Offline
                                  U Offline
                                  umen242
                                  wrote on last edited by
                                  #16

                                  ok so this is what was my initial setup to start the thread i subclass he thread and invoke the QThread start() and the start trigger the QThread::run()
                                  and inside the run i have the code that i show above that cause the problem .
                                  so what do you think is the best solution here ? maybe the timer code is wrong after all .

                                  like this :
                                  @ //Singeltone object
                                  ApiManager::ApiManager()
                                  {
                                  // im not using new QThead here

                                     m_Thread.start()
                                  
                                  }
                                  

                                  @

                                  1 Reply Last reply
                                  0
                                  • U Offline
                                    U Offline
                                    umen242
                                    wrote on last edited by
                                    #17

                                    Some update ,
                                    after implementing the thread as worker object , i eliminated the delay in my gui , now its just works
                                    smooth.
                                    thanks andre !

                                    1 Reply Last reply
                                    0

                                    • Login

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