4 QT分析之除錯跟蹤系統

2021-09-07 09:28:33 字數 3078 閱讀 6284

在我們前面的分析中,經常看到qwarning()和qdebug()之類的呼叫。今天深入的分析qt的除錯跟蹤系統。

我們先看qdebug.h中的巨集定義:

1 #if !defined(qt_no_debug_stream)

2 q_core_export_inline qdebug qdebug()

3 4 #else // qt_no_debug_stream

5 #undef qdebug

6 inline qnodebug qdebug()

7 #define qdebug qt_no_qdebug_macro

8 9 #ifdef qt_no_member_templates

10 template11 inline qnodebug operator<

12 #endif

13 14 #endif

15 16 #if !defined(qt_no_warning_output)

17 q_core_export_inline qdebug qwarning()

18 #else

19 #undef qwarning

20 inline qnodebug qwarning()

21 #define qwarning qt_no_qwarning_macro

22 #endif

這裡很明顯,qt的除錯跟蹤系統就是兩條:debug和warning。先看debug,如果我們定義了巨集qt_no_debug_stream,qdebug()被定義成qnodebug(),而qt_no_qdebug_macro的定義:

1 #define qt_no_qdebug_macro if(1); else qdebug
注意if後面的分號,其等價於空語句。

我們再看qnodebug類的定義:

1 class qnodebug

2 5 inline qnodebug(const qdebug &){}

6 inline ~qnodebug(){}

7 #if !defined( qt_no_textstream )

8 inline qnodebug &operator<

9 inline qnodebug &operator<

10 #endif

11 inline qnodebug &space()

12 inline qnodebug &nospace()

13 inline qnodebug &maybespace()

14 15 #ifndef qt_no_member_templates

16 template17 inline qnodebug &operator<

18 #endif

19 };

過載的《操作只是返回其自身。另外一種情況(就是有debug_stream)的時候,也就是預設情況下,qdebug被定為qdebug,qdebug的輸出裝置是什麼呢?看qdebug類中構造的定義:

1     inline qdebug(qiodevice *device) : stream(new stream(device)) {}

2 inline qdebug(qstring *string) : stream(new stream(string)) {}

3 inline qdebug(qtmsgtype t) : stream(new stream(t)) {}

4 inline qdebug(const qdebug &o):stream(o.stream)

可以知道qdebug的輸出裝置可以使qstring,qiodevice或者qtmsgtype指定的型別。

如果我們在main()函式裡面寫這樣一行程式:

1 qdebug() << "hello world!";
其執行的效果是向stderr裝置輸出"hello world!",根據

1 q_core_export_inline qdebug qdebug()
定義,實際呼叫的是:

1 inline qdebug(qtmsgtype t) : stream(new stream(t)) {}
語句,在新生成stream物件的時候,呼叫的是:

1 stream(qtmsgtype t) : ts(&buffer, qiodevice::writeonly), ref(1), type(t), space(true), message_output(true) {}
執行完畢之後,會釋放qdebug物件,看看qdebug的釋放:

1 inline ~qdebug() 

7 }

我們再來看qt_message_output()的**:

1 void qt_message_output(qtmsgtype msgtype, const char *buf)

2 else

17 18 if (msgtype == qtfatalmsg

19 || (msgtype == qtwarningmsg

20 && (!qgetenv("qt_fatal_warnings").isnull())) )

44 }

首先是判斷使用者有沒有handler,如果有這個處理能力就讓使用者自己處理:

1 static qtmsghandler handler = 0;                // pointer to debug handler
在qglobal.cpp中定義。要是想自己處理,只要讓handler指向自己的處理函式就可以了,多少有點c程式的味道。

否則的話就會輸出到stderr裝置上(win系統中非wince的情況)。

其他,如果是fatal(致命)錯誤或者警告,則會呼叫_crtdbgreport(),其模式是_crt_error。也就是往偵錯程式報告致命錯誤。qwarning的實現基本類似,不再深入一步一步分析。

**:

4 QT功能模組

選中乙個檔案 str path為檔案路徑 qstring str path qfiledialog getopenfilename this,tr 選擇轉碼檔案 tr home tr 選中多個檔案 qstring strs qstringlist file list,output name qstr...

4 QT自定義模型

在聊學習之前,想說一下將近乙個星期的時間我都幹了些什麼,為什麼沒有學習,總結起來乙個字 玩,11號朋友遠道而來,說是在家閒得慌,過來找我一起浪,直到昨天才將他送走,既然朋友來了,自然不能怠慢,請他吃飯,帶他閒逛,一起去爬山,還吃了一天的自製火鍋,回想起來這味道有點反胃。獨處的時候適合學習和思考,玩耍...

Q學習 4 QT的元物件系統

qt對c 進行了擴充套件,提供了三個主要的功能 訊號槽 執行時型別資訊和動態屬性,這三個擴充套件功能都是由 元物件系統 提供的。元物件系統基於三個支撐點 1 oobject為需要使用元物件系統有點的類提供了基類。2 q object巨集宣告在類的私有段中,可用來啟用元物件特徵,如動態屬性,訊號槽。3...