Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > QPropertyAnimation и QPixmap


Автор: Moby 25.10.2010, 16:08
Используя пример Easing Curves у меня не получается заставить двигаться рисунок.

Код

class PixmapItem : public QObject, public QGraphicsPixmapItem
 {
     Q_OBJECT
     Q_PROPERTY(QPointF pos READ pos WRITE setPos)
 public:
     PixmapItem(const QPixmap &pix) : QGraphicsPixmapItem(pix)
     {
     }
 };

Код

QGraphicsScene m_scene;
PixmapItem *pm;

Код

 QPixmap pix(QString(QCoreApplication::applicationDirPath()+"/imgs/pic1.bmp"));
    pm = new PixmapItem(pix);

    m_scene.addItem(pm);
    ui->graphicsView->setScene(&m_scene);

    QPropertyAnimation *animation = new QPropertyAnimation(pm, "geometry");
    animation->setDuration(8000);
    animation->setStartValue(QRect(0, 0, 100, 30));
    animation->setEndValue(QRect(250, 250, 100, 30));
    animation->setEasingCurve(QEasingCurve::Linear);
    animation->start();


Да еще вот такое получаю
Запускается C:\Qt\Fusion\Fusion\release\Fusion.exe...
QPropertyAnimation: you're trying to animate a non-existing property geometry of your QObject
QPropertyAnimation: you're trying to animate a non-existing property geometry of your QObject
C:\Qt\Fusion\Fusion\release\Fusion.exe завершился с кодом 0


В чем проблема, заранее спасибо. 

Автор: SABROG 26.10.2010, 09:26
Цитата(Moby @  25.10.2010,  16:08 Найти цитируемый пост)
В чем проблема, заранее спасибо.  

Так тебе же пишет Qt, что у твоего класса нет свойства "geometry". Максимум что есть это свойство "pos", надо добавлять свойство geometry и реализовывать методы geometry() и setGeometry().

Автор: Moby 2.11.2010, 15:21
Разобрался. За основу взял пример.

А как сделать так, что бы один пиксмап двигался влево, а другой вправо? Использовать два QPropertyAnimation? Я так попробовал но получил вот такую странную ситуацию: вот при таких настройках анимации 
 
Код

m_anim->setStartValue(QPoint(0,0));
m_anim->setEndValue(QPoint(C_point.x()*2-img1->width(),0));
m_anim->setDuration(ms);
m_anim->setLoopCount(1);
m_anim->start();

m_anim2->setStartValue(QPoint(0,0));
m_anim2->setEndValue(QPoint(0,0));
m_anim2->setDuration(ms);
m_anim2->setLoopCount(1);
m_anim2->start();

у меня два пиксмапа стартуют из середины экрана и двигаются до конца. так и надо. но вот если повторно запустить то один пиксмап остается на  месте (с краю экрана), а второй начинает движение, считая началом первый пиксмап. 
И я так не понял что означает setStart(End)Value, как то странно они эти координаты воспринимают.

1 - откуда такая зависимость берется

2 - как после стоп анимации вернуть пиксмапы на свои места, то есть в центр. 


Автор: SABROG 2.11.2010, 17:05
Код

m_anim2->setStartValue(QPoint(0,0));
m_anim2->setEndValue(QPoint(0,0));


Я вообще не понимаю как у тебя второй рисунок двигается, если стартовая координата равна конечной.

Автор: Moby 3.11.2010, 12:17
Я то же не понимаю. Я не понимаю вообще как это все работает. Ибо даже если я выставляю вот так
    
Код

void startanimation()
{
    m_anim->setStartValue(QPoint(C_point.x()-img1->width(),0));
    m_anim->setEndValue(QPoint(C_point.x()*2-img1->width(),0));   
    m_anim->start();

    m_anim2->setStartValue(QPoint(C_point.x()-img1->width(),0));
    m_anim2->setEndValue(QPoint(0,0));
    m_anim2->start();
}

То вроде бы все логично, но если, поворюсь, сделать принудительную остановку *->stop() дождаться окончания анимации и после опять вызвать startanimation(), то один пиксамп остается на своем месте, к примеру почти у края экрана, а второй началом считает его.

Сейчас код выложу. 

Да и кстати, а почему координата по У в setStart(End)Value не является тем, чем должна. То есть у меня У выставлен всюду 0. Но пиксампы по У расположены по центру экрана. Как это может быть? Я даже не вызываю QGraphicsScene->itemAt().

Вот релиз программки http://ifolder.ru/20088258

animation.h
Код

#ifndef ANIMATION_H
 #define ANIMATION_H

 #include <QtGui>

 #include <QtCore/qpropertyanimation.h>

 class Animation : public QPropertyAnimation {
 public:
     enum PathType {
         LinearPath,
         CirclePath,
         NPathTypes
     };
     Animation(QObject *target, const QByteArray &prop)
         : QPropertyAnimation(target, prop)
     {
         setPathType(LinearPath);
     }

     void setPathType(PathType pathType)
     {
         if (pathType >= NPathTypes)
             qWarning("Unknown pathType %d", pathType);

         m_pathType = pathType;
         m_path = QPainterPath();
     }

     void updateCurrentTime(int currentTime)
          {
              if (m_pathType == CirclePath) {
                  if (m_path.isEmpty()) {
                      QPointF to = endValue().toPointF();
                      QPointF from = startValue().toPointF();
                      m_path.moveTo(from);
                      m_path.addEllipse(QRectF(from, to));
                  }
                  int dura = duration();
                  const qreal progress = ((dura == 0) ? 1 : ((((currentTime - 1) % dura) + 1) / qreal(dura)));

                  qreal easedProgress = easingCurve().valueForProgress(progress);
                  if (easedProgress > 1.0) {
                      easedProgress -= 1.0;
                  } else if (easedProgress < 0) {
                      easedProgress += 1.0;
                  }
                  QPointF pt = m_path.pointAtPercent(easedProgress);
                  updateCurrentValue(pt);
                  emit valueChanged(pt);
              } else {
                  QPropertyAnimation::updateCurrentTime(currentTime);
              }
          }

     QPainterPath m_path;
     PathType m_pathType;
 };

 #endif // ANIMATION_H



window.h
Код

#ifndef WINDOW_H
#define WINDOW_H

#include <QWidget>
#include <QtGui>
#include <QKeyEvent>
#include <qdesktopwidget.h>
#include <QBitmap>
#include <qpainter.h>
#include "animation.h"

class PixmapItem : public QObject, public QGraphicsPixmapItem
 {
     Q_OBJECT
     Q_PROPERTY(QPointF pos READ pos WRITE setPos)
 public:
     PixmapItem(const QPixmap &pix) : QGraphicsPixmapItem(pix)
     {
     }
 };

namespace Ui {
    class Window;
}

class Window : public QWidget {
    Q_OBJECT
public:
    Window(QWidget *parent = 0);
    ~Window();

protected:
    void changeEvent(QEvent *e);

private:
    Ui::Window *ui;
    void startAnimation();
    void keyPressEvent(QKeyEvent* event);

    QPixmap *img1, *img2;
    QGraphicsScene m_scene;
    QGraphicsScene m_scene2;
    PixmapItem *m_item;
    Animation *m_anim;
    PixmapItem *m_item2;
    Animation *m_anim2;
    QPoint C_point;
    bool action, l;
    int ms;

private slots:
    void on_verticalSlider_actionTriggered(int action);
    void on_pushButton_2_clicked();
    void on_pushButton_clicked();
    void create();
    void create_img();
};

#endif // WINDOW_H



window.cpp
Код

#include "window.h"
#include "ui_window.h"

Window::Window(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Window)
{
    action = l = false;
    ms = 5000;

    ui->setupUi(this);

    QDesktopWidget *d = QApplication::desktop();
    C_point.setX(d->width()/2);
    C_point.setY(d->height()/2);

    ui->graphicsView->setGeometry(0,0,d->width(),d->height());

    create();

}

void Window::create()
{
    create_img();

    m_item = new PixmapItem(*img1);
    m_item2 = new PixmapItem(*img2);

    m_scene.addItem(m_item);
    //m_scene.itemAt(C_point.x()+1,C_point.y());
    m_scene.addItem(m_item2);
    //m_scene.itemAt(C_point.x()-1,C_point.y());
    //m_scene.itemAt(0,d->height()/2);
    ui->graphicsView->setScene(&m_scene);
    //ui->graphicsView->setScene(&m_scene2);
    m_anim = new Animation(m_item, "pos");
    m_anim->setEasingCurve(QEasingCurve::Linear);
    m_anim2 = new Animation(m_item2, "pos");
    m_anim2->setEasingCurve(QEasingCurve::Linear);
}

void Window::create_img()
{
    img1 = new QPixmap(QString(QCoreApplication::applicationDirPath()+"/imgs/1-1.bmp"));
    img2 = new QPixmap(QString(QCoreApplication::applicationDirPath()+"/imgs/1-2.bmp"));

    QPen pen(QBrush(QColor(66,111,199)), 0);

    QPainter p;
    p.begin(img1);
    p.setPen(pen);

    for (int i=0; i <= img1->height(); i+=2)
    {
        p.drawLine(0, i, img1->width(), i);
    }

    p.end();

    p.begin(img2);
    p.setPen(pen);

    for (int i=1; i <= img1->height(); i+=2)
    {
        p.drawLine(0, i, img1->width(), i);
    }

    p.end();

    img1->setMask(img1->createMaskFromColor(QColor(66,111,199), Qt::MaskInColor));
    img1->setMask(img1->createMaskFromColor(QColor(255,255,255), Qt::MaskInColor));
    img2->setMask(img2->createMaskFromColor(QColor(66,111,199), Qt::MaskInColor));
    img2->setMask(img2->createMaskFromColor(QColor(255,255,255), Qt::MaskInColor));

}

void Window::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Space)
    {

        ui->label->setText(QString(m_anim->currentValue().toInt()));
        m_anim->stop();
        m_anim2->stop();
        ui->frame->show();
        QWidget::setCursor( Qt::ArrowCursor);



    }

    if(event->key() == Qt::Key_S)
    {
        if(action)
        {
            startAnimation();
            action = false;
            l = true;
        }
    }
}

void Window::startAnimation()
{

    m_anim->setStartValue(QPoint(C_point.x()-img1->width(),0));
    m_anim->setEndValue(QPoint(C_point.x()*2-img1->width(),0));
    m_anim->setDuration(ms);
    m_anim->setLoopCount(1);
    m_anim->start();

    m_anim2->setStartValue(QPoint(C_point.x()-img1->width(),0));
    m_anim2->setEndValue(QPoint(0,0));
    m_anim2->setDuration(ms);
    m_anim2->setLoopCount(1);
    m_anim2->start();

}

Window::~Window()
{
    delete ui;
}

void Window::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void Window::on_pushButton_clicked()
{
    ui->frame->hide();
    m_scene.itemAt(C_point.x(),C_point.y());


    action = true;
    QWidget::setCursor( Qt::BlankCursor);
}

void Window::on_pushButton_2_clicked()
{
    this->close();
}

void Window::on_verticalSlider_actionTriggered(int action)
{
    if(ui->verticalSlider->value() == 1)
        ms = 15000;
    if(ui->verticalSlider->value() == 2)
        ms = 18000;
    if(ui->verticalSlider->value() == 3)
        ms = 21000;
    if(ui->verticalSlider->value() == 4)
        ms = 24000;
    if(ui->verticalSlider->value() == 5)
        ms = 27000;
}


Автор: SABROG 3.11.2010, 17:01
В твоем релизе у меня на компе вообще статичная картинка. Кнопку старт жал, ползунок менял, значение в QLineEdit тоже, ничто не влияет.

Автор: Moby 3.11.2010, 18:02
Я дурак, забыл сказать, что надо кнопку S еще жать )))

Автор: SABROG 3.11.2010, 18:44
Цитата(Moby @ 3.11.2010,  18:02)
Я дурак, забыл сказать, что надо кнопку S еще жать )))

Нажал, вроде нормально картинки разъезжаются, а как повторить не перезапуская программу хз.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)