QPushButton *button = new QPushButton(「Animated Button」);
QState *state1 = new QState(machine);
state1->assignProperty(button, 「geometry」, QRect(0, 0, 150, 30));
QState *state2 = new QState(machine);
state2->assignProperty(button, 「geometry」, QRect(250, 250, 150, 30));php
#include <QApplication>
#include <QPushButton>
#include <QStateMachine>
#include <QState>
#include <QSignalTransition>
#include <QPropertyAnimation>
int main(int argc,char *argv[]){
QApplication app(argc,argv);
QPushButton *button = new QPushButton(「Animated Button」);
button->show();
QStateMachine *machine = new QStateMachine;
//QState *state1 = new QState(machine->rootState());
QState *state1 = new QState(machine);
state1->assignProperty(button, 「geometry」, QRect(0, 0, 150, 30));
machine->setInitialState(state1);
//QState *state2 = new QState(machine->rootState());
QState *state2 = new QState(machine);
state2->assignProperty(button, 「geometry」, QRect(250, 250, 150, 30));
QSignalTransition *transition1 = state1->addTransition(button,
SIGNAL(clicked()), state2);
transition1->addAnimation(new QPropertyAnimation(button, 「geometry」));
QSignalTransition *transition2 = state2->addTransition(button,
SIGNAL(clicked()), state1);
transition2->addAnimation(new QPropertyAnimation(button, 「geometry」));
machine->start();
app.exec();
}html//這個代碼來自於Qt-4.6 Assistant幫助的Animation索引,原代碼的rootState()函數是沒有的,應該算是bug了吧:)git
上邊介紹了怎麼使用Qt-4.6的動畫類來實現位置的自動變化,有時候還會一些自定義屬性變化需求,好比顏色的變化,以及某些非數值直接相關的屬性,這時候能夠用自定義的變量來靈活控制。下面我實現了一個很是簡單的例子用於讓Label上的文字自動作顏色變化,不過樣子很醜 ,主要是演示功能windows
前文sanfanling提到QTextBrowser中選中文字的變色能夠用相似方法來操做,不過我以爲更簡便的方法是用timerEvent,呵呵(八卦一下,不知此sanfanling是否就是雲帆論壇的KDE名人三翻領?)//這一部分代碼主要是利用繼承給QLabel增長了一個顏色屬性
app
#include <QApplication>
#include <QLabel>
#include <QPropertyAnimation>
class Label:public QLabel{
Q_OBJECT
Q_PROPERTY(int color READ color WRITE setColor)
public:
Label(const QString&text,QLabel *p=0):QLabel(text,p){icolor=0;};
inline const int& color() const{return icolor;};
void setColor(const int& );
private:
int icolor;
};框架
void Label::setColor(const int &rcolor) {
QPalette pal;
pal.setColor(QPalette::Foreground, rcolor);
setPalette(pal);
if(rcolor!=icolor){
icolor=rcolor;
//4 lines get 「text」
QString color_str=QString("%1").arg(icolor,2,16);
color_str+=QString("00")+color_str;
QString str=QString("");
str+=QString("http://www.cuteqt.com/blog")+QString(">") + color_str;
setText(str);
}
repaint();
}函數
//標準的QPropertyAnimation動畫接口,利用屬性color進行自動變化
int main(int argc,char *argv[]){
QApplication app(argc,argv);
Label label("hello,www.cuteqt.com/blog");oop
QPropertyAnimation *anim=new QPropertyAnimation(&label, "color");
anim->setDuration(1800);
anim->setStartValue(16);
anim->setEndValue(0xffffff);
anim->start();佈局
label.show();
return app.exec();
}動畫
#include "main.moc"
]]> http://www.cuteqt.com/blog/?feed=rss2&p=1146 3 http://www.cuteqt.com/blog/?p=1142 http://www.cuteqt.com/blog/?p=1142#comments Sat, 05 Dec 2009 11:20:40
+0000 臭蟲 http://www.cuteqt.com/blog/?p=1142 Qt-4.6新增了Animation Framework(動畫框架),讓咱們可以方便的寫一些生動的程序。沒必要像之前的版本同樣,全部的控件都枯燥的呆在偉大光榮的QLayout裏,也許它們能夠唱個歌,跳個舞。
前面寫過一篇文章Qt動畫效果的幕後英雄:QTimeLine,介紹了怎麼利用QTimeLine寫一動畫程序。今天又再重申前文裏的一句話,所謂動畫就是在一個時間段內的不一樣時間點有不一樣的狀態,只要定義好這樣狀態,實現動畫就是水到渠成的事情。固然作這件事情,最好用的就是狀態機,沒錯Qt-4.6.0提供了QStateMachine類,不過今天我要講的三字決要簡單一些。
QPropertyAnimation用於和QObject中的屬性properties進行通訊,好比QWidget的大小,座標等。來看代碼
QPropertyAnimation *animation = new QPropertyAnimation(myWidget, 「geometry」);
animation->setDuration(10000);
animation->setStartValue(QRect(0, 0, 100, 30));
animation->setEndValue(QRect(250, 250, 100, 30));
animation->start();
第一行建立的QPropertyAnimation對象關聯了myWidget這個窗體的幾何屬性。後面的幾句分別設置了這個動畫的時長,起始座標和結束座標。剩下的事情就交改QProperAnimation去作就好了。而後調用start()啓動它。沒錯,五行代碼就完成了一個完成了一個自動從一個座標點移動到另外一個座標點的窗體。下面我給出一個能夠運行的代碼,是一隻小鳥從下角移到中間的一個小動畫,固然你得本身準備這個同名的圖片:)
#include <QApplication>
#include <QLabel>
#include <QPixmap>
#include <QPropertyAnimation>int main(int argc,char *argv[]){
QApplication app(argc,argv);
QWidget *w=new QWidget();
w->resize(300,400);QPixmap birdimg=QPixmap(「twitter-bird.png」).scaled(40,40);
QLabel *bird_1=new QLabel(w);
bird_1->setPixmap(birdimg);QPropertyAnimation *anim1=new QPropertyAnimation(bird_1, 「pos」);
anim1->setDuration(2000);
anim1->setStartValue(QPoint(0, 360));
anim1->setEndValue(QPoint(110, 180));
anim1->start();
bird_1->move(-40,-40);
w->show();
return app.exec();
}
上面的例子使用了label的位置屬性pos。固然你能夠在本身的類裏增長其它property的,好比讓顏色在變。
上面那個例子中小鳥的移動是線性的,未免太單調了點。QPropertyAnimation中的void setEasingCurve (const QEasingCurve & easing)函數正是用於實現不一樣的曲率變化的,QEasingCurve可用的參數列表(包括函數曲線圖)可在文檔中查到 。將上面動畫相關的代碼部分改爲
QPropertyAnimation *anim1=new QPropertyAnimation(bird_1, 「pos」);
anim1->setDuration(2000);
anim1->setStartValue(QPoint(0, 360));
anim1->setEndValue(QPoint(110, 180));
anim1->setEasingCurve(QEasingCurve::OutBounce);
anim1->start();
注意,新增的第四句。而且試試其它曲線參數,而後運行,看到的動態效果是否是不同了。若是你對列表裏已經有的曲線都不滿意,你還能夠繼承QEasingCurve,實現你須要的效果。
前面的例子是隻有一個動畫在運行,若是想多個動畫一塊兒運行的話,那就要用到動畫組QAnimationGroup了。動畫組分爲兩種分別爲串行和並行,對應於QAnimationGroup的兩個子類QSequentialAnimationGroup和QParallelAnimationGroup。其用法很簡單
QSequentialAnimationGroup group;
//QParallelAnimationGroup group;
group.addAnimation(anim1);
group.addAnimation(anim2);
group.start();
上面的代碼,若是是串行的話,那麼動畫anim1運行以後,纔會運行anim2。若是是並行的話,兩個動畫是同時運行的。若是加了動畫組,那麼單個anim1->start()就不必再單獨調用了,由動畫組來管理。 下面是一個可運行的代碼,兩隻小鳥分別從窗體左上角和右下角移動到中間。
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QPixmap>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>
#include <QParallelAnimationGroup>int main(int argc,char *argv[]){
QApplication app(argc,argv);
QWidget *w=new QWidget();
w->resize(300,400);QPixmap birdimg=QPixmap(「twitter-bird.png」).scaled(40,40);
QLabel *bird_1=new QLabel(w);
bird_1->setPixmap(birdimg);QPropertyAnimation *anim1=new QPropertyAnimation(bird_1, 「pos」);
anim1->setDuration(2000);
anim1->setStartValue(QPoint(0, 360));
anim1->setEndValue(QPoint(110, 180));
//anim1->setEasingCurve(QEasingCurve::OutBounce);
//anim1->start();QLabel *bird_2=new QLabel(w);
bird_2->setPixmap(birdimg);QPropertyAnimation *anim2=new QPropertyAnimation(bird_2, 「pos」);
anim2->setDuration(2000);
anim2->setStartValue(QPoint(0, 0));
anim2->setEndValue(QPoint(150, 180));
anim2->setEasingCurve(QEasingCurve::OutBounce);QSequentialAnimationGroup group;
//QParallelAnimationGroup group;
group.addAnimation(anim1);
group.addAnimation(anim2);
group.start();bird_1->move(-40,-40);
bird_2->move(-40,-40);
w->show();
return app.exec();
}
其實動畫的本質就是在每必定時間間隔內顯示一幀圖像,當這個間隔較短的時候人眼就感受不出來了,以爲看到的是連續的影像。Qt爲開發動畫效果的人員提供了一個很好的時間控制類QTimeLine.
QTimeLine的最簡單用法是
1 QTimeLine timeline=new QTimeLine(1000);
2 timeLine->setFrameRange(0, 100);
3 connect(timeline,SIGNAL(frameChanged(int)),yourobj,SLOT(yourobjslot(int)));
4 timeline->start();
解釋:
1. 建立的時間線持續時長,參數值是毫秒數,1000就是1秒
2. 在這段時間線內,建立的輸出值範圍。也就是第三行中frameChanged信號裏傳出的參數值範圍
3. QTimeLine的默認時間間隔是40ms(也就是1秒25幀),每一個間隔會發出一個frameChanged()的信號,此處將該信號鏈接到你能控制動畫效果的對象和槽上。
4. 啓動timeline後,每一個時間間隔的frameChanged()信號才能正常發出。
固然還有一些複雜的參數設置能夠更好的控制你的效果。
setLoopCount(int count)該函數控制了動畫的重複次數。默認是1,若是設置成0則表示無限循環。
setUpdateInterval(int interval)該函數用於控制更新動畫的時間間隔。
在QTimeLine所設置的持續時長過去後,相應的會發出一個finished()的信號,你能夠在接收到這個信號之後作一些掃尾的工做。
另外還有一個別致的選項:
setCurveShape (CurveShape shape),該選項用於控制間隔輸出數值的一個變化規律。CurveShage現有的選項是
QTimeLine::EaseInCurve 0 The value starts growing slowly, then increases in speed.
QTimeLine::EaseOutCurve 1 The value starts growing steadily, then ends slowly.
QTimeLine::EaseInOutCurve 2 The value starts growing slowly, then runs steadily, then grows slowly again.
QTimeLine::LinearCurve 3 The value grows linearly (e.g., if the duration is 1000 ms, the value at time 500 ms is 0.5).
QTimeLine::SineCurve 4 The value grows sinusoidally.
QTimeLine::CosineCurve 5 The value grows cosinusoidally.
很少加解釋了,2是默認值。由於即便沒有這個選項,若是隻輸出均勻數(選項3),咱們仍是能夠本身對數據進行二次加工,生成咱們想要的任意規律的數字。
利用QTimeLine咱們很容易實現一些圖像消隱的效果,只須要你在每一個間隔結束後顯示圖像消隱過程當中不一樣階段的一個定格便可。這裏就有一個很好的例子,短短300餘行,想必用不了你多長時間便可讀通
http://qt.gitorious.org/qt-labs/graphics-dojo/trees/master/genie
咱們www.cuteqt.com/blog也奉獻一個,互相交流:)
]]> http://www.cuteqt.com/blog/?feed=rss2&p=509 5 http://www.cuteqt.com/blog/?p=276 http://www.cuteqt.com/blog/?p=276#comments Mon, 01 Jun 2009 02:12:51
+0000 shiroki http://www.cuteqt.com/blog/?p=276 看到qtcn上有人在問怎麼能動態的變換顯示的圖片(http://www.qtcn.org/bbs/read.php?tid=18835), 其實這是很容易實現的。 基本的是使用QTimer系列的類來控制時間, 另外從Qt4開始全部的繪製工做應該都放在窗體子類的paintEvent函數裏調用, 因此通常狀況下你須要把想定製繪圖的類派生一下, 重寫paintEvent虛函數,
把drawPixmap之類的函數放在這裏調用。 筆者的例子一方面是有點取巧, 另外一方面也爲了和問的問題一致, 沒有去派生子類, 而是用了個QLabel來顯示圖片, 各位看官在看代碼的時候要注意了。
下面就簡單的介紹一下程序的實現, 很是簡單, 三言兩語就清楚了。
程序的主窗體採用了QFrame, 其實隨便一個類均可以, 好比QWidget也同樣。
在主窗體中放了一個layout用來控制內部控件的佈局, Label控件和Pushbutton都放在此佈局中。 爲了顯示圖片方便, 給Label設置了一個固定大小。
構造函數就是建立佈局、子控件和定時器, 並鏈接信號和槽函數。
主類裏定義了兩個槽函數, 一個用來響應定時器並變換圖片, 另外一個用來響應用戶點擊按鈕並啓動或中止定時器。
代碼看看附件就行了, 有任何不清楚可在本站bbs留言。
例子的打包格式是tar.gz, 因爲blog上載的限制, 後綴名被篡改了, 你們下載以後本身改回去一下。 另外由於windows下的qt默認會給debug和release版本建立不一樣的目錄存放binary, 因此代碼裏用的相對路徑在windows下可能會找不到圖片, 你們拿回去改改mainwin.cpp, 或者把圖片放在程序啓動的目錄裏。 如從debug目錄運行,就要把圖片放在debug目錄中,或者若以debug\ani.exe這樣運行的話,圖片就要放在debug上級目錄。
這樣應該就能夠顯示圖片了。 Windows就是這麼麻煩!
例子程序下載: picanimation.tar.gz
]]> http://www.cuteqt.com/blog/?feed=rss2&p=276 5