• <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++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

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

            CONFIG += precompiled_header

            然后定義需要預編譯的頭文件:

            PRECOMPILED_HEADER = pch.h

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

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

            Qt元類型(MetaType)注冊門

                  昨天調試項目時,突然發現如下消息:

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

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

                  通常使用的connect,實際上最后一個參數使用的是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(直連方式)

                  當信號發出后,相應的槽函數將立即被調用。emit語句后的代碼將在所有槽函數執行完畢后被執行。(信號與槽函數關系類似于函數調用,同步執行

            • Qt::QueuedConnection(排隊方式)

                  當信號發出后,排隊到信號隊列中,需等到接收對象所屬線程的事件循環取得控制權時才取得該信號,調用相應的槽函數。emit語句后的代碼將在發出信號后立即被執行,無需等待槽函數執行完畢。(此時信號被塞到信號隊列里了,信號與槽函數關系類似于消息通信,異步執行

            • Qt::AutoConnection(自動方式)

                  Qt的默認連接方式,如果信號的發出和接收這個信號的對象同屬一個線程,那個工作方式與直連方式相同;否則工作方式與排隊方式相同。

                  我的項目中的確跨線程使用了ERROR_LEVEL為參數類型的信號,因此使用的應當是排隊方式的信號-槽機制,出現“隊列中無法使用ERROR_LEVEL類型”的警告信息就可以理解了。放狗搜了一圈,有篇文章提供了個這樣的解決方案:

            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);

            這樣做的確能使警告信息消失,因為Qt官方文檔寫了:

            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.

            即使用排隊方式的信號-槽機制,Qt的元對象系統(meta-object system)必須知道信號傳遞的參數類型。這里手動改為直連方式,Qt的元對象系統就不必知道參數類型了,于是警告信息消失。但這樣做是不安全的,見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.

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

            頭文件

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

            cpp文件

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

            posted @ 2011-04-15 22:56 RTY 閱讀(345) | 評論 (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內置類型在QVaiant中使用,必須使用該宏。
              • 該類型必須有公有的 構造、析構、復制構造 函數
            • qRegisterMetaType 必須使用該函數的兩種情況
              • 如果非QMetaType內置類型要在 Qt 的屬性系統中使用
              • 如果非QMetaType內置類型要在 queued 信號與槽 中使用

            二者關系

            二者的代碼:

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

            • qRegisterMetaType 將某類型注冊中 MetaType 系統中

            二者的聯系:

            • QMetaTypeId<TYPE>的類中的成員包含對qRegisterMetaType的調用

            • 我們知道類中的成員函數并不一定會被調用(即,該宏并不確保類型被注冊到MetaType)。

            • 通過qRegisterMetaType可以確保類型被注冊

            兩個qRegisterMetaType 的聯系

            • 無參的qRegisterMetaType函數會通過該成員調用帶參數的qRegisterMetaType()

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

            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

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

            • 該類含一個enum和一個返回!QMetaType的id的成員函數

            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));
            }
            • 該函數的核心就是調用了registerType 函數
            • 兩個Helper模板函數分別對構造和析構函數進行封裝

            registerType

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

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

            函數功能:

            • 根據類型名查找其MetaType類型,如果已存在,則直接返回;否則創建后返回。

            • 創建一個 !QCustomTypeInfo 對象
            • 該對象包含要類型的構造、析構信息,已經規范化后的類型名
            • 該對象存入一個全局的!QVector中

            qRegisterMetaType()

            看manual,可以知道,qRegisterMetaType 還有一個無參的重載函數。

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

            unregisterType(const char *typeName)

            函數的作用是取消自己先前注冊的某個metatype類型。

            前面提到注冊信息在一個全局的 QVector<QCustomTypeInfo>中,當取消注冊的時候是怎么樣的呢?直接刪除Vector中相應的項么?源碼告訴我們,不是的。

            實際是查找到相應的項,清空該項的內容。

            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 閱讀(2867) | 評論 (0)編輯 收藏

                   摘要:   閱讀全文

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

              一、基本分類:
              qDebug : 調試信息提示
              qWarning: 一般的警告提示
              qCritical: 嚴重錯誤提示
              qFatal: 致命錯誤提示

              二、如何截獲這些信息

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

              三、將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         //調試信息提示
              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         //嚴重錯誤提示
              19         case QtCriticalMsg:
              20                 txt = QString("Critical: %1").arg(msg);
              21         break;
              22         //致命錯誤提示
              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         //先注冊自己的MsgHandler
              39         qInstallMsgHandler(customMessageHandler);        
              40         
              41         //以后就可以像下面這樣直接打日志到文件中,而且日志也會包含時間信息
              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.
              只要執行qInstallMsgHandler(0) 就可以了

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

              http://www.webresourcesdepot.com/

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

              現在開始樣式表!
              僅僅改變一個文件就可以改變數百個網頁的外觀......個性化的表現而不損失訪問者......所有這些都因為網頁樣式表的強大和靈活特性。
              CSS 速成
              層疊樣式表的基礎入門。
              CSS 結構和規則
              各種選擇符、偽類、偽元素和層疊順序的入門。
              CSS 屬性
              各種層疊樣式表級別一有效的屬性的描述。
              將樣式表加入到HTML中
              各種將樣式表加入到HTML文本中的方法。
              依賴樣式表
              怎樣會是濫用樣式表和使你的網頁難以處理。
              CSS 參考
              連接到介紹CSS的規范和其它方面的文章。

               

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

              這只是一個布局實例,學習CSS有用處,因為這個用來修飾圖片的邊框做的不錯,主要是想了解如何用CSS實現這種布局,在相對、絕對定位,或者是在多種瀏覽器不失真、不變形,從事WEB前端設計的朋友有空可參考一下。


              網址:http://www.jb51.net/jiaoben/22250.html

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

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





              網址:http://www.jb51.net/jiaoben/20333.html

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

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


              網址:http://www.jb51.net/jiaoben/28880.html

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

              50個css做的button弄完了,說了早上給大家下載的,中午有事情在忙,所以現在才弄完,圖片和CSS已經打包好了,大家可以下載,因為時間關系,有些button沒有做成可伸縮的,如果需要的話自己改一下就行了,我沒時間改了,另外如果想要PSD源文檔的,可以留下Email。另外聲明:本站所有腳本、圖片、教程、程序等等全屬個人原創,轉載請保留版權。


              網摘:http://www.jb51.net/jiaoben/21699.html

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

              僅列出標題
              共31頁: First 23 24 25 26 27 28 29 30 31 
              久久人人爽人人爽人人片AV麻烦| 久久99热这里只有精品国产| 久久综合噜噜激激的五月天| 久久精品人人槡人妻人人玩AV | 久久综合亚洲鲁鲁五月天| 久久人人爽人人爽人人片AV东京热| 麻豆一区二区99久久久久| 久久午夜电影网| 久久婷婷五月综合成人D啪 | 久久综合给合久久狠狠狠97色69| 久久精品国产亚洲精品2020| 久久精品国产欧美日韩| 无码人妻精品一区二区三区久久久 | 久久国产影院| 国内精品久久久久久野外| 少妇熟女久久综合网色欲| 久久精品国产亚洲Aⅴ蜜臀色欲| 亚洲精品国产字幕久久不卡| 色婷婷噜噜久久国产精品12p| 精品国产一区二区三区久久| 久久综合久久美利坚合众国| 国内精品久久久久久久久| 国产精品久久自在自线观看| 久久国语露脸国产精品电影| 日韩精品久久久久久久电影| 久久久久国产精品三级网| 国产精品一区二区久久精品| 久久久国产乱子伦精品作者| 亚洲成色WWW久久网站| 久久99国产精品久久99小说| 精品久久久无码中文字幕天天| 久久精品成人国产午夜| 蜜臀av性久久久久蜜臀aⅴ麻豆| 少妇无套内谢久久久久| 久久久亚洲AV波多野结衣| 少妇无套内谢久久久久| 久久午夜无码鲁丝片秋霞 | 精品久久久噜噜噜久久久| 久久99热只有频精品8| 久久婷婷五月综合色奶水99啪| 无码伊人66久久大杳蕉网站谷歌|