2014-06-27 5 views
1

В этой программе я построил QPropertyanimation и добавлю к нему свой товар и pos(). I override KeyPressEvent. И с помощью клавиш состоят из J, ф, г вещи идти forward, идти back и jump.использование qpropretyanimation желательно

Под действием силы тяжести, когда прыжок пункта должен падать. Для этого я вызываю функцию down. Но предмет сразу после прыжка не падает. У меня также есть еще одна проблема: когда первое нажатие j и f (вперед и назад) элемент анимируется желательно, но для пункта следующего раза идти вперед и возвращать всю сцену.

Я имею в виду, он должен анимировать, например, 40 пикселей, но он анимированный 800 пикселей.

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    QPoint start; 
    QPoint end; 
    ~MainWindow(); 
private: 
    QGraphicsView* view; 
    QGraphicsScene* scene; 
    void keyPressEvent(QKeyEvent* k); 
    MyQgraphicsObject* m; 
    QPropertyAnimation* pr; 
    QElapsedTimer* timer; 
    int f; 
    int u; 
    int b; 
    void forward(); 
    void up(); 
    void back(); 
    void down(); 
}; 

MainWindow::MainWindow(QWidget *parent) : 
     QMainWindow(parent) 
{ 
    view=new QGraphicsView; 
    scene=new QGraphicsScene; 
    m=new MyQgraphicsObject; 
    pr=new QPropertyAnimation(m,"pos"); 
    view->setScene(scene); 
    view->resize(800,800); 
    view->setFixedSize(800,800); 
    setCentralWidget(view); 
    scene->addItem(m); 
    start= QPoint(0,0); 
    f=30; 
    u=-30; 
    b=-30; 
} 

void MainWindow::keyPressEvent(QKeyEvent *k) 
{ 
    switch (k->key()) { 
    case Qt::Key_J: { 
     forward(); 
     break; 
     } 
    case Qt::Key_Z: { 
     up(); 
     down(); 
     break; 
     } 
    case Qt::Key_F: { 
     back(); 
     break; 
     } 
    default: 
     break; 
    } 
} 

void MainWindow::forward() 
{ 
    end.setX(f); 
    pr->setEndValue(end); 
    pr->setDuration(1000); 
    pr->setEasingCurve(QEasingCurve::Linear); 
    pr->start(); 
    f+=40; 
} 

void MainWindow::up() 
{ 
    end.setY(u); 
    pr->setEndValue(end); 
    pr->setDuration(1000); 
    pr->setEasingCurve(QEasingCurve::Linear); 
    pr->start(); 
    u-=30; 
    pr->pause(); 
} 

void MainWindow::back() 
{ 
    end.setX(b); 
    pr->setEndValue(end); 
    pr->setDuration(1000); 
    pr->setEasingCurve(QEasingCurve::Linear); 
    pr->start(); 
    b-=40; 
} 

void MainWindow::down() 
{ 
    u+=30; 
    end.setY(u); 
    pr->setEndValue(end); 
    pr->setDuration(1000); 
    pr->setEasingCurve(QEasingCurve::Linear); 
    pr->start(); 
} 
+0

Код слишком низкого качества. Я не могу догадаться, для чего нужны однобуквенные переменные. Также вызов 'down()' сразу после 'up()' не будет делать то, что вам нужно. Анимация асинхронна. Вам нужно настроить 'QTimer' и периодически вызывать' down() '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''). Кроме того, если пользователь нажимает клавишу при выполнении анимации, нужно сделать еще одну анимацию, но это не будет сделано, потому что 'pr-> start()' ничего не делает, если анимация уже выполняет. –

+0

извините за мой код. Вы сказали, что я должен использовать [QTimer]. Где я его использую? Call down() снова после up.if возможно поставить пример кода для руководства me.i действительно нужно для этой программы. Я очень новичок в qt. особенно в [QGraphicsView] и анимации. – sarina

