[Solved] QAnimations: what's the best way to print flippable cards?
-
@Pippin
Hi this one is having flip code
https://blog.qt.io/blog/2009/06/09/flippin-widgets-medium-rare-please/
with animation. maybe you can reuse some of it. -
@mrjj good one ! Indeed, the code easily be re-used since it's already using the graphics view framework.
-
@mrjj Thanks a lot, that is very helpful. A bit old though (2009), I see a method
rootState()
that doesn't exist anymore. -
@Pippin
indeed at bit old.
They talk about it here. (rootState())
http://stackoverflow.com/questions/7051146/qt-animation-member-doesnt-existQState *state1 = new QState(machine);
seems to be same as rootState -
@mrjj Thank you again. I've been willing to use your link but I would have questions.
How can I link a QState to a QGraphics(Pixmap)Item ?
QState::assignProperty
takes QObjects as first argument, but QGraphics(Pixmap)Item are not QObjects. -
hi
i think you need to make you own QGraphicsObject
that controls the image drawing.
Then add a new property for switching the image to next one and
use that for QState::assignProperty -
@mrjj said:
hi
i think you need to make you own QGraphicsObject
that controls the image drawing.
Then add a new property for switching the image to next one and
use that for QState::assignPropertyI'm really not familiar enough with Qt for that sadly... It's a real shame there is no simple way to do that. I'm a bit surprised that the beginner that I am finds right away something easy that is not easily done on Qt.
-
@Pippin
well the c++ of Qt does take some practice and knowledge of Class and subclasses and other
c++ related topic. Once mastering common c++ methods, its not that hard as it else would seem.Did you have a look at QML ? its another qt way that is more easy in regards to more dynamic
user interfaces.
For example it can just flip
http://doc.qt.io/qt-4.8/qml-flipable.html#details
and tons of other easy to use features. -
@mrjj I don't know how to use QML, the tutorial shows code but I failed to understand where to put it / how to link it with the rest of the project. I'm doing everything through
qmake
,make
and./run
in the terminal. I'm also not sure if QML can do anything I could do with C++ methods :S -
@Pippin
its not like c++
there is a viewer program and you can also embed in c++
http://www.ics.com/blog/whole-shebang-running-qml-files-directly
Google is your friend
You can mix with c++ so you can do most.
But depends on what you really need for project. -
@mrjj said:
@Pippin
its not like c++
there is a viewer program and you can also embed in c++
http://www.ics.com/blog/whole-shebang-running-qml-files-directly
Google is your friend
You can mix with c++ so you can do most.
But depends on what you really need for project.The thing is, the QGraphicsView/Scene is only part of a window, which is part of my global project. How exactly do I insert QML inside a Qt project?
-
hi
you can use createWindowContainer
http://www.ics.com/blog/combining-qt-widgets-and-qml-qwidgetcreatewindowcontainer
or like this
http://doc.qt.io/qt-4.8/qml-integration.html
(check if works for 5.5)But if most of is c++ , it might be overkill to use QML just to draw some cards.
Even if easy animation wise. You can try it out and see how much a hassle it is. -
Would it work if I created a class that inherits both from QObject and QGraphicsPixmapItem? Would that make the
assignProperty
thing work or is it more complicated than that? -
@Pippin
That should work. Remember Q_OBJECT in class.
Not much more needed
adding a property for advancing image
http://doc.qt.io/qt-5.5/properties.html
then use the CurrentFrame (or what you call it) with animation system to
load next image .
If I understand correctly that you have sequence of images that is the card flipping. -
Thank you for your help so far @mrjj
So I've created the class QSpecialGraphicsPixmapItem, which basically inherits from QObject and QGraphicsPixmapItem.
QPixmap *pix = new QPixmap("Images/A.png"); QSpecialGraphicsPixmapItem* item = new QSpecialGraphicsPixmapItem(*pix); item->setPos(100, 100); WindowScene.addItem(item); QStateMachine *machine = new QStateMachine(); QState *state1 = new QState(); state1->assignProperty(item, "rotation", 90); QState *state2 = new QState(); state2->assignProperty(item, "rotation", 0); state1->addTransition(&Button1, SIGNAL(clicked()), state2); state2->addTransition(&Button1, SIGNAL(clicked()), state1); machine->addState(state1); machine->addState(state2); machine->setInitialState(state1); machine->start();
But when I compile & execute it, the pixmap is not rotated by 90 as it should be (since state1 is the initial state). What am I missing? Edit: nvm, got it. I just had to add
Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
in the definition of the class QSpecialGraphicsPixmapItem. I'm starting to get it.
-
Good work!
If it works, please update to solved.
Im pretty sure many more in the future will want to flip cards. :) -
@mrjj Well not yet, I'm not quite flipping QGraphicsPixmapItems yet ^^
Let's suppose I want to flip an horizontal, face-down card so that it becomes a vertical, face-up card. Let's suppose I also want to move it in the process, from point A to point B. There are 3 transformations to operate at once:
- a rotation round the Z axis (horizontal to vertical: 90 degrees)
- a rotation round the Y axis (face-down to face-up: 180 degrees)
- a translation from (x_a, y_a) to (x_b, y_b)
My plan is to first create a transformation that will do half the above (1):
- a rotation round the Z axis (horizontal to oblique: 45 degrees)
- a rotation round the Y axis (face-down to <interim state> : 90 degrees)
- a translation from (x_a, y_a) to ([x_a + x_b]/2, [y_a + y_b]/2)
When this animation is over, I have to find a way to automatically run another function that will change the QPixmap, then initiate the rest of the transformation (2). I have no idea which signal conveys the information "Animation is Finished" in Qt 5.5 though. Once this is coded, I only have to create the second, and last, animation that will operate at once (3):
- a rotation round the Z axis (oblique to vertical: 45 degrees)
- a rotation round the Y axis (<interim state> to face-up : 90 degrees)
- a translation from([x_a + x_b]/2, [y_a + y_b]/2) to (x_b, y_b)
So basically, to do that, I have to find out the QTransform objects that will do (1) and (3) for me, and I have to find out how to "know" that my QObject has finished its first animation so that I can change its QPixmap then initiate the second animation (2).
If someone knows how to handle either part of the solution, feel free to share... Thank you.
Or maybe I should forget about the rotation round the Y axis and simply realize a scale from 0 to 1 x-wise. Not sure which is better.
-
oh, biit too early to celebrate ;)
Animations can tell when finished.
connect(animation, signal( finished() ), this, slot( XXx );
Also look at QSequentialAnimationGroup
http://doc.qt.io/qt-5/qsequentialanimationgroup.html#details -
@mrjj Okay thanks, I'll look into it. Do you have any idea how to use an animation based on a QTransform object? Is it even possible? Like, putting the starting value at Id, and the ending value at the matrix we want?
Or should I rather create 3 animations on the same object (1 translation + 1 scale x-wise OR 1 rotation round Y + 1 rotation round Z) ? Does Qt allow more than 1 animation at a time for a given object?
-
Well I only used QPropertyAnimation which needs a property.
Not seen any that took a QTransform. So I think it can't out of the box but
it might be possible in some way.--Does Qt allow more than 1 animation at a time for a given object
That I never tried. But if different props, I see no reason why not.