Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, May 2008
Problem with QTimeLine


Message 1 in thread

Hi,

I use an QTimeLine as a member of an QGraphicsRectItem sub-class in order to 
animate it (QGraphicsRectItem subclass) across a given QPainterPath. I 
connect QTimeLine 's signal finished() to a slot AnimationDone() of the 
animated class to process something after the animation is finished.

The following is the code for activating animation:
--------------------------------------------
        m_AnimatingTimeLine.setDuration(5000);      //m_AnimatingTimeLine is 
an 
QTimeLine
        m_AnimatingTimeLine.setFrameRange(0, 100);
        //
        qreal t = 0;    
        //
        while (t <= 0.99){
                QPointF pt  = path->pointAtPercent(t);          //path is an 
QPainterPath 
                m_Animation->setPosAt(t, 
QPointF(pt.x()-boundingRect().width()/2, 
pt.y()-boundingRect().height()/2));   //m_Animation is an 
QGraphicsItemAnimation
                //
                t += 0.01;
        }
        //
        m_AnimatingTimeLine.start();
---------------------------------------------

The problem is that when I call this code from an non-Qt-graphics class, it 
works fine, at least at the point that after the duration the AnimationDone() 
coupled with signal QTimeLine::finished() is called. 

But when I call it from a Qt-graphics class, specifically another 
QGraphicsItem sub class, then it does not work although the last code line      
m_AnimatingTimeLine.start() is reached, and state of the QTimeLine instance 
changes to Running already. The slot AnimationDone() is not called at all.

It took me a day to find the reason but I am still stuck. If you expect any 
reasons for that, please let me know.

Thank you very much.

.Viet Trung.

--
 [ signature omitted ] 

Message 2 in thread

On Tuesday 13 May 2008 03:47, Do Viet Trung wrote:

>
> But when I call it from a Qt-graphics class, specifically another
> QGraphicsItem sub class, then it does not work although the last
> code line       m_AnimatingTimeLine.start() is reached, and state
> of the QTimeLine instance changes to Running already. The slot
> AnimationDone() is not called at all.
>

QGraphicsItem is not a QObject.  To have slots, your class must 
inherit from QObject.

If this doesn't explain your problem, try providing us with a 
simple, complete testcase; your explanation doesn't tell us what 
AnimationDone() is supposed to do, how/where the connection is 
established, or the location of the code you pasted.

-- 
 [ signature omitted ] 

Message 3 in thread

Hi,

Thanks a lot for your reply.

> QGraphicsItem is not a QObject.  To have slots, your class must
> inherit from QObject.
Yes, my class already inherits from QObject, so I think it is not the reason.

So far I think it seems to be caused by something else rather than QTimeLine, 
so let me describe more details about my problem:

I would like to animate different graphics objects at the same time, more 
specifically in my case, sending messages from one network node S to several 
other nodes (D1, D2,.., Dn) across corresponding paths between them at the 
same time. 

Note that a path between the source and a destination node may go through some 
intermediate nodes, e.g. S------>A---->B----->Di. Therefore a path may insist 
of more than one links (a direct connection between two nodes). A message run 
from S to Di should arrive to A and then to B and finally to Di.

Messages, links, nodes are graphics objects and inherited from QGraphicsItem 
and QObject.

To do so, my general idea is: 

 All the following procedure is written in one class inherited from QObject:
---------------------------------------------
1      - Define a slot named __AnimateMessage(path) which  moving the message 
across the path;
	- Define a signal named _AnimateMessage(path) which triggers the above slot;

2. In the main function AnimateMessage(S, {Di}):

        + for each destination node Di in {Di}{
            - find path Pi from S to Di ---> get collection of links;
	    - emit _AnimateMessage(path) signal;
            - consider D(i+1);
        }
        + waiting for the message arrives ALL {Di} using a QWaitCondition Q1;
  }  //end of AnimateMessage()

3. Back to the slot __AnimateMessage(path):

    + for each link Lj in the path{
	    - call Lj->ForwardMessage() which in turn emits Lj's signal 
_ForwardMessage(). This signal triggers the private function 
Lj->__ForwardMessage(). In turn, it creates a graphical message and moves it 
across the line of the link (using QTimeLine);
           - wait the animation on Lj finish using a QWaitCondition Q2; 
	   - consider L(j+1);
    }
    + wake Q1 to inform the main function that the message reaches a 
destination node;
} // end of slot __AnimateMessage()
------------------------------------------

With the code like above, it is stuck at Q2 waiting, i.e., the animation in Lj 
does not work.  So it cannot wake up the Q2 which should be done if the 
animation is finished.

