Results 1 to 12 of 12

Thread: How to use multiple instances of a class containing QTimer?

  1. #1
    Join Date
    Jul 2012
    Posts
    4
    Platforms
    Windows

    Default How to use multiple instances of a class containing QTimer?

    Hello,
    I have written two classes, one of which uses QTimer. My first class creates a QVector of my second class and in each instance of the second class, a QTimer is started in order to increment a counter periodically until it reaches a maximum. In other words, I have 5 timers running each in their respective class instance. I have no compile or execution errors but the timer's slot never seems to be called. I guess this means that the timeout signal of each qtimer is not called either... why? Are the QTimers out of scope before the timeout signal can be sent? I don't see why, as all instances of the classes remain active throughout... I have seen the comment on using QTimer in multiple threads here, except that I'm not using threads. Does anyone have any idea where I'm going wrong? Thanks very much in advance. My simplified code is as follows:

    .h of my first class:
    Qt Code:
    1. #include <QVector>
    2.  
    3. class MyFirstClass {
    4. public:
    5. void Initialize();
    6. void Run();
    7. QVector<QSharedPointer<MySecondClass> > mMySecondClass;
    8. }
    To copy to clipboard, switch view to plain text mode 
    .cpp of my first class:
    Qt Code:
    1. void MyFirstClass::Initialize() {
    2. mMySecondClass.resize(5); // Create 5 instances of second class
    3. for (i = 0; i<mMySecondClass.size(); ++i) { // Initialize all 5 instances
    4. mMySecondClass[i] = QSharedPointer<MySecondClass>(new MySecondClass);
    5. mMySecondClass[i]->Initialize();
    6. }
    7. }
    8.  
    9. void MyFirstClass::Run() {
    10. for (i = 0; i<mMySecondClass.size(); ++i) { // Call Run for all 5 instances of second class
    11. mMySecondClass[i]->Run();
    12. }
    13. }
    To copy to clipboard, switch view to plain text mode 
    .h of my second class:
    Qt Code:
    1. #include <QTimer>
    2.  
    3. class MySecondClass: public QObject {
    4. Q_OBJECT
    5. public:
    6. void Initialize();
    7. void Run();
    8.  
    9. protected slots:
    10. void TimerSlot(); // slot connected to timeout of QTimer
    11.  
    12. protected:
    13. QTimer *mMyTimer;
    14. int mCounter;
    15. }
    To copy to clipboard, switch view to plain text mode 
    .cpp of my second class:
    Qt Code:
    1. void MySecondClass::Initialize() {
    2. mMyTimer= new QTimer();
    3. }
    4.  
    5. void MySecondClass::Run() {
    6. mCounter = 0; // initialize counter
    7. connect(mMyTimer, SIGNAL(timeout()), this, SLOT(TimerSlot())); // connect timer signal to slot
    8. mMyTimer->start(5); // start timer
    9. }
    10.  
    11. void MySecondClass::TimerSlot() {
    12. mCounter += 1; // increment counter
    13. if (mCounter > 10) { // stop timer when counter reaches 10
    14. mMyTimer->stop();
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 
    Example implementation:
    Qt Code:
    1. MyFirstClass foo;
    2. foo.Initialize();
    3. foo.Run();
    To copy to clipboard, switch view to plain text mode 
    Last edited by nhungr; 20th July 2012 at 11:44.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to use multiple instances of a class containing QTimer?

    QVector::resize() will not create instances of your class. It will create instances of QSharedPointer.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jul 2012
    Posts
    4
    Platforms
    Windows

    Default Re: How to use multiple instances of a class containing QTimer?

    Oops yes, you're right, I have to call new. I forgot a line in the code above. I've added it as line 4 in the code above for for the .cpp of my first class. The problem remains though... Any ideas?
    Thanks.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to use multiple instances of a class containing QTimer?

    Are you able to prepare a minimal compilable example reproducing the problem? By the way, your code is leaking memory.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: How to use multiple instances of a class containing QTimer?

    Where do you initialize your 'mCounter'?
    And how do you know if your slot has been called or not?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  6. #6
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to use multiple instances of a class containing QTimer?

    Let me add a couple of questions:
    - QTimer needs an event loop to be running for events to be delivered; can you confirm that an event loop is running at some point between the initialization of the MyFirstClass instance (allocation, Initialize() and Run()) and its destruction?
    - On a side note: why do you use Initialize() methods instead of constructors, thus running the risk of using objects in an uninitialized state?

  7. #7
    Join Date
    Jul 2012
    Posts
    4
    Platforms
    Windows

    Default Re: How to use multiple instances of a class containing QTimer?

    Thanks for the useful hints! The problem did indeed come from the fact that I didn't have an events loop running... which means my qtimer::connect events didn't get processed. So I need to make a call to QCoreApplication::exec(), as shown here for example. Although it works now, it's made me run into another conceptual problem: is there any way of interrupting the qtimers prematurely (by pressing a key on the keyboard for example) since the application now requires the exec routine to terminate before moving on?

  8. #8
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to use multiple instances of a class containing QTimer?

    yes, there is a way to stop a timer
    http://doc.qt.io/qt-4.8/QTimer#stop
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  9. #9
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to use multiple instances of a class containing QTimer?

    Now that your application has an event loop, you indeed need to call QCoreApplication::exit() or QCoreApplication::quit() for the program to exit. If I understand correctly, currently your application runs in a console, sets up some timers, some functions are called when they time out, and at some point QCoreApplication::quit() is called. Now you would also like your application to exit immediately when a certain key is pressed without waiting for the above scenario to complete. Is that correct?

    If it is the case, then you do not need to stop the timers. What you need is a way to handle some event (key press, or termination request from the OS) and make sure that QCoreApplication::quit() gets called. This is not trivial (and unfortunately platform-specific), but it may not be necessary. In its current state, your program is immediately killed if you hit Ctrl+C as it (currently) ignores the termination request. Of course this ends the program brutally but it is OK if no cleanup is required. It is definitely something to avoid if e.g. your program may be in the middle of writing to some files. So the main question is: is it acceptable if your program gets killed without having the chance to run some cleanup code?

  10. #10
    Join Date
    Jul 2012
    Posts
    4
    Platforms
    Windows

    Default Re: How to use multiple instances of a class containing QTimer?

    Yes, that's exactly what I need. However, instead of exiting the application entirely, I want it just to exit the events loop and then continue with the rest of the code in my main loop. In other words. is there a way of polling inside the Qtimer slot whether a key has been pressed and stopping the timer in consequence? Once the last timer has been stopped, quit the events loop and go on with the rest of the code?
    Perhaps my approach of using qtimers is not a good approach? Is it worthwhile looking into using QThreads instead?
    Thanks very much.

  11. #11
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to use multiple instances of a class containing QTimer?

    to deal with key press events you would normally have a gui and be using widgets. Otherwise you are either dealing with non-standard c++ headers or doing things like peek or cin.get.


    I don't know if QCoreApplication::winEventFilter could help you whilst not using any gui to handle key presses
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to use multiple instances of a class containing QTimer?

    Usually it's possible to monitor stdin using QSocketNotifier but it requires to disable buffering for stdin.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Replies: 2
    Last Post: 19th October 2011, 09:30
  2. Multiple instances of QWebView
    By darious in forum Qt Programming
    Replies: 1
    Last Post: 11th October 2011, 07:55
  3. Replies: 2
    Last Post: 2nd April 2011, 14:35
  4. Multiple program instances
    By scwizard in forum Qt Programming
    Replies: 13
    Last Post: 1st April 2007, 17:42
  5. accessing my own class-instances
    By mikro in forum Newbie
    Replies: 3
    Last Post: 11th July 2006, 00:10

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.