ответ

2

Вы не должны использовать resize и setFixedSize на view, потому что вы используете его в setCentralWidget и его размер будет управляться макете. Вместо этого вы должны использовать setFixedSize.

Анимация асинхронная. Например, когда вы вызываете up(); down(), эти функции будут выполняться без паузы в 1 секунду. Кроме того, запуск анимации, когда он уже запущен, не влияет.

Обычно анимации используются таким образом, когда вы точно знаете, где вам нужно перемещать объект в следующую секунду. Сложно получить директивы от пользователя и изменить траекторию объекта, когда анимация уже выполняется.

Вот пример правильного использования анимаций для этой задачи. Объект может получать одну директиву (вперед, назад или прыгать) в секунду, а согласно анимации будет выполняться в следующую секунду.

Заголовок:

class MainWindow : public QMainWindow { 
    Q_OBJECT  
public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 
private: 
    QGraphicsView* view; 
    QGraphicsScene* scene; 
    void keyPressEvent(QKeyEvent* k); 
    QGraphicsObject* object; 
    QPropertyAnimation* animation; 
    QPointF pos; 
    double speed; 

    enum Command { 
    command_none, command_jump, command_forward, command_back 
    }; 
    Command next_command; 

private slots: 
    void timeout(); 
}; 

Источник:

MainWindow::MainWindow(QWidget *parent) : 
     QMainWindow(parent) 
{ 
    view = new QGraphicsView; 
    scene = new QGraphicsScene; 
    object = scene->addWidget(new QPushButton("test")); 
    object->setPos(0, -object->boundingRect().height()); 
    animation = new QPropertyAnimation(object,"pos"); 
    animation->setDuration(1000); 
    view->setScene(scene); 
    setFixedSize(800,800); 
    scene->addRect(-500, -200, 1000, 200); 
    setCentralWidget(view); 
    scene->addItem(object); 
    next_command = command_none; 
    speed = 100; 

    QTimer* timer = new QTimer(this); 
    connect(timer, SIGNAL(timeout()), this, SLOT(timeout())); 
    timer->start(1000); 
} 

MainWindow::~MainWindow() {} 

void MainWindow::keyPressEvent(QKeyEvent *k) 
{ 
    switch (k->key()) { 
    case Qt::Key_J: { 
    next_command = command_forward; 
    break; 
    } 
    case Qt::Key_Z: { 
    next_command = command_jump; 
    break; 
    } 
    case Qt::Key_F: { 
    next_command = command_back; 
    break; 
    } 
    default: 
    break; 
    } 
} 

void MainWindow::timeout() { 
    //fall 
    if (pos.y() < 0) { 
    pos.setY(pos.y() + speed); 
    if (pos.y() >= 0) { 
     pos.setY(0); 
    } 
    } 
    //action 
    switch(next_command) { 
    case command_forward: 
    pos.setX(pos.x() + speed); 
    break; 
    case command_back: 
    pos.setX(pos.x() - speed); 
    break; 
    case command_jump: 
    if (pos.y() == 0) { 
     pos.setY(pos.y() - speed); 
    } 
    break; 
    default: 
    break; 
    } 
    next_command = command_none; 
    animation->stop(); 
    animation->setEndValue(pos - QPointF(0, object->boundingRect().height())); 
    animation->start(); 
} 
+0

: Благодарю вас за ответ answer.i скомпилируйте ваш код. Но у него есть одна ошибка. 'object = scene-> addwidget (новый QPushButton ("test"); 'я решил не использовать анимацию. И я меняю' x' и 'y' мой пункт напрямую. Но теперь я не знаю, как остановить мой item.can я задаю этот вопрос на этой странице, как Answer.or снова спросить на этом сайте. – sarina

+0

если возможно, посетите этот пост. никто не отвечает мне. [http://stackoverflow.com/questions/24475305/how-to-remove-extra-margins-arounding-a-qpixmap] – sarina