If I call the slot __AnimateMessage(path) directly from the main function 
rather than triggering it by emitting the signal _AnimateMessage(), then the 
slot function works fine. But this way does not fulfill my need.

The reason why I emit the signal _AnimateMessage() in main function rather 
than calling directly slot __AnimateMessage() is that I think with this way I 
can activate all the animations approximately at the same time.

Sorry for a long writing but I want you to understand thoughfully about it so 
that you can give me ideas.

Thanks for your time. I am looking forward to hearing from you.

.Viet Trung.


On Tuesday 13 May 2008 01:16, you wrote:
> On Tuesday 13 May 2008 03:47, Do Viet Trung wrote:
> > But when I call it from a Qt-graphics class, specifically another
> > QGraphicsItem sub class, then it does not work although the last
> > code line       m_AnimatingTimeLine.start() is reached, and state
> > of the QTimeLine instance changes to Running already. The slot
> > AnimationDone() is not called at all.
>
> QGraphicsItem is not a QObject.  To have slots, your class must
> inherit from QObject.
>
> If this doesn't explain your problem, try providing us with a
> simple, complete testcase; your explanation doesn't tell us what
> AnimationDone() is supposed to do, how/where the connection is
> established, or the location of the code you pasted.

--
 [ signature omitted ] 

Message 4 in thread

Hi,

> Messages, links, nodes are graphics objects and inherited from QGraphicsItem 
> and QObject.

Like this?
	class QGraphicsItem_sub_class : public QObject, public QGraphicsItem {
	    // ...
	};
Or like that?
	class QGraphicsItem_sub_class : public QGraphicsItem, public QObject {
	    // ...
	};


-- 
 [ signature omitted ] 

Message 5 in thread

Hi,

Thanks for your reply.

Regarding your question, it is like this:

class QGraphicsItem_sub_class : public QObject, public QGraphicsItem{ 	    
                 // ...
};

, because I used to get compile errors with the other.

Best regards,

.Viet Trung.


On Tuesday 13 May 2008 20:59, Dimitri wrote:
> Hi,
>
> > Messages, links, nodes are graphics objects and inherited from
> > QGraphicsItem and QObject.
>
> Like this?
> 	class QGraphicsItem_sub_class : public QObject, public QGraphicsItem {
> 	    // ...
> 	};
> Or like that?
> 	class QGraphicsItem_sub_class : public QGraphicsItem, public QObject {
> 	    // ...
> 	};

--
 [ signature omitted ] 

Message 6 in thread

On Tuesday 13 May 2008 20:43, Do Viet Trung wrote:

>
> Sorry for a long writing but I want you to understand thoughfully
> about it so that you can give me ideas.
>

I notice that you are using QWaitCondition, but you don't mention 
the use of threads anywhere.  QWaitCondition is intended to be used 
in multithreaded apps.

What you described should be possible without using threads.

-- 
 [ signature omitted ] 

Message 7 in thread

Hi,

Thanks for your reply.

You are right, I use QWaitCondition is just for a purpose of waiting until one 
animation finished without spending CPU time. Actually I do not know another 
way to do so. So if you have any idea about that, please let me know.

On the other hand, I am not sure but I think emitting signals to activate 
slots at the same time in Qt may be considered as using multithreads. Is this 
right?

Thanks again for your attention.

Have a nice day!

.Viet Trung.




On Wednesday 14 May 2008 01:28, Rohan McGovern wrote:
> On Tuesday 13 May 2008 20:43, Do Viet Trung wrote:
> > Sorry for a long writing but I want you to understand thoughfully
> > about it so that you can give me ideas.
>
> I notice that you are using QWaitCondition, but you don't mention
> the use of threads anywhere.  QWaitCondition is intended to be used
> in multithreaded apps.
>
> What you described should be possible without using threads.

--
 [ signature omitted ] 

Message 8 in thread

Hi,

"Do Viet Trung" <viet.trung.do@xxxxxxxxxxxxxx> wrote in message 
news:200805140956.53112.viet.trung.do@xxxxxxxxxxxxxxxxx
> You are right, I use QWaitCondition is just for a purpose of waiting until 
> one
> animation finished without spending CPU time. Actually I do not know 
> another
> way to do so. So if you have any idea about that, please let me know.
Take a look at the Qxt library (on http://www.libqxt.org/page/index). It has 
a class that allows you to make a piece of code wait for a signal: 
http://docs.libqxt.org/classQxtSignalWaiter.html.

> On the other hand, I am not sure but I think emitting signals to activate
> slots at the same time in Qt may be considered as using multithreads. Is 
> this
> right?
No, that is certainly NOT right. Threads are something completely different 
than asynchronic programming in general.

André
 

--
 [ signature omitted ]