QT類庫
QT核心特點
- QT是一個跨平台開發的類庫。
- QT的元對象編譯器MOC是一個預處理器,在源程序被編譯前先將這些QT特性的程序轉為標准的C++兼容的形式,然后再有標准的C++編譯器進行編譯。也就是為什么在使用信號和槽的機制的類里,必須添加一個Q_OBJECT宏的原因,只有添加了這個宏,moc才能對類里的信號與槽代碼進行預處理。
- QT Core模塊是qt類庫的核心。
QT元對象系統
- 元對象系統由三個基礎組成:(1)QObject類是所有使用元對象系統類的基類。(2)在一個類的private部分申明Q_OBJECT宏,使得類可以使用元對象的特性,如動態屬性,信號與槽。(3)MOC為每個QObject的子類提供必要的代碼來實現元對象系統的特性;構建項目時MOC工具讀取C++源文件,當它發現類的定義里有Q_OBJECT宏時,它會為這個類生成另外一個包含有元對象支持代碼的C++源文件,這個生成的源文件連同類的實現文件一起被編譯和連接。
元對象的其它功能
- QObject::metaObject()函數返回關聯的元對象,元對象類QMetaObject包含了訪問元對象的一些接口函數。
- QMetaObject::newInstance()函數創建類的一個新的實例。
- QObject::inherits(const char* className)函數判斷一個對象實例是否是名稱為className的類或QObject的子類的實例。
- QObject::tr()和QObject::reUtf8()函數可翻譯字符串,用於多語言界面設計。
- QObject::setProperty()和QObject::property()用於通過屬性名動態設置和獲取屬性值。
屬性系統
- QT提供了一個Q_PROPERTY()宏可以定義屬性,他也是基於元對象系統實現的。
- 動態屬性,定義了屬性后,可以通過QObject::setProperty()函數設置屬性值;可以通過QObject::property()函數來獲取屬性值。
- 類的附加信息:屬性系統還有一個宏Q_CLASSINFO(),可以為類的元對象定義“名稱--值信息”。
信號與槽
- connect()函數有多種重載
- 不管是那種參數形式的connect()函數,最后都會有一個參數Qt::ConnectionType type,默認值為Qt::AutoConnection.枚舉類型Qt::ConnectionType表示信號與槽之間的關聯方式,有Qt::AutoConnection(缺省值):如果信號的接受者和發送這在同一個線程,就使用Qt::DirectConnection方式;否則使用QT::QUeuedConnection方式,在信號發射時自動確定關聯方式;Qt::DirectionConnection:信號被發射時槽函數立即執行,槽函數和信號在同一個線程;Qt::QueuedConnection:在時間循環回到接收者線程后執行槽函數,槽函數與信號在不同的線程;Qt::BlockingQueuedConnection:與Qt::QueuedConnection相似,只是信號線程會阻塞直到槽函數執行完畢,當信號和槽在同一個線程時絕對不能使用這種方式,否則會造成死鎖。
- 使用Sender()獲得信號發射者。例如在QSpinx的ValueChanged(int)信號的槽函數里,可以通過Sender()和qobject_cast獲得信號發射者的指針,從而對信號發射者進行操作。QSpinBox *spinBox=qobject_caet<QSpinBox *>(sender());
- 自定義信號以及其使用:在自己設計的類里也可以自定義信號,信號就是在類定義里聲明的一個函數,無需實現,只需要發射(emit)。信號函數必須是無返回值的函數,但是可以有輸入參數。
Qt全局定義
數據類型定義
- 為了確保在各個平台上個數據類型都有統一確定的長度,Qt為各種常見的數據類型定義了類型符號。
- 數據類型定義如下圖所示:
函數
-
頭文件包含一些常用函數的定義,這些函數多以模板類型作為參數,返回相應的模板類型。 -
中常用的全局函數定義如下圖所示:
-
還有一些基礎的數學運算函數在
頭文件中定義。
宏定義
-
頭文件中定義了很多宏。
常用的宏
- QT_VERSSION 這個宏展開為數值形式0xMMNNPP表示QT編譯器版本,例如Qt編譯器版本為Qt5.9.1,則QT_VERSION為0x050901。這個宏常用語條件編譯設置,根據qt版本不同,編譯不同的代碼段。
- QT_VERSION_CHECK 這個宏展開為Qt版本號的一個整數表示。
- QT_VERSION_STR 這個宏展開為Qt版本號的字符串,如“5.9.0”
- Q_BYTE_ORDER,Q_BIG_ENDIAN和Q_LITTLE_ENDIAN;Q_BYTE_ORDER表示系統內存中數據的字節序,Q_BIG_ENDIAN表示大端字節序,Q_LITTLE_ENDIAN表示小端字節序。在判斷系統字節序時會用到。
- Q_DECL_IMPORT和Q_DECL_EXPORT 在使用或設計共享庫時,用於導出庫的內容。
- Q_DECL_OIVERRIDE 在類定義中,用於重載一個虛函數,使用此宏后,如果重載的虛函數沒有進行任何重載操作,編譯器將會報錯。
- Q_DECL_FINAL 這個宏將一個虛函數定義為最終級別,不能再被重載,或定義一個類不能再被繼承。
- Q_UNUSED(name) 這個宏用於在函數中定義不在函數體力使用的參數。
- foreach(variable,container) 用於容器類的遍歷。
- forever 用於構造一個無限循環。
- qDebug(const char * message,...) 在debugger窗體顯示信息,如果編譯器設置了Qt_NO_DEBUG_OUTPUT,則不作任何輸出。類似的宏還有qWarning,qCritical,qFatal,qInfo,也是用於在debugger窗體顯示信息。
容器類
Qt容器類比標准模板庫(STL)中的容器類更輕巧,安全和易於使用。這些容器類是掩式共享和可重入的,而且他們進行了速度和存儲優化,他們是線程安全的,也就是說他們作為制度容器可被多個線程訪問。
順序容器類
- Qt的順序容器類有QList,QLinkedList,QVector,QStack和QQueue。
- QList是最常用的容器類,基於數組列表的形式實現的。
- QLinkedList是鏈式列表,數據項不是用連續的內存存儲的,它基於迭代器訪問數據項。
- QVector提供動態數組的功能,以下標索引訪問數據;QVector的性能比QList更高,因為QVector的數據項是連續存儲的。
- QStack是提供類似於堆棧的后入先出操作的容器類,push()和pop()是主要的接口函數。
- QQueue是提供與類似於隊列先入先出操作的容器類,enqueue()和dequeue()是主要的操作函數。
關聯容器類
- 關聯容器類包括QMap,QMultiMap,QHash,QMultiHash,QSet。
- QMultiMap和QMultiHash支持一個鍵關聯多個值,QHash和QMultiHash類使用散列函數進行查找,查找的速度更快。
- QSet是基於散列表的集合模板類,他存儲數據的順序是不定的,查找值的速度非常快。QSet內部就是用QHash實現的。
- QMap<Key,T>提供一個字典,一個鍵映射一個值,QMap存儲數據是按照鍵的順序,如果不在乎存儲順序,使用QHash會更快。
- QMultiMap是map的子類,是用於處理多只映射的便利類。QMa正常情況下是不允許多值映射,除非使用QMap::insertMulti()添加鍵值對。
- QHash是基於散列表來實現字典功能的模板類,QHash<Key,T>存儲的鍵值對具有非常快的查找速度。QHash和QMap,前者比后者的查找速度快;在后者上遍歷時,數據項是按照鍵排序的,而前者的數據項是任意順序的;QMap的鍵必須提供“<”運算符,QHash的鍵必須提供“==”運算符和一個名稱為qHash()的全局散列函數。
- QMultiHash是QHash的子類,是用於處理多只映射的便利類。
容器類的迭代
迭代器(iterator)為訪問容器類里的數據項提供了統一的方法;Qt有兩種迭代器類:Java類型迭代器和STL類型的迭代器。
- Java類型的迭代器更易於使用,且提供了一些高級的功能,而STL類型的迭代器效率更高。
- Qt還提供了一個關鍵字foreach(
里定義的一個宏)用於方便地訪問容器里所有數據項。
Java類型迭代器
對於每個容器類,有兩個java類型迭代器:一個用於只讀操作,一個用於讀寫操作,每個迭代器和容器類的迭代關系如下圖所示:
Java類型的迭代器的指針不是指向下一個數據項,而是在數據項之間。
STL類型迭代器
STL迭代器與Qt和STL的原生算法兼容,並且進行了速度優化,對於每一個容器類,都有兩個STL類型迭代器,一個用於制度訪問,一個用於讀寫訪問,無需修改數據時一定使用制度迭代器,因為速度更快;STL類型迭代器是是數組的指針,所以++運算符使迭代器指向下一個數據項,“*”運算符返回數據項內容。與Java類型迭代器不同,STL迭代器直接指向數據項。STL迭代器類型如下所示:
foreach可以遍歷集合中所有的項
Qt類庫模塊
Qt類庫里大量的類根據功能分為各種模塊,這些模塊又分為幾大類。
- Qt基本模塊:提供Qt在所有平台上的基本功能。
- Qt附加木塊:實現一些特定功能的提供附加價值的模塊。
- 增值模塊:單獨發布的提供額外價值的模塊或工具。
- 技術預覽模塊:一些處於開發階段,但是可以作為技術預覽使用的模塊。
- Qt工具:幫助應用程序開發的一些工具。
QT基本模塊
Qt基本模塊是Qt在所有平台上的基本功能,他們在所有的平台和目標平台上都可以用。具體的模塊如下圖所示:
- Qt Core模塊是Qt類庫的核心,其它所有的模塊都依賴於此模塊,如果是用qmake構建項目,則Qt Core模塊是自動被加入到項目的。
- Qt GUI模塊提供了用於開發GUI應用程序必要的類,使用qmake構建應用程序時,Qt GUI模塊是自動被加入項目的,如果不使用GUI功能,則需要在項目配置文件中加入如下一行:QT -=gui
- 其它模塊一般不會被自動加入到項目中,如果需要在項目中用某個模塊,則可以在項目配置中個添加此模塊,例如Qt Network則需要在配置文件中加入:“QT += network”
Qt附加模塊
Qt附加模塊可以實現一些特定目的,這些模塊可能只能在某些平台上有,或只能用於某些操作系統,或只是為了向后兼容。用戶安裝時可以選擇性的安裝這些附加模塊。Qt附加模塊列表(未烈出一些過時的模塊,以及專門用於QML或QtQuick的模塊)如下圖所示:
Qt增值模塊
除了隨Qt5發布的上述這些模塊,還有一些模塊是單獨發布的,這些模塊只在商業版許可的Qt里才有。
技術預覽模塊
還處於開發和測試階段的模塊。
Qt工具
Qt工具在所有支持的平台上都可以使用,用於幫助應用程序的開發和設計,Qt工具如下圖所示: