0

I would like to display an animated arrow shape button.

To draw it, I creat a class which inheriths QGraphicsObjectand use the QPainterPath class.

I draw it in a QGraphicsScene and animate it using the property geometry, re defined in MyArrow class.

You can find all the code here : https://github.com/TaiZzZ/arrowAnimation

My issue is the following :

The arrow animates (meaning it moves right and comes back) but stays painted while moving. Do you have any idea why ?

Ps : I have the same behaviour using QState Machine, so I'm guessing the issue comes only from the way I draw my arrows.

I tried two different things :

  • Changing the bezier curve into line, it doesn't fix the problem.

  • Instead of drawing the path, I drew a rectangle(the boundingRect()) (So I only changed drawPath(path)), and it works

So to conclude, the bug comes from QPainterPath ... but why ?

EDIT :

Here are pictures to illustrate my problem :

Before the animation After the animation

Note that it is no longer anti-alliased...

TaiZzZ
  • 53
  • 11
  • What do you mean by "stays painted while moving"? Note also that your github repo appears to be incomplete -- I get "WARNING: Failure to find: mainwindow.ui" when I run `qmake`. – G.M. Jun 28 '17 at 08:25
  • In deed I forgot that file, now it should work properly. "stays painted while moving" isn't very clear, but I don't know how to explain the issue shortly ! May be the best option is to had pictures, so please refer to the pictures. – TaiZzZ Jun 28 '17 at 09:56

1 Answers1

2

The problem is actually quite straightforward -- you're not clearing your QPainterPath before reusing it.

Your Arrow class has a member...

QPainterPath arrow;

and your Arrow::paint implementation begins with...

arrow.moveTo(rect.right(),rect.center().y());
arrow.lineTo(rect.left(),rect.top());

So, each time Arrow::paint is called it's adding another new subpath to the QPainterPath. Hence, at any given time what you see is the accumulated paths . The simplest solution would be to remove the arrow member variable and use a locally scoped QPainterPath...

QPainterPath arrow;
arrow.moveTo(rect.right(),rect.center().y());
arrow.lineTo(rect.left(),rect.top());
G.M.
  • 12,232
  • 2
  • 15
  • 18