• <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>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            QT也可以像VS那樣使用預(yù)編譯頭文件來加速編譯器的編譯速度。首先在.pro文件中加入:

            CONFIG += precompiled_header

            然后定義需要預(yù)編譯的頭文件:

            PRECOMPILED_HEADER = pch.h

            其中pch.h頭文件即為自定義的預(yù)編譯頭文件。

            posted @ 2011-04-15 23:02 RTY 閱讀(896) | 評(píng)論 (0)編輯 收藏

            Qt元類型(MetaType)注冊(cè)門

                  昨天調(diào)試項(xiàng)目時(shí),突然發(fā)現(xiàn)如下消息:

            QObject::connect: Cannot queue arguments of type 'ERROR_LEVEL'
            (Make sure 'ERROR_LEVEL' is registered using qRegisterMetaType().)

            其中ERROR_LEVEL只是我定義的枚舉類型即enum ERROR_LEVEL。然后在Qt的信號(hào)-槽函數(shù)的參數(shù)中使用了這個(gè)枚舉型,在發(fā)送信號(hào)時(shí)就出現(xiàn)了上述警告。上面警告的大概意思是信號(hào)隊(duì)列中無法使用 ERROR_LEVEL類型,要使用qRegisterMetaType()注冊(cè)該類型后方可使用。

                  通常使用的connect,實(shí)際上最后一個(gè)參數(shù)使用的是Qt::AutoConnection類型:

            bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection )

            Qt支持6種連接方式,其中3中最主要:

            • Qt::DirectConnection(直連方式)

                  當(dāng)信號(hào)發(fā)出后,相應(yīng)的槽函數(shù)將立即被調(diào)用。emit語句后的代碼將在所有槽函數(shù)執(zhí)行完畢后被執(zhí)行。(信號(hào)與槽函數(shù)關(guān)系類似于函數(shù)調(diào)用,同步執(zhí)行

            • Qt::QueuedConnection(排隊(duì)方式)

                  當(dāng)信號(hào)發(fā)出后,排隊(duì)到信號(hào)隊(duì)列中,需等到接收對(duì)象所屬線程的事件循環(huán)取得控制權(quán)時(shí)才取得該信號(hào),調(diào)用相應(yīng)的槽函數(shù)。emit語句后的代碼將在發(fā)出信號(hào)后立即被執(zhí)行,無需等待槽函數(shù)執(zhí)行完畢。(此時(shí)信號(hào)被塞到信號(hào)隊(duì)列里了,信號(hào)與槽函數(shù)關(guān)系類似于消息通信,異步執(zhí)行

            • Qt::AutoConnection(自動(dòng)方式)

                  Qt的默認(rèn)連接方式,如果信號(hào)的發(fā)出和接收這個(gè)信號(hào)的對(duì)象同屬一個(gè)線程,那個(gè)工作方式與直連方式相同;否則工作方式與排隊(duì)方式相同。

                  我的項(xiàng)目中的確跨線程使用了ERROR_LEVEL為參數(shù)類型的信號(hào),因此使用的應(yīng)當(dāng)是排隊(duì)方式的信號(hào)-槽機(jī)制,出現(xiàn)“隊(duì)列中無法使用ERROR_LEVEL類型”的警告信息就可以理解了。放狗搜了一圈,有篇文章提供了個(gè)這樣的解決方案:

            connect(cm, SIGNAL(sendLog(QUuid, QByteArray, bool)),
                        this,SLOT(sendRes(QUuid,QByteArray,bool)));
            改為:
            connect(cm, SIGNAL(sendLog(QUuid, QByteArray, bool)),
                        this,SLOT(sendRes(QUuid,QByteArray,bool)), Qt::DirectConnection);

            這樣做的確能使警告信息消失,因?yàn)镼t官方文檔寫了:

            With queued connections, the parameters must be of types that are known to Qt's meta-object system, because Qt needs to copy the arguments to store them in an event behind the scenes.

            即使用排隊(duì)方式的信號(hào)-槽機(jī)制,Qt的元對(duì)象系統(tǒng)(meta-object system)必須知道信號(hào)傳遞的參數(shù)類型。這里手動(dòng)改為直連方式,Qt的元對(duì)象系統(tǒng)就不必知道參數(shù)類型了,于是警告信息消失。但這樣做是不安全的,見Qt官方文檔:

            Be aware that using direct connections when the sender and receiver live in different threads is unsafe if an event loop is running in the receiver's thread, for the same reason that calling any function on an object living in another thread is unsafe.

                  因此,咱還是老老實(shí)實(shí)地用qRegisterMetaType()注冊(cè)類型吧,見代碼:

            頭文件

            /*! \file errorlevel.h*/
            
            #ifndef ERRORLEVEL_H
            
            #define ERRORLEVEL_H
            
            
            
            /*! \enum ERROR_LEVEL
            
             * 錯(cuò)誤等級(jí)的定義。通常用來在傳遞錯(cuò)誤消息時(shí)標(biāo)記錯(cuò)誤的等級(jí)。
            
             */
            
            enum ERROR_LEVEL
            
            {
            
                NORMAL,  /*!< 普通錯(cuò)誤,通常不需要處理,可以記錄或者顯示錯(cuò)誤消息。*/
            
                CRITICAL /*!< 嚴(yán)重錯(cuò)誤,需要緊急處理,如果沒有妥善處理,可能導(dǎo)致后續(xù)操作失敗。*/
            
            };
            
            
            
            #endif // ERRORLEVEL_H

            cpp文件

            /*! \file errorlevel.cpp*/
            
            #include "errorlevel.h"
            
            
            
            /*! 模板函數(shù)顯式實(shí)例化,注冊(cè)ERROR_LEVEL到元對(duì)象系統(tǒng)。這樣才可以在信號(hào)-槽
            
             * 隊(duì)列里使用ERROR_LEVEL類型參數(shù)。
            
             */
            
            int i = qRegisterMetaType<ERROR_LEVEL>("ERROR_LEVEL");
            元類型注冊(cè)方法受益于這篇文章

            posted @ 2011-04-15 22:56 RTY 閱讀(354) | 評(píng)論 (0)編輯 收藏

            Registering custom types

            February 15th, 2009

            Just a note here, if you would have to pass custom data types between threads in Qt. As we know, a signal-slot connection is then (by default) of type Qt::QueuedConnection. Because in such a situation Qt needs to store passed parameters for a while, it creates their temporary copies. If it doesn’t recognize the passed data type, throws out an error:

             

            QObject::connect: Cannot queue arguments of type 'MyType'
                        

             

            So custom data types have to be registered using qRegisterMetaType(), like in the example:

             

            qRegisterMetaType<MyType>( "MyType" );
                        

             

            And this example is literal ⇒ when your class is called MyType, you register it as "MyType". Lastly I did something similar to this:

             

              1
                          2
                          3
                        
            typedef QMap<QString,QImage> MapStringImage;
                        (...)
                        qRegisterMetaType<MapStringImage>( "images" );
                        

             

            I didn’t get the error from QObject::connect (!), but also didn’t get things working. Wasted few hours hacking QMetaType class with no effect, and then more by accident than design changed "images" to "MapStringImage" and woo-hoo! That was my only problem… That’s why I’m stressing this naming issue, especially that documentation doesn’t tell a lot about it.

            BTW I needed to use typedef because otherwise Qt didn’t have a clue what to do with such a complex type.




            原文:http://hi.baidu.com/cyclone/blog/item/01108bd40599b00fa18bb793.html


            基本理解

            • Q_DECLARE_METATYPE
              • 如果要使自定義類型或其他非QMetaType內(nèi)置類型在QVaiant中使用,必須使用該宏。
              • 該類型必須有公有的 構(gòu)造、析構(gòu)、復(fù)制構(gòu)造 函數(shù)
            • qRegisterMetaType 必須使用該函數(shù)的兩種情況
              • 如果非QMetaType內(nèi)置類型要在 Qt 的屬性系統(tǒng)中使用
              • 如果非QMetaType內(nèi)置類型要在 queued 信號(hào)與槽 中使用

            二者關(guān)系

            二者的代碼:

            • Q_DECLARE_METATYPE 展開后是一個(gè)特化后的類 QMetaTypeId<TYPE>

            • qRegisterMetaType 將某類型注冊(cè)中 MetaType 系統(tǒng)中

            二者的聯(lián)系:

            • QMetaTypeId<TYPE>的類中的成員包含對(duì)qRegisterMetaType的調(diào)用

            • 我們知道類中的成員函數(shù)并不一定會(huì)被調(diào)用(即,該宏并不確保類型被注冊(cè)到MetaType)。

            • 通過qRegisterMetaType可以確保類型被注冊(cè)

            兩個(gè)qRegisterMetaType 的聯(lián)系

            • 無參的qRegisterMetaType函數(shù)會(huì)通過該成員調(diào)用帶參數(shù)的qRegisterMetaType()

            這兩個(gè)東西真難理清,不妨看看源碼吧。

            Q_DECLARE_METATYPE

            代碼來源:src/corelib/kernel/qmetatype.h

            #define Q_DECLARE_METATYPE(TYPE)                                        \
            QT_BEGIN_NAMESPACE \
            template <> \
            struct QMetaTypeId< TYPE > \
            { \
            enum { Defined = 1 }; \
            static int qt_metatype_id() \
            { \
            static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
            if (!metatype_id) \
            metatype_id = qRegisterMetaType< TYPE >(#TYPE); \
            return metatype_id; \
            } \
            }; \
            QT_END_NAMESPACE

            • 宏展開是一個(gè)在Qt的命名空間中的一個(gè)類模板的特化 QMetaTypeId<TYPE>

            • 該類含一個(gè)enum和一個(gè)返回!QMetaType的id的成員函數(shù)

            qRegisterMetaType(const char *typeName)

            代碼來源:src/corelib/kernel/qmetatype.h

            template <typename T>
            int qRegisterMetaType(const char *typeName)
            {
            typedef void*(*ConstructPtr)(const T*);
            ConstructPtr cptr = qMetaTypeConstructHelper<T>;
            typedef void(*DeletePtr)(T*);
            DeletePtr dptr = qMetaTypeDeleteHelper<T>;

            return QMetaType::registerType(typeName, reinterpret_cast<QMetaType::Destructor>(dptr),
            reinterpret_cast<QMetaType::Constructor>(cptr));
            }
            • 該函數(shù)的核心就是調(diào)用了registerType 函數(shù)
            • 兩個(gè)Helper模板函數(shù)分別對(duì)構(gòu)造和析構(gòu)函數(shù)進(jìn)行封裝

            registerType

            代碼來源:src/corelib/kernel/qmetatype.cpp

            int QMetaType::registerType(const char *typeName, Destructor destructor, Constructor constructor)

            函數(shù)功能:

            • 根據(jù)類型名查找其MetaType類型,如果已存在,則直接返回;否則創(chuàng)建后返回。

            • 創(chuàng)建一個(gè) !QCustomTypeInfo 對(duì)象
            • 該對(duì)象包含要類型的構(gòu)造、析構(gòu)信息,已經(jīng)規(guī)范化后的類型名
            • 該對(duì)象存入一個(gè)全局的!QVector中

            qRegisterMetaType()

            看manual,可以知道,qRegisterMetaType 還有一個(gè)無參的重載函數(shù)。

            template <typename T>
            inline int qRegisterMetaType()
            {
            return qMetaTypeId(static_cast<T *>(0));
            }
            • 函數(shù)看起來和帶參數(shù)的那個(gè)似乎區(qū)別很大(難道不是么?)。
            • 手冊(cè)中告訴我們,執(zhí)行這個(gè)的時(shí)候,模板參數(shù)T必須用 Q_DECLARE_METATYPE() 聲明過
            • 能猜到原因嗎?注意看前面 Q_DECLARE_METATYPE() 代碼,
            • 對(duì)了。類中的成員函數(shù)qt_metatype_id中包含對(duì)qRegisterMetaType(typeName)的調(diào)用
            • 這兒就是輾轉(zhuǎn)調(diào)用了這個(gè)帶參數(shù)的qRegisterMetaType函數(shù) 

            unregisterType(const char *typeName)

            函數(shù)的作用是取消自己先前注冊(cè)的某個(gè)metatype類型。

            前面提到注冊(cè)信息在一個(gè)全局的 QVector<QCustomTypeInfo>中,當(dāng)取消注冊(cè)的時(shí)候是怎么樣的呢?直接刪除Vector中相應(yīng)的項(xiàng)么?源碼告訴我們,不是的。

            實(shí)際是查找到相應(yīng)的項(xiàng),清空該項(xiàng)的內(nèi)容。

            for (int v = 0; v < ct->count(); ++v)
             {

             if (ct->at(v).typeName == typeName)
             {

             QCustomTypeInfo &inf = (*ct)[v];
             inf.typeName.clear();
             inf.constr = 0;
             inf.destr = 0;
             inf.alias = -1;
             }
            }

             

              posted @ 2011-04-15 22:34 RTY 閱讀(2900) | 評(píng)論 (0)編輯 收藏

                   摘要:   閱讀全文

              posted @ 2011-04-15 22:20 RTY 閱讀(2922) | 評(píng)論 (0)編輯 收藏

              一、基本分類:
              qDebug : 調(diào)試信息提示
              qWarning: 一般的警告提示
              qCritical: 嚴(yán)重錯(cuò)誤提示
              qFatal: 致命錯(cuò)誤提示

              二、如何截獲這些信息

              Qt提供了qInstallMsgHandler 方法用來定制消息發(fā)生后如何來處理。
              qInstallMsgHandler 是一個(gè)回調(diào)函數(shù),主要是由qDebug、qWarnng、qCritical、qFatal這些函數(shù)進(jìn)行觸發(fā),
              也就是說,qDeubg這些函數(shù)處理的消息文本會(huì)被qInstallMsgHandler 所指向的回調(diào)函數(shù)截獲,這樣就允許用戶自己來處理這些消息文本。
              例如,你完全可以將這些消息文本輸出并保存到相關(guān)的日志文件中。請(qǐng)看下面的示例!

              三、將qDebug()\qWarning()\qCritical()\qFatal() 信息輸出到指定文件中

               1 #include <QtDebug>
               2 #include <QFile>
               3 #include <QTextStream>
               4 
               5 void customMessageHandler(QtMsgType type, const char *msg)
               6 {
               7         QString txt;
               8         switch (type) {
               9         //調(diào)試信息提示
              10         case QtDebugMsg:
              11                 txt = QString("Debug: %1").arg(msg);
              12                 break;
              13 
              14         //一般的warning提示
              15         case QtWarningMsg:
              16                 txt = QString("Warning: %1").arg(msg);
              17         break;
              18         //嚴(yán)重錯(cuò)誤提示
              19         case QtCriticalMsg:
              20                 txt = QString("Critical: %1").arg(msg);
              21         break;
              22         //致命錯(cuò)誤提示
              23         case QtFatalMsg:
              24                 txt = QString("Fatal: %1").arg(msg);
              25                 abort();
              26         }
              27 
              28         QFile outFile("debuglog.txt");
              29         outFile.open(QIODevice::WriteOnly | QIODevice::Append);
              30         QTextStream ts(&outFile);
              31         ts << txt << endl;
              32 }
              33 
              34 int main( int argc, char * argv[] )
              35 {
              36         QApplication app( argc, argv );
              37 
              38         //先注冊(cè)自己的MsgHandler
              39         qInstallMsgHandler(customMessageHandler);        
              40         
              41         //以后就可以像下面這樣直接打日志到文件中,而且日志也會(huì)包含時(shí)間信息
              42         qDebug("This is a debug message at thisisqt.com");
              43         qWarning("This is a warning message  at thisisqt.com");
              44         qCritical("This is a critical message  at thisisqt.com");
              45         qFatal("This is a fatal message at thisisqt.com");
              46 
              47         return app.exec();
              48 }


              四、如何取消信息處理呢?
              簡單:
              還是用qInstallMsgHandler.
              只要執(zhí)行qInstallMsgHandler(0) 就可以了

              posted @ 2011-04-10 14:14 RTY 閱讀(9321) | 評(píng)論 (0)編輯 收藏

              http://www.webresourcesdepot.com/

              http://htmlhelp.com/zh/reference/css/

              現(xiàn)在開始樣式表!
              僅僅改變一個(gè)文件就可以改變數(shù)百個(gè)網(wǎng)頁的外觀......個(gè)性化的表現(xiàn)而不損失訪問者......所有這些都因?yàn)榫W(wǎng)頁樣式表的強(qiáng)大和靈活特性。
              CSS 速成
              層疊樣式表的基礎(chǔ)入門。
              CSS 結(jié)構(gòu)和規(guī)則
              各種選擇符、偽類、偽元素和層疊順序的入門。
              CSS 屬性
              各種層疊樣式表級(jí)別一有效的屬性的描述。
              將樣式表加入到HTML中
              各種將樣式表加入到HTML文本中的方法。
              依賴樣式表
              怎樣會(huì)是濫用樣式表和使你的網(wǎng)頁難以處理。
              CSS 參考
              連接到介紹CSS的規(guī)范和其它方面的文章。

               

              posted @ 2011-04-10 12:14 RTY 閱讀(157) | 評(píng)論 (0)編輯 收藏

              這只是一個(gè)布局實(shí)例,學(xué)習(xí)CSS有用處,因?yàn)檫@個(gè)用來修飾圖片的邊框做的不錯(cuò),主要是想了解如何用CSS實(shí)現(xiàn)這種布局,在相對(duì)、絕對(duì)定位,或者是在多種瀏覽器不失真、不變形,從事WEB前端設(shè)計(jì)的朋友有空可參考一下。


              網(wǎng)址:http://www.jb51.net/jiaoben/22250.html

              posted @ 2011-04-10 11:57 RTY 閱讀(300) | 評(píng)論 (0)編輯 收藏

              風(fēng)格類似Vista的純CSS菜單欄,超漂亮的菜單,因使用了不少的資源文件,因此一并打包,方便你下載,效果可以看上圖,黑色與藍(lán)色調(diào)配合,大氣,沉穩(wěn)。





              網(wǎng)址:http://www.jb51.net/jiaoben/20333.html

              posted @ 2011-04-10 11:53 RTY 閱讀(296) | 評(píng)論 (0)編輯 收藏

              CSS完成一個(gè)漂亮的登錄框效果,而且還是仿Windows XP的樣式,只不過是經(jīng)典風(fēng)格的XP,包含完整的資源文件,你下載后直接把相關(guān)文件拷貝就可用啦,先看看效果圖在上邊,是不是很美麗?


              網(wǎng)址:http://www.jb51.net/jiaoben/28880.html

              posted @ 2011-04-10 11:51 RTY 閱讀(927) | 評(píng)論 (1)編輯 收藏

              50個(gè)css做的button弄完了,說了早上給大家下載的,中午有事情在忙,所以現(xiàn)在才弄完,圖片和CSS已經(jīng)打包好了,大家可以下載,因?yàn)闀r(shí)間關(guān)系,有些button沒有做成可伸縮的,如果需要的話自己改一下就行了,我沒時(shí)間改了,另外如果想要PSD源文檔的,可以留下Email。另外聲明:本站所有腳本、圖片、教程、程序等等全屬個(gè)人原創(chuàng),轉(zhuǎn)載請(qǐng)保留版權(quán)。


              網(wǎng)摘:http://www.jb51.net/jiaoben/21699.html

              posted @ 2011-04-10 11:49 RTY 閱讀(832) | 評(píng)論 (0)編輯 收藏

              僅列出標(biāo)題
              共31頁: First 23 24 25 26 27 28 29 30 31 
              亚洲AV无一区二区三区久久| 久久人人爽人人爽人人片AV高清| 久久久噜噜噜www成人网| 久久精品卫校国产小美女| 久久综合狠狠综合久久综合88 | 久久精品国产乱子伦| 久久偷看各类wc女厕嘘嘘| 青青青青久久精品国产 | 久久综合视频网站| 香蕉久久夜色精品升级完成| 日韩亚洲欧美久久久www综合网| 欧美久久一级内射wwwwww.| 久久亚洲私人国产精品vA| 久久精品免费网站网| 久久大香香蕉国产| 久久久久波多野结衣高潮| 国产成人精品久久亚洲| 久久综合给合久久狠狠狠97色69 | 粉嫩小泬无遮挡久久久久久| 久久久久久毛片免费看| 久久99精品国产自在现线小黄鸭| 伊人久久精品影院| 久久久久久国产精品无码下载| WWW婷婷AV久久久影片| A级毛片无码久久精品免费| 精品国产青草久久久久福利| 99热成人精品热久久669| 色婷婷综合久久久久中文一区二区 | 热99RE久久精品这里都是精品免费| 久久精品国产亚洲沈樵| 久久人人爽人人爽人人片AV不 | 欧美性大战久久久久久| 91久久精品无码一区二区毛片| 少妇高潮惨叫久久久久久| 久久香综合精品久久伊人| 日批日出水久久亚洲精品tv| 欧美激情精品久久久久久| 日本久久久久久久久久| 久久天天躁狠狠躁夜夜av浪潮 | 久久久精品午夜免费不卡| 久久青青草原综合伊人|