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. QThread and timers
Forum Updated to NodeBB v4.3 + New Features

QThread and timers

Scheduled Pinned Locked Moved General and Desktop
25 Posts 5 Posters 13.4k 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.
  • L Offline
    L Offline
    lgeyer
    wrote on last edited by
    #11

    It should indeed warn on Linux as well. Did you define QT_NO_DEBUG to suppress the warning?

    1 Reply Last reply
    0
    • A Offline
      A Offline
      astodolski
      wrote on last edited by
      #12

      [quote author="JKSH" date="1356061869"][quote author="astodolski" date="1356056195"]
      @
      void FlashWizard::reject()
      {
      worker->stop();
      }@
      [/quote]That's a direct function call. Your main thread executes FlashWizard::reject(), thus it will also execute Worker::stop(), thus it will also execute Worker::killTimer(). In other words, the program is attempting to kill the timer from the main thread.

      To execute Worker::stop() in your other thread, connect the your button's clicked() signal to Worker::stop(). You can get rid of FlashWizard::reject() altogether.

      Edit: To clarify, a slot is just a regular C++ function. It is technically possible to call a slot from any thread, but we usually don't want this. To make the call safely, we use a queued signal-slot connection -- Qt notifies the event loop of the "correct" thread when the signal is emitted, and the slot is then called from that thread

      Looks like there is a bug in Qt though, if the Linux implementation fails to warn the developer about the cross-thread timer manipulation![/quote]

      I tried doing it this way:

      @connect(button(QWizard::CancelButton), SIGNAL(clicked()), worker, SLOT(stop()));@

      I get an error:

      C2664: 'bool QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)' : cannot convert parameter 1 from 'QAbstractButton *' to 'const QObject *'
      Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

      I casted the button to QObject* and the slot does not get executed when I click the Wizard cancel button.

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

        [quote author="Lukas Geyer" date="1356075094"]It should indeed warn on Linux as well. Did you define QT_NO_DEBUG to suppress the warning?[/quote]

        No I didn't try that - good to know. I prefer to understand and prevent the warning. Thanks for the tip.

        Could be a Qt bug.

        1 Reply Last reply
        0
        • JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by
          #14

          [quote author="astodolski" date="1356188428"]I tried doing it this way:

          @connect(button(QWizard::CancelButton), SIGNAL(clicked()), worker, SLOT(stop()));@

          I get an error:

          C2664: 'bool QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)' : cannot convert parameter 1 from 'QAbstractButton *' to 'const QObject *'
          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

          I casted the button to QObject* and the slot does not get executed when I click the Wizard cancel button.[/quote]Hmm... QAbstractButton inherits QWidget which inherits QObject, so it should work. Perhaps QAbstractButton was simply forward-declared by the QWizard header. Try adding #include <QAbstractButton>

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

          1 Reply Last reply
          0
          • L Offline
            L Offline
            lgeyer
            wrote on last edited by
            #15

            [quote author="astodolski" date="1356188639"][quote author="Lukas Geyer" date="1356075094"]It should indeed warn on Linux as well. Did you define QT_NO_DEBUG to suppress the warning?[/quote]
            No I didn't try that - good to know. I prefer to understand and prevent the warning. Thanks for the tip.[/quote]

            Please do not misunderstand me: I do not recommend using QT_NO_DEBUG to supress the warning. I was just curious why you didn't get the warning on your embedded device, and one reason might be that you have QT_NO_DEBUG defined.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              astodolski
              wrote on last edited by
              #16

              [quote author="Lukas Geyer" date="1356255159"][quote author="astodolski" date="1356188639"][quote author="Lukas Geyer" date="1356075094"]It should indeed warn on Linux as well. Did you define QT_NO_DEBUG to suppress the warning?[/quote]
              No I didn't try that - good to know. I prefer to understand and prevent the warning. Thanks for the tip.[/quote]

              Please do not misunderstand me: I do not recommend using QT_NO_DEBUG to supress the warning. I was just curious why you didn't get the warning on your embedded device, and one reason might be that you have QT_NO_DEBUG defined.[/quote]

              I don't target an embedded device - I'm targeting Desktop.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                astodolski
                wrote on last edited by
                #17

                [quote author="JKSH" date="1356229131"][quote author="astodolski" date="1356188428"]I tried doing it this way:

                @connect(button(QWizard::CancelButton), SIGNAL(clicked()), worker, SLOT(stop()));@

                I get an error:

                C2664: 'bool QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)' : cannot convert parameter 1 from 'QAbstractButton *' to 'const QObject *'
                Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

                I casted the button to QObject* and the slot does not get executed when I click the Wizard cancel button.[/quote]Hmm... QAbstractButton inherits QWidget which inherits QObject, so it should work. Perhaps QAbstractButton was simply forward-declared by the QWizard header. Try adding #include <QAbstractButton>[/quote]

                @
                connect((QObject*)button(QWizard::CancelButton), SIGNAL(clicked()), worker, SLOT(stop()));
                @

                The Cancel button has no effect on the process. I also included:

                @#include <QAbstractButton>@

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  goli
                  wrote on last edited by
                  #18

                  I have embedded device, and I don't get this warrning on the device.
                  This is my code:
                  @
                  .h file:

                  #include <QObject>
                  #include <QThread>

                  class ThreadManager: public QObject
                  {
                  Q_OBJECT

                  public:
                  explicit ThreadManager();
                  virtual ~ThreadManager();

                  inline void startTheThread()
                  {
                      m_thread->start();
                  }
                  

                  protected:
                  virtual void run() = 0;

                  private slots:
                  void exec();

                  private:
                  QThread* m_thread;
                  };

                  .cpp file:

                  ThreadManager::ThreadManager():
                  QObject()
                  {
                  m_thread = new QThread();
                  moveToThread(m_thread);
                  connect(m_thread, SIGNAL(started()), this, SLOT(exec()));
                  connect(m_thread, SIGNAL(finished()), m_thread, SLOT(deleteLater()));
                  }

                  ThreadManager::~ThreadManager()
                  {
                  m_thread->quit();
                  }

                  void ThreadManager::exec()
                  {
                  run();
                  }
                  @

                  I create a class that inherit ThreadManager and in the run() function I create a timer with timerEvent:
                  @
                  startTimer(1000);
                  @

                  when the program end I get this warrning...

                  1 Reply Last reply
                  0
                  • JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by
                    #19

                    [quote author="astodolski" date="1356287500"]
                    @
                    connect((QObject*)button(QWizard::CancelButton), SIGNAL(clicked()), worker, SLOT(stop()));
                    @

                    The Cancel button has no effect on the process.[/quote]I notice you have a custom Qt Designer UI for your FlashWizard. Are you still using the QWizard's built-in Cancel button, or did you implement a new one in Qt Designer? button(QWizard::CancelButton) returns a pointer to the built-in button, but this button doesn't exist if you implemented your own UI.

                    Also, the (QObject*) typecast is unnecessary -- the compiler should cast it for you automatically. Furthermore, if you ever need to make an explicit typecast, using qobject_cast<> is safer, as Qt will perform a run-time check to see if the cast is valid.

                    [quote author="goli" date="1356332295"]I create a class that inherit ThreadManager and in the run() function I create a timer with timerEvent:
                    @
                    startTimer(1000);
                    @

                    when the program end I get this warrning...[/quote]QThread IS a thread manager (see http://qt-project.org/doc/qt-5.0/qtcore/qthread.html for a full description, and a small example on how to use QThread). Your code is wrapping a thread manager in a thread manager, so I recommend redesigning it.

                    Read astodolski's code from 21 December and my reply (http://qt-project.org/forums/viewthread/22916/#107177 ) -- is your issue the same?

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

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      goli
                      wrote on last edited by
                      #20

                      JKSH , Thank you for your reply.
                      I don't have the same issue as astodolski. I create the timer in the run() function of the thread(even if I do it without thread manager).
                      I do it this way to create a event loop for the thread that is saperate from the main thread(GUI thread).
                      when I try to get the "finished()":http://qt-project.org/doc/qt-5.0/qtcore/qthread.html#finished signal and then kill the timer, I get this warrning, but not all the time...sometimes it appear and sometimes not.

                      1 Reply Last reply
                      0
                      • JKSHJ Offline
                        JKSHJ Offline
                        JKSH
                        Moderators
                        wrote on last edited by
                        #21

                        You're welcome, goli.

                        Some questions:

                        How do you kill the timer? Which thread does the killing?

                        It sounds like you're using a QObject's built-in timer -- which thread does that QObject live in?

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

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          goli
                          wrote on last edited by
                          #22

                          The Timer was created in the run(in the exec of the thread) function of the new thread with startTimer function. This way I create Event loop for this thread that is saperate from the main thread. I keep the ID of this timer and kill him when the thread is finished. The main thread is the one who kill the timer, but I can't see other way to kill this timer that was created in the exec of the thread...

                          1 Reply Last reply
                          0
                          • JKSHJ Offline
                            JKSHJ Offline
                            JKSH
                            Moderators
                            wrote on last edited by
                            #23

                            [quote author="goli" date="1356439206"]The Timer was created in the run(in the exec of the thread) function of the new thread with startTimer function. This way I create Event loop for this thread that is saperate from the main thread. I keep the ID of this timer and kill him when the thread is finished. The main thread is the one who kill the timer, but I can't see other way to kill this timer that was created in the exec of the thread...[/quote]Let's see if I understood your method: You subclassed a QThread (let's call it a SubclassedQThread), started a timer in SubclassedQThread::run(), and started an event loop by calling exec() In SubclassedQThread::run()?

                            Firstly, you must remember that QThread is NOT a thread; QThread is a thread manager. Code inside SubclassedQThread::run() runs in the other thread, BUT the SubclassedQThread object lives in the main thread.

                            So, your problem doesn't begin when you kill your timer; it begins when you START your timer, because:

                            • Your SubclassedQThread lives in the main thread, but
                            • You start the timer from the other thread, and

                            Now, timers are supposed to run in the same thread as the object they belong to, so your timer is started in the "wrong" thread.

                            Is this confusing? Don't worry, you are not alone. Many people have faced similar problems like yours, because of QThread's design.

                            QThread's developer realized that the design is unintuitive, so he made a new recommendation: Avoid subclassing QThread. This is especially important if you use an event loop in your new thread!

                            If you'd like, I can write an example to show you how to use timers in a multithreaded program properly. Before that though, I'd like to ask: What do you want your program to do? Why do you want a timer in a separate thread?

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

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              astodolski
                              wrote on last edited by
                              #24

                              [quote author="JKSH" date="1356353967"][quote author="astodolski" date="1356287500"]
                              @
                              connect((QObject*)button(QWizard::CancelButton), SIGNAL(clicked()), worker, SLOT(stop()));
                              @

                              The Cancel button has no effect on the process.[/quote]I notice you have a custom Qt Designer UI for your FlashWizard. Are you still using the QWizard's built-in Cancel button, or did you implement a new one in Qt Designer? button(QWizard::CancelButton) returns a pointer to the built-in button, but this button doesn't exist if you implemented your own UI.

                              Also, the (QObject*) typecast is unnecessary -- the compiler should cast it for you automatically. Furthermore, if you ever need to make an explicit typecast, using qobject_cast<> is safer, as Qt will perform a run-time check to see if the cast is valid.

                              [quote author="goli" date="1356332295"]I create a class that inherit ThreadManager and in the run() function I create a timer with timerEvent:
                              @
                              startTimer(1000);
                              @

                              when the program end I get this warrning...[/quote]QThread IS a thread manager (see http://qt-project.org/doc/qt-5.0/qtcore/qthread.html for a full description, and a small example on how to use QThread). Your code is wrapping a thread manager in a thread manager, so I recommend redesigning it.

                              Read astodolski's code from 21 December and my reply (http://qt-project.org/forums/viewthread/22916/#107177 ) -- is your issue the same?
                              [/quote]

                              I use the Cancel button from the Wizard created in the ui in the designer. That's why I originally used the reject() method.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                astodolski
                                wrote on last edited by
                                #25

                                [quote author="goli" date="1356332295"]I have embedded device, and I don't get this warrning on the device.
                                [/quote]

                                I target desktop on Windows. Could be a bug?

                                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