Results 1 to 6 of 6

Thread: QTimeLine in QtConcurrent - C++

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Dec 2016
    Posts
    7
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default QTimeLine in QtConcurrent - C++

    Hallo, I have the following question, I'm trying to do the next thing, when a player kills 2 enemies they should die simultaneously with simple animation
    (a few pics change over time). So in order to achieve this parallelism I create a number of threads equal to the number of enemies to be killed
    (e.g. 2 enemies to be killed = 2 threads to be created)

    below the code of creating threads, it works just fine:

    Qt Code:
    1. std::vector<QFuture<void>> threadResults;
    2. for(int i = 0; i < blantsToKill.size(); ++i) {
    3. threadResults.push_back(QtConcurrent::run(this, &GameManager::killBlant, std::ref(blantsToKill[i])));
    4. }
    5. std::for_each(threadResults.begin(), threadResults.end(), std::bind(&QFuture<void>::waitForFinished, std::placeholders::_1));
    To copy to clipboard, switch view to plain text mode 

    But here the problem appears, the function is called, and slots called as well, however i get the following message "QObject::startTimer: Timers cannot be started from another thread" and pictures for my QGraphicsPixmapItem are not updated.
    I tried Qt::QueuedConnection and it didn't help a bit.


    Qt Code:
    1. void Blant::die()
    2. {
    3. QTimeLine* timeLine = new QTimeLine(m_animationMoveTime);
    4. timeLine->setUpdateInterval(100);
    5. timeLine->setDuration(400);
    6. connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animateDying(qreal)), Qt::DirectConnection);
    7. connect(timeLine, SIGNAL(finished()), this, SLOT(finishDying()), Qt::DirectConnection);
    8. timeLine->start();
    9.  
    10. // so the function wouldn't return before animation finished.
    11. delay(400 + 100 * 2);
    12. }
    To copy to clipboard, switch view to plain text mode 

    I guess, it's important to note, that if I don't use threads my code works fine, but without parallel execution the enemies killed subsequently.
    Also except TimeLine created in this function, at this particular moment no other timers work.
    I thought problem could be with delay, however after substituting it with a code (just to check how it works without delay) like this:

    Qt Code:
    1. volatile long i = 0;
    2. while(i < 10000000000) {
    3. ++i;
    4. }
    To copy to clipboard, switch view to plain text mode 

    it's still the same problem.

    this is slot animateDying, finishDying is mostly the same.
    Qt Code:
    1. void Blant::animateDying(qreal)
    2. {
    3. qDebug() << "ololo" << m_nextFrame;
    4. setPixmap((m_blantsPictures[m_blantColor].dyings[m_nextFrame++]));
    5. if(m_nextFrame == m_blantsPictures[m_blantColor].dyings.size() - 1)
    6. m_nextFrame = 0;
    7.  
    8. }
    To copy to clipboard, switch view to plain text mode 

    So any help would be much appreciated, including any thoughts how the simultaneous effect could be achieved without addittional threads.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTimeLine in QtConcurrent - C++

    Qt GUI class instances can only be used in the main thread, i.e. the one started when your app starts. Possibly QTimeLine also falls into this category. In any case, you won't be able to access QGraphicsItem instances from a different thread, and updates to GUI class instances will always occur in the order in which the main event loop calls their paintEvents. You can't update different things on the GUI simultaneously no matter what.

    In the main thread you -can- use the Qt animation framework to nearly simultaneously make changes to your two bad guys by reworking your QTimeLine into QAbstractAnimation instead.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. The following user says thank you to d_stranz for this useful post:

    monnzz (14th December 2016)

  4. #3
    Join Date
    Dec 2016
    Posts
    7
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTimeLine in QtConcurrent - C++

    d_stranz, thank you very much for your help now I know where to look further.

  5. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QTimeLine in QtConcurrent - C++

    Quote Originally Posted by d_stranz View Post
    Possibly QTimeLine also falls into this category.
    Unlikely.

    But if die() is executed by a secondary thread then, due to the enforced DirectConnection, so will animateDying() and the setPixmap() call is definitely UI.


    Quote Originally Posted by d_stranz View Post
    In any case, you won't be able to access QGraphicsItem instances from a different thread, and updates to GUI class instances will always occur in the order in which the main event loop calls their paintEvents. You can't update different things on the GUI simultaneously no matter what.
    Well, yes and no.
    Obviously the items will be repainted one after each other, but that could still be in the same frame update for the view, thus appearing simultaniously updated.

    Quote Originally Posted by d_stranz View Post
    In the main thread you -can- use the Qt animation framework to nearly simultaneously make changes to your two bad guys by reworking your QTimeLine into QAbstractAnimation instead.
    Exactly. Even QTimeLine can do that.
    Using threads here is only necessary if the goal is to make the program as complex as possible.

    Cheers,
    _

  6. The following user says thank you to anda_skoa for this useful post:

    monnzz (14th December 2016)

  7. #5
    Join Date
    Dec 2016
    Posts
    7
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTimeLine in QtConcurrent - C++

    anda_skoa, thank you for the explanation
    So I've changed my program structure to do my "die" animation in one thread and it works like a charm

    In a few threads it was not possible to update my view. I could see slot working but animation wasn't going at all. I could see only the first state and the last, which is removing an enemy from the scene but it doesn't have anything to do with the animation, because clearly I remove items after the animation finished (by finished i mean after even finished() slot is finished .)

    Also I had that strange warning "QObject::startTimer: Timers cannot be started from another thread", and I didn't manage to figure out what was the cause. I don't have any external timers and, as you can see in my first post, QTimeLine is created in a child thread.

    Finally, I'm very grateful to you for your support, but it would be nice if you could suggest any explanation for that warning with timers in threads.

  8. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QTimeLine in QtConcurrent - C++

    Quote Originally Posted by monnzz View Post
    Finally, I'm very grateful to you for your support, but it would be nice if you could suggest any explanation for that warning with timers in threads.
    Hard to tell, maybe in your delay() function?

    If you want to debug this set a break point in QObject::startTimer at the place where it writes that warning and look at where the call is coming from.

    Cheers,
    _

Similar Threads

  1. qtimeline doesn't run
    By Nfrancisj in forum Newbie
    Replies: 7
    Last Post: 28th March 2016, 11:38
  2. QTimer and QTimeLine
    By martisho in forum Qt Programming
    Replies: 3
    Last Post: 24th November 2009, 14:29
  3. discontinuous QTimeLine problem
    By yagabey in forum Qt Programming
    Replies: 0
    Last Post: 2nd December 2008, 21:20
  4. QTimeLine
    By babu198649 in forum Newbie
    Replies: 6
    Last Post: 31st January 2008, 10:32
  5. QGraphicsItemAnimation and QTimeLine
    By babu198649 in forum Newbie
    Replies: 13
    Last Post: 31st December 2007, 11:34

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.