• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            zhonghua

            C++博客 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
              72 Posts :: 1 Stories :: 4 Comments :: 0 Trackbacks

            2015年2月2日 #

            在最近的web開發(fā)中是不是就會(huì)用到一些選擇器,發(fā)現(xiàn)很多尤其是CSS3新增的不太熟悉,在此總結(jié)一下。

            優(yōu)先級(jí)

            不同級(jí)別

            1. 在屬性后面使用 !important 會(huì)覆蓋頁(yè)面內(nèi)任何位置定義的元素樣式。

            2.作為style屬性寫在元素內(nèi)的樣式

            3.id選擇器

            4.類選擇器

            5.標(biāo)簽選擇器

            6.通配符選擇器

            7.瀏覽器自定義

            同一級(jí)別

            同一級(jí)別中后寫的會(huì)覆蓋先寫的樣式

             

            基礎(chǔ)選擇器

            選擇器含義
            *通用元素選擇器,匹配頁(yè)面任何元素(這也就決定了我們很少使用)
            #idid選擇器,匹配特定id的元素
            .class類選擇器,匹配class包含(不是等于)特定類的元素
            element標(biāo)簽選擇器

             

            復(fù)制代碼
            *         {             /*頁(yè)面所有元素都使用*/             border:0;         }          #test         {             /*id=test 的元素*/             background-color:#0e0;         }          .staus         {             /*含有類status的元素*/             border:0;         }          div         {             /*頁(yè)面所有div*/              background-color:#0e0;         }
            復(fù)制代碼

            組合選擇器

            選擇器含義
            E,F多元素選擇器,用”,分隔,同時(shí)匹配元素E或元素F
            E F后代選擇器,用空格分隔,匹配E元素所有的后代(不只是子元素、子元素向下遞歸)元素F
            E>F子元素選擇器,用”>”分隔,匹配E元素的所有直接子元素
            E+F直接相鄰選擇器,匹配E元素之后相鄰同級(jí)元素F
            E~F普通相鄰選擇器(弟弟選擇器),匹配E元素之后同級(jí)元素F(無(wú)論直接相鄰與否)
            .class1.class2這個(gè)姑且也算一個(gè)吧,沒什么名字,匹配類名中既包含class1又包含class2的元素

            我就不一一舉例子了,選擇器并不是只能寫兩層,發(fā)現(xiàn)有些小朋友有這種誤解,認(rèn)為只能寫E>F這樣的,我們寫可以寫E>F.class Element這樣,你要你搞得定優(yōu)先級(jí)

             

            屬性選擇器

             

            選擇器含義
            E[attr]匹配所有具有屬性attr的元素,div[id]就能取到所有有id屬性的div
            E[attr=value]匹配屬性attr值為value的元素,div[id=test],匹配id=test的div
            E[attr~=value]匹配所有屬性attr具有多個(gè)空格分隔、其中一個(gè)值等于value的元素
            E[attr|=value]匹配所有att屬性具有多個(gè)”-”分隔、其中一個(gè)值以value開頭的元素,主要用于lang屬性,比如“en”、“en-us”
            E[attr ^=value]匹配屬性attr的值以value開頭的元素
            E[attr $=value]匹配屬性attr的值以value結(jié)尾的元素
            E[attr *=value]匹配屬性attr的值包含value的元素

            偽類選擇器

             

            選擇器含義
            E:first-child匹配元素E的第一個(gè)子元素
            E:link匹配所有未被點(diǎn)擊的鏈接
            E:visited匹配所有已被點(diǎn)擊的鏈接
            E:active匹配鼠標(biāo)已經(jīng)其上按下、還沒有釋放的E元素
            E:hover匹配鼠標(biāo)懸停其上的E元素
            E:focus匹配獲得當(dāng)前焦點(diǎn)的E元素
            E:lang(c)匹配lang屬性等于c的E元素
            E:enabled匹配表單中可用的元素
            E:disabled匹配表單中禁用的元素
            E:checked匹配表單中被選中的radio或checkbox元素
            E::selection匹配用戶當(dāng)前選中的元素
            E:root匹配文檔的根元素,對(duì)于HTML文檔,就是HTML元素
            E:nth-child(n)匹配其父元素的第n個(gè)子元素,第一個(gè)編號(hào)為1
            E:nth-last-child(n)匹配其父元素的倒數(shù)第n個(gè)子元素,第一個(gè)編號(hào)為1
            E:nth-of-type(n)與:nth-child()作用類似,但是僅匹配使用同種標(biāo)簽的元素
            E:nth-last-of-type(n)與:nth-last-child() 作用類似,但是僅匹配使用同種標(biāo)簽的元素
            E:last-child匹配父元素的最后一個(gè)子元素,等同于:nth-last-child(1)
            E:first-of-type匹配父元素下使用同種標(biāo)簽的第一個(gè)子元素,等同于:nth-of-type(1)
            E:last-of-type匹配父元素下使用同種標(biāo)簽的最后一個(gè)子元素,等同于:nth-last-of-type(1)
            E:only-child匹配父元素下僅有的一個(gè)子元素,等同于:first-child:last-child或 :nth-child(1):nth-last-child(1)
            E:only-of-type匹配父元素下使用同種標(biāo)簽的唯一一個(gè)子元素,等同于:first-of-type:last-of-type或 :nth-of-type(1):nth-last-of-type(1)
            E:empty匹配一個(gè)不包含任何子元素的元素,文本節(jié)點(diǎn)也被看作子元素
            E:not(selector)匹配不符合當(dāng)前選擇器的任何元素

            偽元素選擇器

             

            選擇器含義
            E:first-line匹配E元素內(nèi)容的第一行
            E:first-letter匹配E元素內(nèi)容的第一個(gè)字母
            E:before在E元素之前插入生成的內(nèi)容
            E:after在E元素之后插入生成的內(nèi)容
            posted @ 2015-02-02 15:01 米米 閱讀(236) | 評(píng)論 (0)編輯 收藏

            2014年1月13日 #

                 摘要:       最近寫程序中需要將數(shù)據(jù)輸出保存到Excel文件中。翻看《C++ GUI Programming with Qt 4》(Second Edition)發(fā)現(xiàn)可以在Qt中運(yùn)用ActiveX控件,這真是太好了。        看了很久教程也沒有學(xué)會(huì),畢竟是新手,平時(shí)也沒學(xué)過ActiveX編程。一些在VB中可以方便使用的函數(shù)在...  閱讀全文
            posted @ 2014-01-13 17:23 米米 閱讀(2292) | 評(píng)論 (0)編輯 收藏

            2014年1月9日 #

            • 老有人問如何讓Qt的應(yīng)用程序自動(dòng)重啟,稍微寫一點(diǎn),也順便理理自己的思路 2011.10.26

            自動(dòng)重啟,也就是退出當(dāng)前進(jìn)程,啟動(dòng)一個(gè)新的進(jìn)程。于是,先看程序如何退出

            退出

            Qt程序的一般結(jié)構(gòu)如下:

            int main(int argc, char** argv) {     QApplication app(argc, argv);     Widget w;     w.show()     return app.exec(); }

            最后一句啟動(dòng)了主線程的事件循環(huán)。而要退出程序,就是要退出這個(gè)事件循環(huán),使main函數(shù)返回。

            如何退出?

            正確方式:

            • QCoreApplication::exit(int);

            它還有一個(gè)馬甲

            • QCoreApplication::quit();

            對(duì)于QApplication來(lái)說,它有一個(gè)常用的屬性

            quitOnLastWindowClosed

            所以,當(dāng)最后一個(gè)窗口關(guān)閉時(shí),它可以自動(dòng)調(diào)用前面的exit()

            而至于關(guān)閉窗口呢,我們還可以使用

            • QApplication::closeAllWindows()

            注:一般來(lái)說,對(duì)于多個(gè)窗口的程序,調(diào)用這個(gè)會(huì)比直接調(diào)用quit要好。因?yàn)檫@樣窗口可以接受到Close事件。

            啟動(dòng)外部程序

            在Qt中,做這個(gè)工作的非QProcess莫屬了,要啟動(dòng)當(dāng)前程序的另一個(gè)進(jìn)程,有要使二者沒有"父子"關(guān)系。恩

            QProcess::startDetached(qApp->applicationFilePath(), QStringList());

            可是,為什么不寫成下面這樣?

            QProcess::startDetached(qApp->applicationFilePath());

            當(dāng)然,如果路徑中不包含空格,這個(gè)也可以工作。

            重新啟動(dòng)1

            現(xiàn)在簡(jiǎn)單了,要重新啟動(dòng),只需要調(diào)用

            void XXX::onXXX() {     qApp->quit();     QProcess::startDetached(qApp->applicationFilePath(), QStringList()); }

            或者:

            void XXX::onXXX() {     qApp->closeAllWindow();     QProcess::startDetached(qApp->applicationFilePath(), QStringList()); }

            重新啟動(dòng)2

            盡管沒什么好處,但有時(shí)候,我似乎更喜歡這樣寫:

            void XXX::onXXX() {     qApp->exit(773) }

            然后main函數(shù)改成

            int main(int argc, char** argv) { ....     int ret = app.exec();     if (ret == 773) {         QProcess::startDetached(qApp->applicationFilePath(), QStringList());         return 0;     }     return ret; }

            這里面我用了一個(gè)魔數(shù):773,沒什么特別含義,只是因?yàn)槲矣X得

            773 = 'r'+'e'+'s'+'t'+'a'+'r'+'t'  ==>restart

            上班了,就寫到這兒...

            posted @ 2014-01-09 15:13 米米 閱讀(891) | 評(píng)論 (0)編輯 收藏

            2013年12月11日 #

                 摘要:         昨晚在一個(gè)郵件列表里面看見一個(gè)關(guān)于在線程種使用signal/slot的討論,由于回復(fù)太多,這里就不貼出原文了。        主要是關(guān)于怎樣從一個(gè)線程發(fā)送信號(hào)到另外一個(gè)線程的問題。其實(shí)這個(gè)也不是什么復(fù)雜的問題,在qt的asstant里面已經(jīng)描訴...  閱讀全文
            posted @ 2013-12-11 17:08 米米 閱讀(880) | 評(píng)論 (0)編輯 收藏

            2013年11月17日 #

             轉(zhuǎn)自:http://indure.chinaunix.com/space.php?uid=25520556&do=blog&id=2211406

                   主要使用QTableView和QTableWidget中的三個(gè)函數(shù)實(shí)現(xiàn)

            QTableView::verticalScrollBar()->setSliderPosition()  //設(shè)置當(dāng)前滑動(dòng)條的位置

            QTableView::verticalScrollBar()->maximum();             //滑動(dòng)條能移動(dòng)的最大位置

            QTableView::verticalScrollBar()->value();                   //獲得當(dāng)前滑動(dòng)條的位置

             

             

            1. static int nCurScroller=0; //翻頁(yè)時(shí)的當(dāng)時(shí)滑動(dòng)條位置
            2. static int pageValue = 10; // 一頁(yè)顯示條數(shù)

            3. void SplayHisForm::createHisForm()
            4. {
            5.                 …….
            6.     hisTableWidget = new QTableWidget;
            7.     hisTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
            8.     hisTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
            9.             …….
            10. }

            11. /***下一頁(yè)***/
            12. void SplayHisForm::nextPageHis()
            13. {
            14.     int maxValue = hisTableWidget->verticalScrollBar()->maximum(); // 當(dāng)前SCROLLER最大顯示值25
            15.     nCurScroller = hisTableWidget->verticalScrollBar()->value(); //獲得當(dāng)前scroller值

            16.     if(nCurScroller<maxValue)
            17.         hisTableWidget->verticalScrollBar()->setSliderPosition(pageValue+nCurScroller);
            18.     else
            19.         hisTableWidget->verticalScrollBar()->setSliderPosition(0);
            20. }

            21. /***上一頁(yè)***/
            22. void SplayHisForm::prePageHis()
            23. {
            24.     int maxValue = hisTableWidget->verticalScrollBar()->maximum(); // 當(dāng)前SCROLLER最大顯示值25
            25.     nCurScroller = hisTableWidget->verticalScrollBar()->value();

            26.     if(nCurScroller>0)
            27.         hisTableWidget->verticalScrollBar()->setSliderPosition(nCurScroller-pageValue);
            28.     else
            29.         hisTableWidget->verticalScrollBar()->setSliderPosition(maxValue);
            30. }

             QTableView和QTableWidget翻頁(yè)功能實(shí)現(xiàn)

            posted @ 2013-11-17 17:15 米米 閱讀(3159) | 評(píng)論 (0)編輯 收藏

            2013年9月12日 #

            vs生成的工程 用
            qmake -project 生成pro
            在pro里增加

            TRANSLATIONS += myapp.ts

            然后命令行輸入lupdate ***.pro
            打開.ts文件,一條一條的翻譯就是了
            最后lrelease ***.pro

            posted @ 2013-09-12 15:59 米米 閱讀(484) | 評(píng)論 (0)編輯 收藏

            2013年6月5日 #

            Qt4中的tooltip與win32中的tooltip有很多不一樣的地方,下面來(lái)總結(jié)一下。

            一是不能直在堆或棧中生成QToolTip對(duì)象。因?yàn)槠錁?gòu)造函數(shù)為私有。
            二是從widget獲取的tooltip不是tooltip對(duì)象,而是tooltip中的文本。
            三是tooltip跟本不是一個(gè)widget。所以不把它當(dāng)作widget用。
            四是tooltip類是一個(gè)靜態(tài)類,所以跟本不必生成tooltip對(duì)象就可以使用。
            五是tooltip類不能被定制,所以不能從它產(chǎn)生各種形狀的tooltip窗口。

            QtoolTip有兩種使用方式:
            一是靜態(tài)tooltip。比如為一個(gè)widget設(shè)置一個(gè)不變的tooltip文本,當(dāng)鼠標(biāo)移上去時(shí)顯示tooltip。此時(shí)很簡(jiǎn)單,只需調(diào)用widget的setToolTip()設(shè)置文本即可。
            二是動(dòng)態(tài)tooltip。也就是一個(gè)widget上的tooltip是變化的。此時(shí)需要重寫QWidget::event()函數(shù),在里面判斷事件類型,如果是QEvent::ToolTip,則控制顯示的文本的內(nèi)容,即可實(shí)現(xiàn)動(dòng)態(tài)tooltip。

            看如下代碼示例:

            1. bool SortingBox::event(QEvent *event)  
            2.  {  
            3.      if (event->type() == QEvent::ToolTip) {  
            4.          QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);  
            5.          int index = itemAt(helpEvent->pos());  
            6.          if (index != -1) {  
            7.              QToolTip::showText(helpEvent->globalPos(), shapeItems[index].toolTip());  
            8.          } else {  
            9.              QToolTip::hideText();  
            10.              event->ignore();  
            11.          }  
            12.   
            13.          return true;  
            14.      }  
            15.      return QWidget::event(event);  
            16.  }  
            可以看到,是調(diào)用 QtoolTip::showText()在某個(gè)位置顯示tooltip文本。

            那么,如果想隨時(shí)顯示tooltip,該怎么做呢?其實(shí)十分簡(jiǎn)單:直接調(diào)用QToolTip::showText(),指定要顯示的位置就行了。因?yàn)閠ooltip類的函數(shù)跟本就相當(dāng)于全局函數(shù)而已。

            呵呵,其實(shí)很簡(jiǎn)單,但從win32轉(zhuǎn)過來(lái)的人,覺得真別扭。
            posted @ 2013-06-05 16:41 米米 閱讀(1940) | 評(píng)論 (0)編輯 收藏

            QThread從QObject派生。它發(fā)出信號(hào)來(lái)表明線程開始了或結(jié)束了。并且也提供了幾個(gè)槽。

            更有趣的是,QObject可以在多個(gè)程中同時(shí)使用,可以發(fā)出信號(hào)給另外線程的槽,以及向“活在”另外線程中的對(duì)象郵寄事件。以上之所以能發(fā)生,是因?yàn)槊總€(gè)初程都被允許擁有它自己的事件循環(huán)。

            QObject 重入

            QObject 是可重入的。它大多數(shù)非界面派生類,比如QTimer,QTcpSocket,QFtp,和QProcess,也都是可重入的,使得在多個(gè)線程中同時(shí)使用 這些類成為可能。但是注意這些類被設(shè)計(jì)為在一個(gè)線程中創(chuàng)建和使用;在一個(gè)線程中創(chuàng)建一個(gè)對(duì)象然后在另一個(gè)線程中調(diào)用它的方法是不能保證一定能工作的。有三 個(gè)限制條件要注意:
            QObject的兒子必須在創(chuàng)建它爹的線程中創(chuàng)建。這表示,你永遠(yuǎn)不能將QThread對(duì)象(this)作為parent傳給在此thread創(chuàng)建的對(duì)象,因?yàn)榫€程對(duì)象自己就是在另一個(gè)線程中創(chuàng)建的。
            事件驅(qū)動(dòng)的對(duì)象應(yīng)該只用于一個(gè)線程中。這一條尤其應(yīng)用于定時(shí)器和網(wǎng)絡(luò)模塊。比如,你不能在創(chuàng)建對(duì)象之外的線程中啟動(dòng)一個(gè)定時(shí)器或連接一個(gè)socket。
            你必須保證在線程中創(chuàng)建的一切對(duì)象在QThread被刪除之前被刪除。這可以通過在你的run()實(shí)現(xiàn)中在棧中創(chuàng)建對(duì)象來(lái)輕松搞定。

            盡管QObject是可重入的,但GUI類,尤其是QWidget和它所有的派生類們,都不是可重入的。它們只能在主線程中使用。QCoreApplication::exec()必須在這個(gè)線程中調(diào)用。

            在實(shí)際應(yīng)用中,最好的方式是把耗時(shí)的計(jì)算放到主線程中外進(jìn)行,完成后通知主線程顯示結(jié)果。

            Pre-Thread Event循環(huán)

            每 個(gè)線程都可以有它自己的事件循環(huán)。初始的線程使用QCoreApplication::exec()來(lái)開始它的事件循環(huán);其它的線程可以使用 QThread::exec()來(lái)啟動(dòng)循環(huán)。就像QCoreApplication,QThread也提供了一個(gè)exit(int)方法和一個(gè) quit()槽。

            線程中的事件循環(huán)使得在線程中使用依靠消息循環(huán)的非GUI的QT類成為可能(比如QTimer,QTcpSocket,QProcess)。它也使得從任何線程連接信號(hào)到一個(gè)線程的槽成為可能。這在下面的“信號(hào)和槽穿越線程”一節(jié)中有詳細(xì)解釋。

            一個(gè)QObject實(shí)例在那個(gè)線程中創(chuàng)建,就叫做“活”在那個(gè)線程中。給這個(gè)對(duì)象的事件們通過線程的事件循環(huán)派發(fā)。一個(gè)QObject對(duì)象所“活在”的線程通過QObject::thread()可以取得。

            注 意在QApplication之前創(chuàng)建的QObject調(diào)用QObject::thread()會(huì)返回0.這意味著主線程將只為這些對(duì)象處理郵寄的事件; 對(duì)于沒有線程的對(duì)象,其它的事件處理跟本不會(huì)發(fā)生。使用QObject::moveToThread()方法來(lái)改變對(duì)象(和它兒子們)的線程(如果一個(gè)對(duì) 象有爹,它就不能被移動(dòng)到另外線程)。

            在擁有對(duì)象之外的線程中調(diào)用刪除對(duì)象是不安全的,除非你能保證在被刪除時(shí)不在處理事件。但可以使用 QObject::deleteLater(),它會(huì)寄出DeferedDelete事件,對(duì)象的線程的事件循環(huán)最終會(huì)抓住它。默認(rèn)下,擁有 Qobject的線程就是創(chuàng)建QObject的線程,但在QObject::moveToTread()之后就變了。

            如果沒有事件循環(huán),事件將不能傳給對(duì)象。比如,如果你在一個(gè)線程中創(chuàng)建一個(gè)QTimer對(duì)象,但是沒有再調(diào)用exec(),那么QTimer將永不能觸發(fā)timeout()信號(hào)。deleteLater()也不再能工作。(這些也同樣適用于主線程。)

            你可以在任何線程中使用QCoreApp:postEvent()手動(dòng)向任何對(duì)象郵寄事件。事件將被對(duì)象所在線程的事件循環(huán)自動(dòng)派發(fā)。

            事 件過濾器被所有的線程所支持,但有個(gè)限制條件:監(jiān)視對(duì)象必須與被監(jiān)視對(duì)象位于同一個(gè)線程中。同樣 的,QCoreApplication::sendEvent()(不同于 QCoreApplication::postEvent())只能在同一線程中的對(duì)象之間發(fā)送事件。

            從另外線程訪問QObject子類


            QObject和它所有的子類都不是線程安全的,這也包含整個(gè)事件派送系統(tǒng)。要記住,當(dāng)你從另外線程訪問對(duì)象時(shí),事件循環(huán)可能派送事件到你的QObject子類。

            如果你調(diào)用一個(gè)非本線程的QObject的子類的函數(shù)并且這個(gè)對(duì)象可能接收事件,你必須用mutex保護(hù)所有對(duì)你的QObject子類的內(nèi)部數(shù)據(jù)的訪問;否則,你可能體驗(yàn)的什么叫崩潰。

            就像其它對(duì)象,QThread對(duì)象“活”在創(chuàng)建它的線程中,而不是它自己所代表的線程中。通常在你的QThread子類中提供槽是不安全的,除非你用mutex保護(hù)成員變量。

            另一方面,你可以從你的QThread tun()中安全的發(fā)出信號(hào),因?yàn)樾盘?hào)發(fā)射是線程安全的。


            穿越線程的信號(hào)和槽們


            Qt支持如下信號(hào)-槽連接類型:
             自動(dòng)連接(默認(rèn))- 如果信號(hào)是從接收對(duì)象所在的線程發(fā)出的,其行為與“直接連接”相同。否則,其行為與“隊(duì)列連接”相同。
             直接連接- 當(dāng)信號(hào)發(fā)出,槽會(huì)被立馬調(diào)用。此槽在發(fā)出者的線程中執(zhí)行,而不一定是接收者所在的線程。
             隊(duì)列連接- 當(dāng)控制返回到接收者所在線程的事件循環(huán)時(shí)調(diào)用。槽在接收者的線程中執(zhí)行。
             阻塞的隊(duì)列連接- 槽像“隊(duì)列連接”那樣被調(diào)用,除了一點(diǎn):當(dāng)前線程會(huì)阻塞住直到槽返回。注:在同一線程中使用此類型的連接將導(dǎo)致死鎖!
             唯一連接- 行為與“自動(dòng)連接”相同,但連接必須在無(wú)復(fù)制品時(shí)才能建立。也就是,如果在相同的兩個(gè)對(duì)象之間已經(jīng)建立了同一個(gè)信號(hào)到同一個(gè)槽的連接,那么連接就不能建立,connect()返回false。

            連接類型可以通過給connect()傳遞一個(gè)額外的參數(shù)來(lái)指定。注意當(dāng)接收者和發(fā)送者位于不同的線程中時(shí),使用“直接連接”,如果事件循環(huán)是運(yùn)行于接收者的線程中,此時(shí)是不安全的,同理調(diào)用位于另外線程的對(duì)象的任何函數(shù)都是不安全的。

            QObject::connect()本身是線程安全的。
            posted @ 2013-06-05 16:40 米米 閱讀(1210) | 評(píng)論 (0)編輯 收藏

            將動(dòng)畫們弄到一起


            一個(gè)應(yīng)用通常將包含不止一個(gè)動(dòng)畫。例如,你可能想同時(shí)移動(dòng)多個(gè)圖形item也可能順序的一個(gè)接一個(gè)的移動(dòng)。
            QanimationGroup 的子類們(QSequentialAnimationGroup和QParallelAnimationGroup)是其它動(dòng)畫的容器,所以這些動(dòng)畫既可 以并行也可以串行。QAnimationGroup是一個(gè)非屬性動(dòng)畫的例子,但是它定期的收到時(shí)間改變的通知。這使得它可以把時(shí)間改變傳輸給所包含的動(dòng)畫 們,從而控制何時(shí)播放那些動(dòng)畫們。

            讓我們看一下使用QSequentialAnimatoinGroup和QParallelAnimationGroup的代碼示例。
            QPushButton *bonnie = new QPushButton("Bonnie");
            bonnie->show();
            QPushButton *clyde = new QPushButton("Clyde");
            clyde->show();
            QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
            // Set up anim1
            QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");
            // Set up anim2
            QParallelAnimationGroup *group = new QParallelAnimationGroup;
            group->addAnimation(anim1);
            group->addAnimation(anim2);
            group->start();
            一個(gè)并行g(shù)roup在同一時(shí)刻播放多個(gè)動(dòng)畫。對(duì)start()的調(diào)用將啟動(dòng)它所統(tǒng)治的所有的動(dòng)畫。

            QPushButton button("Animated Button");
            button.show();
            QPropertyAnimation anim1(&button, "geometry");
            anim1.setDuration(3000);
            anim1.setStartValue(QRect(0, 0, 100, 30));
            anim1.setEndValue(QRect(500, 500, 100, 30));
            QPropertyAnimation anim2(&button, "geometry");
            anim2.setDuration(3000);
            anim2.setStartValue(QRect(500, 500, 100, 30));
            anim2.setEndValue(QRect(1000, 500, 100, 30));
            QSequentialAnimationGroup group;
            group.addAnimation(&anim1);
            group.addAnimation(&anim2);
            group.start();
            QsequentialAnimationGroup順序的播放它的動(dòng)畫們。它在上一個(gè)完成時(shí)按順序播放下一個(gè)。

            既然一個(gè)動(dòng)畫組本就是一個(gè)動(dòng)畫類,你可以把它添加到其它組中。如此,你可以建立起一個(gè)動(dòng)畫樹。


            動(dòng)畫和狀態(tài)
            當(dāng) 使用狀態(tài)機(jī),我們可以使用一個(gè)QSignalTransition或QEventTransition類在狀態(tài)轉(zhuǎn)換時(shí)連接一個(gè)或多個(gè)動(dòng)畫。這些類都是從 QAbstractTransition派生的,它們定義了簡(jiǎn)易的函數(shù)addAnimation(),使得能夠添加一個(gè)或多個(gè)動(dòng)畫,在狀態(tài)轉(zhuǎn)換時(shí)啟動(dòng)這些 動(dòng)畫。

            我們還可能連接屬性與狀態(tài),而不是手動(dòng)設(shè)置開始與結(jié)束值。下面是完整的代碼,演示了動(dòng)畫一個(gè)QPushButton的geometry屬性。

            QPushButton *button = new QPushButton("Animated Button");
            button->show();
            QStateMachine *machine = new QStateMachine;
            QState *state1 = new QState(machine);
            state1->assignProperty(button, "geometry", QRect(0, 0, 100, 30));
            machine->setInitialState(state1);
            QState *state2 = new QState(machine);
            state2->assignProperty(button, "geometry", QRect(250, 250, 100, 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();
            posted @ 2013-06-05 16:40 米米 閱讀(878) | 評(píng)論 (0)編輯 收藏

            概述

            Qt動(dòng)畫架構(gòu)中的主要類如下圖所示:



            動(dòng)畫框架由基類QAbstractAnimation和它的兩個(gè)兒子QVariantAnimationQAnimationGroup組成。QAbstractAnimation是所有動(dòng)畫類的祖宗。它包含了所有動(dòng)畫的基本屬性。比如開始,停止和暫停一個(gè)動(dòng)畫的能力。它也可以接收時(shí)間改變通知。


            動(dòng)畫框架又進(jìn)一步提供了QProertyAnimation類。它繼承自QVariantAnimation并對(duì)某個(gè)Qt屬性(它須是Qt的”元數(shù)據(jù)對(duì)象系統(tǒng)”的一部分,見http://blog.csdn.net/nkmnkm/article/details/8225089)執(zhí)行動(dòng)畫。此類對(duì)屬性執(zhí)行一個(gè)寬松曲線插值。所以當(dāng)你想去動(dòng)畫一個(gè)值時(shí),你可以把它聲明為一個(gè)屬性,并且讓你的類成為一個(gè)QObject。這給予我們極大的自由度來(lái)動(dòng)畫那些已存在的widget和其它QObject


            復(fù)雜的動(dòng)畫可以通過建立一個(gè)QAbstractAnimation的樹來(lái)構(gòu)建。這個(gè)樹通過使用QAnimationGroups來(lái)創(chuàng)建,QAnimationGroups作為其它動(dòng)畫的容器。注意動(dòng)畫組也是從QAbstractAnimation派生的,所以動(dòng)畫組可以再包含其它動(dòng)畫組。


            動(dòng)畫框架可以單獨(dú)使用,同時(shí)也被設(shè)計(jì)為狀態(tài)機(jī)框架的一部分。狀態(tài)機(jī)提供了一個(gè)特定的狀態(tài)可以用來(lái)播放動(dòng)畫。在進(jìn)入或退出某個(gè)狀態(tài)時(shí)QState也可以設(shè)置屬性們,并且這個(gè)特定的動(dòng)畫狀態(tài)將在指定QPropertyAnimation時(shí)給予的值之間做插值運(yùn)算。后面我們要進(jìn)一步介紹此問題。


            在場(chǎng)景的背后,動(dòng)畫被一個(gè)全局定時(shí)器收集,這個(gè)定時(shí)器發(fā)送update到所有的正在播放的動(dòng)畫中。

            動(dòng)畫框架中的類們

            QAbstractAnimation

            所有動(dòng)畫類的基類

            QAnimationGroup

            動(dòng)畫組的基類

            QEasingCurve

            控制動(dòng)畫的寬松曲線類

            QParallelAnimationGroup

            并行動(dòng)畫組類

            QPauseAnimation

            串行動(dòng)畫組類的暫停類

            QPropertyAnimation

            動(dòng)畫Qt屬性的類

            QSequentialAnimationGroup

            串行動(dòng)畫組類

            QTimeLine

            控制動(dòng)畫的時(shí)間線類

            QVariantAnimation

            各動(dòng)畫類的虛基類


            動(dòng)畫Qt屬性們

            如前面所講,QPropertyAnimation類可以修改Qt屬性們。要?jiǎng)赢嬕粋€(gè)值,就需要使用此類。實(shí)際上,它的父類,QVariantAnimation,是一個(gè)虛擬類,不能被直接使用。


            我們選擇動(dòng)畫Qt屬性的一個(gè)主要理由是Qt屬性為我們提供了自己動(dòng)畫已存在的類的自由度。尤其是QWidget類(我們也可以把它嵌入到一個(gè)QGraphicsView中)具有很多屬性表示其bounds,colors等等。讓我們看一個(gè)小例子:

            1. QPushButton button("Animated Button");  
            2. button.show();  
            3. QPropertyAnimation animation(&button, "geometry");  
            4. animation.setDuration(10000);  
            5. animation.setStartValue(QRect(0, 0, 100, 30));  
            6. animation.setEndValue(QRect(250, 250, 100, 30));  
            7. animation.start();  

            這段代碼將把按鈕在10秒種內(nèi)從屏幕的左上角移動(dòng)到(250,250)處。

            上面的例子舉在開始值和結(jié)束值之間做線性插值。還可以在開始和結(jié)束值之間設(shè)置值,插值運(yùn)算就會(huì)經(jīng)過這些點(diǎn)。


            1. QPushButton button("Animated Button");  
            2. button.show();  
            3. QPropertyAnimation animation(&button, "geometry");  
            4. animation.setDuration(10000);  
            5. animation.setKeyValueAt(0, QRect(0, 0, 100, 30));  
            6. animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));  
            7. animation.setKeyValueAt(1, QRect(0, 0, 100, 30));  
            8. animation.start();  

            在此例中,動(dòng)畫將按鈕在8秒中內(nèi)弄到(250,250)處,然后在2秒種內(nèi)又弄回原位。移位是在這些點(diǎn)中間以線性插值進(jìn)行的。


            你 也有可能動(dòng)畫一個(gè)QObject的值,雖然這些值并沒有被聲明為Qt屬性。唯一的要求就是這個(gè)值具有一個(gè)setter。之后你可以從這個(gè)類派生子類從而包 含這些值并且聲明一個(gè)使用這個(gè)setter的屬性。注意每個(gè)Qt屬性都需要有一個(gè)getter,所以你需要提供一個(gè)getter,如果它不存在的話。

            1. class MyGraphicsRectItem : public QObject, public QGraphicsRectItem  
            2. {  
            3.     Q_OBJECT  
            4.     Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry)  
            5. };  

            在上例中,我們派生了QGraphicsRectItem并定義了一個(gè)geometry屬性。我們現(xiàn)在可以動(dòng)畫這個(gè)widget的geometry了,即使QGraphicsRectItem沒有提供geometry屬性。

            動(dòng)畫和圖形視圖框架

            當(dāng)你想動(dòng)畫QGraphicsItems,你也要用QPropertyAnimation。然而,QGraphicsItem不是從QObject派生的。一個(gè)好的解決方案是派生要?jiǎng)赢嫷膱D形item。派生類也要從QObject派生。這樣,QPropertyAnimation就可以被用于QGraphicsItems了。

            1. class Pixmap : public QObject, public QGraphicsPixmapItem  
            2. {  
            3.     Q_OBJECT  
            4.     Q_PROPERTY(QPointF pos READ pos WRITE setPos)  
            5.     ...  

            就如上一節(jié)中所講的,我們需要定義希望去動(dòng)畫的屬性。

            注意:QObject必須是繼承中的第一個(gè),因?yàn)樵獢?shù)據(jù)對(duì)象系統(tǒng)需要這樣做。

            寬松曲線

            QPropertyAnimation在屬性的開始值和結(jié)束值之間執(zhí)行一個(gè)插值運(yùn)算。除了向動(dòng)畫添加更多的關(guān)鍵值外,你還可以使用一個(gè)寬松曲線。寬松曲線描述了一個(gè)在01之間插值的速度變化的函數(shù),如果你想控制一個(gè)動(dòng)畫的速度而不改變插值的路徑時(shí),就非常有用。


            1. QPushButton button("Animated Button");  
            2. button.show();  
            3. QPropertyAnimation animation(&button, "geometry");  
            4. animation.setDuration(3000);  
            5. animation.setStartValue(QRect(0, 0, 100, 30));  
            6. animation.setEndValue(QRect(250, 250, 100, 30));  
            7. animation.setEasingCurve(QEasingCurve::OutBounce);  
            8. animation.start();  

            這里,動(dòng)畫將按照一個(gè)曲線進(jìn)行,這個(gè)曲線使得動(dòng)畫像一個(gè)跳動(dòng)的皮球從開始位置跳到結(jié)束位置。QEasingCurve具有一個(gè)大曲線集合,你可以從里面選擇一個(gè)。它們被定義為QEasingCurve::Type枚舉。如果你需要不一樣的曲線,你也可以自己實(shí)現(xiàn)一個(gè),然后注冊(cè)到QEasingCurve

            posted @ 2013-06-05 16:39 米米 閱讀(828) | 評(píng)論 (0)編輯 收藏

            僅列出標(biāo)題  下一頁(yè)
            久久精品国产色蜜蜜麻豆| 久久青青草原精品影院| 国产视频久久| 久久青青草原综合伊人| 国产亚洲精久久久久久无码| 狠狠色丁香婷婷久久综合| 久久久久人妻精品一区三寸蜜桃| 99国产欧美精品久久久蜜芽 | 久久久久亚洲AV综合波多野结衣| 国产亚洲精品美女久久久| 久久久久国产精品熟女影院| 伊人久久综合无码成人网| 2020久久精品亚洲热综合一本| 久久午夜免费视频| 久久久国产视频| 久久久亚洲欧洲日产国码是AV | 久久久国产乱子伦精品作者| 欧美午夜精品久久久久免费视| 人妻少妇久久中文字幕| 久久久久久亚洲Av无码精品专口| 欧美丰满熟妇BBB久久久| 久久精品国产清高在天天线| 久久se精品一区精品二区| 久久99精品国产麻豆宅宅| 国产精品激情综合久久| 精品熟女少妇aⅴ免费久久| 久久天天躁狠狠躁夜夜2020| 亚洲午夜精品久久久久久浪潮| 97香蕉久久夜色精品国产| 欧洲成人午夜精品无码区久久| 国产精品美女久久久| 91精品国产91热久久久久福利| 久久免费视频6| 成人久久免费网站| 国产成人久久精品一区二区三区 | 久久综合亚洲欧美成人| 国产精品无码久久综合| 国产69精品久久久久99尤物| 久久久久人妻精品一区三寸蜜桃| 久久精品成人欧美大片| 久久99精品久久久久子伦|