简体   繁体   English

在Qt中为QGraphicsObject / QGraphicsItem设置动画

[英]animating a QGraphicsObject/QGraphicsItem in Qt

Situation : An upper class dialog generates a raster with squares. 情况 :上层dialog生成带有正方形的栅格。 A player sits at (0,0) and when the user clicks on a square a pathfinding algoritm pathFind generates a QString of directions the player has to take to reach this goal. 玩家坐在(0,0)处,并且当用户单击一个正方形时,寻路算法pathFind生成一个QString方向,指示玩家必须达到该方向。 The QString is then converted to an array of int . 然后将QString转换为int数组。

dialog calls a function from the mysquare class named movePlayer which should move the player in the correct direction. dialogmysquare类调用了一个名为movePlayer的函数,该函数应将播放器向正确的方向移动。

This movement should not happen instantaneous but at a certain rate which is why I'm trying to animate each movement so it takes a certain amount of time. 此运动不应该瞬时发生,而是一定速度,这就是为什么我要为每个运动设置动画,所以需要一定的时间。

My problem however is that the player square is not moving at all. 但是我的问题是玩家广场根本没有动。 Sometimes when I click somewhere outside of the grid it snaps to the ending position. 有时,当我单击网格外部的某个位置时,它会捕捉到结束位置。 Weird. 奇怪的。

MySquare class (the player) MySquare类(播放器)

 MySquare::MySquare(int x,int y, int w, int h){
        curX = x;
        curY = y;

    initX = x;
    initY = y;
    width = w;
    height = h;
    posAnimation.setPropertyName("getGridPos");
    posAnimation.setTargetObject(this);
}


bool MySquare::movePlayer(int direction){
    switch (direction){
    case 0: //move right
        curX+=width;
        break;
    case 1: //move up
        curY+=height;
        break;
    case 2: //move left
        curX+=-width;
        break;
    case 3: //move down
        curY+=-height;
        break;
    }
    //setPos(curX,curY);
    QPoint p;
    p.setX(curX);
    p.setY(curY);

    setGridPos(p);
    update();
    return true;
}

void MySquare::setGridPos(QPoint myPos) {
    posAnimation.setStartValue(pos());
    posAnimation.setDuration(2000); // 2 seconds
    posAnimation.setEndValue(myPos);
    posAnimation.start();
}


QPoint MySquare::getGridPos() const {
    return pos();
}

MySquare header (the player) MySquare标头(播放器)

 class MySquare : public QGraphicsObject
    {
        Q_OBJECT
        Q_PROPERTY(QPoint getGridPos READ getGridPos WRITE setGridPos) // define meta-property "pos"s
    public:
    QPropertyAnimation posAnimation;
    MySquare(int x,int y,int h, int w);
    QRectF boundingRect() const; //outer most edges of the object
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    bool movePlayer(int direction);
public slots:
    QPoint getGridPos() const; // getter
    void setGridPos(QPoint p); // setter

signals:
    void targetChanged(int x, int y);

private:
    int curX,curY,height,width,initX,initY;
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
};

edit: 编辑:

  • I've added some qDebug inside the setGridPos which are all immediately printed; 我在setGridPos中添加了一些qDebug,这些都可以立即打印出来。 which is telling me that the script is not blocking on the animation which could be part of the problem. 这告诉我脚本没有阻止动画,这可能是问题的一部分。

edit2: 编辑2:

  • It seems it works when I only call the movePlayer function once; 当我只调用一次movePlayer函数时,它似乎可以工作;

edit3: I have a feeling it might be resolved using an animation group. edit3:我觉得可以使用动画组来解决。

Use a QSequentialAnimationGroup . 使用QSequentialAnimationGroup

From the second time I called movePlayer the animation stops working. 从我第二次调用movePlayer开始,动画就停止了工作。 I had to rewrite some parts of the dialog aswel: now the directions are no longer given one by one but are passed trough a vector. 我不得不重写dialog某些部分:现在不再逐一给出方向,而是通过矢量传递。 I hope I didn't add any memory leaks using the 'new' but I don't think there is any way around it. 我希望我没有使用“ new”添加任何内存泄漏,但我认为没有任何解决方法。

 void MySquare::movePlayer(std::vector <int> directions){
        QSequentialAnimationGroup *group = new QSequentialAnimationGroup;
        //determine direction
        //& add each element to the group
        QPoint startPosition;
        startPosition.setX(pos().x());
        startPosition.setY(pos().y());

        for (int i=0; i<directions.size(); i++){
            int direction = directions[i];
            switch (direction){
            case 0: //move right
                curX+=width;
                break;
            case 1: //move up
                curY+=height;
                break;
            case 2: //move left
                curX+=-width;
                break;
            case 3: //move down
                curY+=-height;
                break;
            }

            QPoint endPosition;
            endPosition.setX(curX);
            endPosition.setY(curY);

            QPropertyAnimation *animation = new QPropertyAnimation(this,"getGridPos");
            animation->setStartValue(startPosition);
            animation->setDuration(1000); // 1 seconds
            animation->setEndValue(endPosition);
            group->addAnimation(animation); ////add animatons to a QSequentialAnimationGroup
            //delete animation;

            //update startPosition for next loop
            startPosition.setX(endPosition.x());
            startPosition.setY(endPosition.y());
        }
        qDebug() << "start animation group" << endl;
        group->start();
        update();
        //delete group;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM