Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: lighting от Октябрь 09, 2009, 13:36



Название: Странное поведение QTimeLine
Отправлено: lighting от Октябрь 09, 2009, 13:36
Пробовал создать анимацию, и столкнулся с весьма странным поведением QTimeLine. Догадываюсь что на 99,999% ошибка в моем коде, но что-то никак ее не могу обнаружить.
mainwindow.h
Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QtGui/QMainWindow>
#include <QWidget>
#include <QtGui/QGraphicsView>
#include <QFileDialog>
 
class QTimeLine;
class QPushButton;
class QFileDialog;
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
public:
   MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
private slots:
   void dialogAppear();
   void dialogDisappear();
   void TimerNextFrame();
 
private:
   QGraphicsView *graphicsView;
   QGraphicsScene *scene;
   QPushButton *btnClose;
   QPushButton *btnShow;
   QFileDialog *fileDialog;
   QTimeLine *dialogAnimTimer;
   QGraphicsProxyWidget *item;
   QTransform transform;
 
};
 
#endif // MAINWINDOW_H
 

mainwindow.cpp
Код
C++ (Qt)
#include "mainwindow.h"
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QPushButton>
#include <QTimeLine>
 
MainWindow::MainWindow(QWidget *parent)
   : QMainWindow(parent)
{  
   this->setGeometry(200,200, 800, 600);
   graphicsView = new QGraphicsView(this);
   graphicsView->setGeometry(0,0,800,600);
   graphicsView->setRenderHint(QPainter::Antialiasing);
   scene = new QGraphicsScene(this);
   scene->setSceneRect(0,0,790,590);    
   graphicsView->setScene(scene);
   dialogAnimTimer = new QTimeLine();
   dialogAnimTimer->setDuration(200);
   dialogAnimTimer->setFrameRange(1, 20);
   connect(dialogAnimTimer, SIGNAL(frameChanged(int)), this , SLOT(TimerNextFrame()));
   fileDialog = new QFileDialog(this);
   fileDialog->hide();
   btnClose = new QPushButton(tr("&Quit"));
   btnShow = new QPushButton(tr("Show dialog"));
   connect(btnClose, SIGNAL(clicked()), this, SLOT(close()));
   connect(btnShow, SIGNAL(clicked()), this, SLOT(dialogAppear()));
   connect(fileDialog, SIGNAL(finished(int)), this, SLOT(dialogDisappear()));
   btnClose->move(700, 500);
   scene->addWidget(btnClose);
   scene->addWidget(btnShow);
   item = new QGraphicsProxyWidget();
   item = scene->addWidget(fileDialog);
}
 
MainWindow::~MainWindow()
{
 
}
 
void MainWindow::dialogAppear()
{
   dialogAnimTimer->setDirection(QTimeLine::Forward);
   dialogAnimTimer->start();
}
 
void MainWindow::dialogDisappear()
{
   dialogAnimTimer->setDirection(QTimeLine::Backward);
   dialogAnimTimer->start();
}
 
void MainWindow::TimerNextFrame()
{
   int framenum = dialogAnimTimer->currentFrame();
     if (dialogAnimTimer->direction() == QTimeLine::Forward)
     {
       transform.scale(1.05, 1.05);
       if (framenum == 1)
       {
         fileDialog->show();
       }
     }
     else
     {
       transform.scale(1/1.05, 1/1.05);
     }
   item->setTransform(transform);
  fileDialog->update();
}
 
Суть проблемы - после запуска программы FileDialog появляется только после второго нажатия btnShow (при том что событие DialogAppear вызывается два раза). После этого повторные нажатия btnShow открывают FileDialog сразу.


Название: Re: Странное поведение QTimeLine
Отправлено: kwisp от Октябрь 09, 2009, 14:16
dialogAnimTimer->setDuration(200);
вот эта строчка смущает немного
общая длительность получается 0,2с.
это правильно?


Название: Re: Странное поведение QTimeLine
Отправлено: lighting от Октябрь 09, 2009, 14:51
kwisp Да, правильно.


Название: Re: Странное поведение QTimeLine
Отправлено: Rcus от Октябрь 09, 2009, 15:25
Тонко, красиво :) сигнал frameChanged посылается только если текущий кадр изменился (внезапно да?) А поскольку при создании объекта время устанавливается в ноль то при первом запуске не произойдет смены кадра. Я бы не стал полагаться на это поведение, в данном случае больше подходит сигнал QTimeLine::stateChanged( QTimeLine::State newState );


Название: Re: Странное поведение QTimeLine
Отправлено: lighting от Октябрь 10, 2009, 10:33
Rcus получается при Direction = Forward и вызове start номер фрейма увеличивается, а время уменьшается и наоборот?
А вот stateChanged мне там ни к чему, frameCahged самое то. Добавил только строчку dialogAnimTimer->setCurrentTime(200); при создании таймлайна и все заработало как надо. Спасибо за подсказку, сам-бы я на это много времени убил :)