• <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開(kāi)發(fā)中是不是就會(huì)用到一些選擇器,發(fā)現(xiàn)很多尤其是CSS3新增的不太熟悉,在此總結(jié)一下。

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

            不同級(jí)別

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

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

            3.id選擇器

            4.類(lèi)選擇器

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

            6.通配符選擇器

            7.瀏覽器自定義

            同一級(jí)別

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

             

            基礎(chǔ)選擇器

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

             

            復(fù)制代碼
            *         {             /*頁(yè)面所有元素都使用*/             border:0;         }          #test         {             /*id=test 的元素*/             background-color:#0e0;         }          .staus         {             /*含有類(lèi)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è)吧,沒(méi)什么名字,匹配類(lèi)名中既包含class1又包含class2的元素

            我就不一一舉例子了,選擇器并不是只能寫(xiě)兩層,發(fā)現(xiàn)有些小朋友有這種誤解,認(rèn)為只能寫(xiě)E>F這樣的,我們寫(xiě)可以寫(xiě)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開(kāi)頭的元素,主要用于lang屬性,比如“en”、“en-us”
            E[attr ^=value]匹配屬性attr的值以value開(kāi)頭的元素
            E[attr $=value]匹配屬性attr的值以value結(jié)尾的元素
            E[attr *=value]匹配屬性attr的值包含value的元素

            偽類(lèi)選擇器

             

            選擇器含義
            E:first-child匹配元素E的第一個(gè)子元素
            E:link匹配所有未被點(diǎn)擊的鏈接
            E:visited匹配所有已被點(diǎn)擊的鏈接
            E:active匹配鼠標(biāo)已經(jīng)其上按下、還沒(méi)有釋放的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匹配用戶(hù)當(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()作用類(lèi)似,但是僅匹配使用同種標(biāo)簽的元素
            E:nth-last-of-type(n)與:nth-last-child() 作用類(lèi)似,但是僅匹配使用同種標(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 米米 閱讀(255) | 評(píng)論 (0)編輯 收藏

            2014年1月13日 #

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

            2014年1月9日 #

            • 老有人問(wèn)如何讓Qt的應(yīng)用程序自動(dòng)重啟,稍微寫(xiě)一點(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)了主線(xiàn)程的事件循環(huán)。而要退出程序,就是要退出這個(gè)事件循環(huán),使main函數(shù)返回。

            如何退出?

            正確方式:

            • QCoreApplication::exit(int);

            它還有一個(gè)馬甲

            • QCoreApplication::quit();

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

            quitOnLastWindowClosed

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

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

            • QApplication::closeAllWindows()

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

            啟動(dòng)外部程序

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

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

            可是,為什么不寫(xiě)成下面這樣?

            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

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

            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,沒(méi)什么特別含義,只是因?yàn)槲矣X(jué)得

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

            上班了,就寫(xiě)到這兒...

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

            2013年12月11日 #

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

            2013年9月12日 #

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

            TRANSLATIONS += myapp.ts

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

            posted @ 2013-09-12 15:59 米米 閱讀(501) | 評(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類(lèi)是一個(gè)靜態(tài)類(lèi),所以跟本不必生成tooltip對(duì)象就可以使用。
            五是tooltip類(lèi)不能被定制,所以不能從它產(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í)需要重寫(xiě)QWidget::event()函數(shù),在里面判斷事件類(lèi)型,如果是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類(lèi)的函數(shù)跟本就相當(dāng)于全局函數(shù)而已。

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

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

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

            QObject 重入

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

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

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

            Pre-Thread Event循環(huán)

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

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

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

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

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

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

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

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

            從另外線(xiàn)程訪(fǎng)問(wèn)QObject子類(lèi)


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

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

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

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


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


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

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

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

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


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

            讓我們看一下使用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)畫(huà)。對(duì)start()的調(diào)用將啟動(dòng)它所統(tǒng)治的所有的動(dòng)畫(huà)。

            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)畫(huà)們。它在上一個(gè)完成時(shí)按順序播放下一個(gè)。

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


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

            我們還可能連接屬性與狀態(tài),而不是手動(dòng)設(shè)置開(kāi)始與結(jié)束值。下面是完整的代碼,演示了動(dòng)畫(huà)一個(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 米米 閱讀(899) | 評(píng)論 (0)編輯 收藏

            概述

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



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


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


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


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


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

            動(dòng)畫(huà)框架中的類(lèi)們

            QAbstractAnimation

            所有動(dòng)畫(huà)類(lèi)的基類(lèi)

            QAnimationGroup

            動(dòng)畫(huà)組的基類(lèi)

            QEasingCurve

            控制動(dòng)畫(huà)的寬松曲線(xiàn)類(lèi)

            QParallelAnimationGroup

            并行動(dòng)畫(huà)組類(lèi)

            QPauseAnimation

            串行動(dòng)畫(huà)組類(lèi)的暫停類(lèi)

            QPropertyAnimation

            動(dòng)畫(huà)Qt屬性的類(lèi)

            QSequentialAnimationGroup

            串行動(dòng)畫(huà)組類(lèi)

            QTimeLine

            控制動(dòng)畫(huà)的時(shí)間線(xiàn)類(lèi)

            QVariantAnimation

            各動(dòng)畫(huà)類(lèi)的虛基類(lèi)


            動(dòng)畫(huà)Qt屬性們

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


            我們選擇動(dòng)畫(huà)Qt屬性的一個(gè)主要理由是Qt屬性為我們提供了自己動(dòng)畫(huà)已存在的類(lèi)的自由度。尤其是QWidget類(lèi)(我們也可以把它嵌入到一個(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)處。

            上面的例子舉在開(kāi)始值和結(jié)束值之間做線(xiàn)性插值。還可以在開(kāi)始和結(jié)束值之間設(shè)置值,插值運(yùn)算就會(huì)經(jīng)過(guò)這些點(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)畫(huà)將按鈕在8秒中內(nèi)弄到(250,250)處,然后在2秒種內(nèi)又弄回原位。移位是在這些點(diǎn)中間以線(xiàn)性插值進(jìn)行的。


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

            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)畫(huà)這個(gè)widget的geometry了,即使QGraphicsRectItem沒(méi)有提供geometry屬性。

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

            當(dāng)你想動(dòng)畫(huà)QGraphicsItems,你也要用QPropertyAnimation。然而,QGraphicsItem不是從QObject派生的。一個(gè)好的解決方案是派生要?jiǎng)赢?huà)的圖形item。派生類(lèi)也要從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)畫(huà)的屬性。

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

            寬松曲線(xiàn)

            QPropertyAnimation在屬性的開(kāi)始值和結(jié)束值之間執(zhí)行一個(gè)插值運(yùn)算。除了向動(dòng)畫(huà)添加更多的關(guān)鍵值外,你還可以使用一個(gè)寬松曲線(xiàn)。寬松曲線(xiàn)描述了一個(gè)在01之間插值的速度變化的函數(shù),如果你想控制一個(gè)動(dòng)畫(huà)的速度而不改變插值的路徑時(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)畫(huà)將按照一個(gè)曲線(xiàn)進(jìn)行,這個(gè)曲線(xiàn)使得動(dòng)畫(huà)像一個(gè)跳動(dòng)的皮球從開(kāi)始位置跳到結(jié)束位置。QEasingCurve具有一個(gè)大曲線(xiàn)集合,你可以從里面選擇一個(gè)。它們被定義為QEasingCurve::Type枚舉。如果你需要不一樣的曲線(xiàn),你也可以自己實(shí)現(xiàn)一個(gè),然后注冊(cè)到QEasingCurve

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

            僅列出標(biāo)題  下一頁(yè)
            国产精品久久永久免费| 久久se精品一区二区影院| 久久无码高潮喷水| A狠狠久久蜜臀婷色中文网| 国产精品成人久久久久三级午夜电影| 国产精品久久久久久久app| 久久精品人妻中文系列| 久久综合日本熟妇| 一本久久久久久久| 久久免费视频观看| 99久久免费国产特黄| 国内精品久久久久久久久| 色偷偷偷久久伊人大杳蕉| 伊人久久精品影院| 久久精品中文字幕大胸| 久久天天躁夜夜躁狠狠| 亚洲国产精品一区二区久久| 午夜精品久久久久久毛片| 亚洲精品美女久久777777| 久久亚洲av无码精品浪潮| 久久中文娱乐网| 日韩久久久久久中文人妻| 精品伊人久久久| 久久久久国产一区二区| 久久久久国产亚洲AV麻豆| 久久综合九色综合97_久久久| 色婷婷综合久久久久中文一区二区 | 亚洲AV乱码久久精品蜜桃| 久久午夜综合久久| 日本加勒比久久精品| 久久亚洲AV无码精品色午夜| 久久久久99精品成人片牛牛影视| 国产精品一久久香蕉国产线看| 亚洲狠狠婷婷综合久久蜜芽| 欧美午夜A∨大片久久| 国产亚洲美女精品久久久| 亚洲综合婷婷久久| 国产成人久久久精品二区三区| 久久精品国产亚洲一区二区| 久久久久四虎国产精品| 青青青青久久精品国产h|