精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

QObject中常使用的成員函數和重要宏定義

嵌入式小生 ? 來源:嵌入式小生 ? 2023-02-20 09:42 ? 次閱讀

一、QObject的重要知識

QObject是Qt對象模型的核心。這個模型的核心特性是一個強大的無縫對象通信機制,即信號和槽。可以使用connect()將信號連接到槽函數,并使用disconnect()破壞已經存在的連接。為了避免永不結束的通知循環,可以使用blockSignals()暫時阻塞信號。受保護的函數connectNotify()disconnectNotify()可以用于跟蹤信號連接。

Qt中,以QObject為基礎形成了一棵“對象樹”,當使用另一個對象作為父對象創建QObject時,該對象將自動將自己添加到父對象的children()列表中。此后父對象擁有該對象的所有權,則會自動刪除析構函數中的子元素。在開發中可以使用findChild()findChildren()根據名稱和可選的類型查找子對象。

每個對象都有一個objectName(),可以通過相應的metaObject()找到它的類名(函數:QMetaObject::className())。在實際開發中可以使用inherits()函數確定對象的類是否繼承了QObject繼承層次結構中的另一個類。當一個對象被刪除時,會發出destroyed()信號,通過這一點可以捕獲此信號,避免對QObject進行懸掛引用。

二、QObject重要成員函數

本小節總結在開發中,QObject中常使用的成員函數和重要宏定義。

1、事件獲取和處理API
/*在此對象上安裝事件篩選器filterObj*/
voidQObject::installEventFilter(QObject*filterObj)

/*這個虛擬函數接收對象的事件,如果事件e被識別并處理,則返回true*/
boolQObject::event(QEvent*e)
2、對象的線程關聯API
/*返回對象所在的線程。*/
QThread*QObject::thread()const

/*更改對象及其子對象的線程關聯性。如果一個對象有父對象,則不能移動該對象到另一個線程中*/
voidQObject::moveToThread(QThread*targetThread)

3、獲取子對象API
/*返回該對象具有給定名稱的所有可轉換為類型T的子對象,如果沒有此類對象,則返回一個空列表*/
QListfindChildren(constQString&name=QString(),Qt::FindChildOptionsoptions=Qt::FindChildrenRecursively)const

/*返回子對象列表*/
constQObjectList&children()const
4、qobject_cast

函數原型如下:

Tqobject_cast(QObject*object)
Tqobject_cast(constQObject*object)

如果對象類型為T(或子類),則將給定的對象轉換為類型T;否則返回nullptr。如果對象是nullptr,那么它也將返回nullptr。

注意:類T必須繼承(直接或間接)QObject并使用Q_OBJECT宏聲明。

qobject_cast()函數的行為類似于標準c++ dynamic_cast(),它的優點是不需要RTTI(Run-Time Type Identification-運行時類型識別)支持,并且可以跨動態庫邊界工作。

5、事件處理相關函數
//此虛函數用于接收對象的事件,如果事件e被識別和處理,則返回true。
virtualboolevent(QEvent*e)

//如果此對象已作為被監視對象的事件過濾器安裝,則過濾事件。
virtualbooleventFilter(QObject*watched,QEvent*event)

//從該對象中移除事件篩選器對象obj。
voidremoveEventFilter(QObject*obj)

//在對象上安裝事件篩選器filterObj
voidinstallEventFilter(QObject*filterObj)
6、定時器相關函數
//啟動計時器并返回計時器標識符
intstartTimer(intinterval,Qt::TimerTypetimerType=Qt::CoarseTimer)

//啟動計時器并返回計時器標識符
intstartTimer(std::millisecondstime,Qt::TimerTypetimerType=Qt::CoarseTimer)

//使用定時器標識符id終止計時器
voidkillTimer(intid)
7、重要宏定義
  • Q_DISABLE_COPY(Class)

    禁止對給定類使用復制構造函數和賦值運算符。

  • Q_DISABLE_COPY_MOVE(Class)

該宏用于禁用給定類的復制構造函數、賦值運算符、移動構造函數和移動賦值運算符,將Q_DISABLE_COPYQ_DISABLE_MOVE組合在一起。

  • Q_DISABLE_MOVE(Class 5.13)

禁止對給定類使用移動構造函數和移動賦值操作符。

  • Q_EMIT

當希望使用第三方信號/槽函數機制來使用Qt信號和槽函數時,可以使用此宏替代emit關鍵字來發出信號。

  • Q_ENUM(...)

這個宏用于向元對象系統注冊一個枚舉類型。該宏必須放在enum聲明之后,且放在具有Q_OBJECTQ_GADGET宏的類中。對于命名空間,應該使用Q_ENUM_NS()。例如:

classMyClass:publicQObject
{
Q_OBJECT

public:
MyClass(QObject*parent=nullptr);
~MyClass();

enumPriority{High,Low,VeryHigh,VeryLow};
Q_ENUM(Priority)
voidsetPriority(Prioritypriority);
Prioritypriority()const;
};
  • Q_ENUM_NS(...)

這個宏向元對象系統注冊一個枚舉類型。它必須放在enum聲明之后,,且具有Q_NAMESPACE宏的名稱空間中。與Q_ENUM相同,但在命名空間中。

  • Q_FLAG(...)

這個宏向元對象系統中注冊一個單標記類型。它通常用于類定義中,以聲明給定enum的值可以用作標志,并使用按位或運算符進行組合。對于命名空間,應該使用Q_FLAG_NS()。例如:

classQLibrary:publicQObject
{
Q_OBJECT

public:
...

enumLoadHint{
ResolveAllSymbolsHint=0x01,
ExportExternalSymbolsHint=0x02,
LoadArchiveMemberHint=0x04
};
Q_DECLARE_FLAGS(LoadHints,LoadHint)
Q_FLAG(LoadHint)
...
}
  • Q_INTERFACES(...)

這個宏告訴Qt這個類實現了哪些接口。在宏定義在實現插件的時候使用。例如:

classBasicToolsPlugin:publicQObject,
publicBrushInterface,
publicShapeInterface,
publicFilterInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID"org.qt-project.Qt.Examples.PlugAndPaint.BrushInterface"FILE"basictools.json")
Q_INTERFACES(BrushInterfaceShapeInterfaceFilterInterface)

public:
...
};
  • Q_NAMESPACE

Q_NAMESPACE宏用于將QMetaObject功能添加到名稱空間。Q_NAMESPACE可以有Q_CLASSINFOQ_ENUM_NS、Q_FLAG_NS,但不能有Q_ENUMQ_FLAGQ_PROPERTYQ_INVOKABLE、信號或槽函數。

  • Q_NAMESPACE_EXPORT(EXPORT_MACRO)

該宏的工作原理Q_NAMESPACE宏完全相同。但是,在名稱空間中定義的外部staticMetaObject變量是用提供的EXPORT_MACRO限定符聲明的。如果需要從動態庫導出對象,該宏定義非常有用。

  • Q_OBJECT

Q_OBJECT宏必須出現在類定義的私有部分中,該類定義聲明自己的信號和槽函數,或者使用Qt元對象系統提供的其他支持。

  • Q_PROPERTY(...)

此宏用于在繼承QObject的類中聲明屬性。屬性的行為類似于類數據成員,但它們具有可通過元對象系統訪問的其他特性。如下代碼:

Q_PROPERTY(typename
(READgetFunction[WRITEsetFunction]|
MEMBERmemberName[(READgetFunction|WRITEsetFunction)])
[RESETresetFunction]
[NOTIFYnotifySignal]
[REVISIONint]
[DESIGNABLEbool]
[SCRIPTABLEbool]
[STOREDbool]
[USERbool]
[CONSTANT]
[FINAL])
  • Q_SIGNAL

這是一個額外的宏,允許我們將單個函數標記為信號。當使用不支持信號或Q_SIGNALS組的第三方源代碼解析器時,使用這個宏。

  • Q_SLOT

這是一個額外的宏,它允許將單個函數標記為槽函數。當使用不支持槽函數或Q_SLOT組的第三方源代碼解析器時,使用這個宏。

三、信號和槽的連接機制注意事項

1、【自動連接(默認)】如果信號是在接收對象具有關聯的線程中發出的,那么行為與直接連接相同。否則,行為與隊列連接相同。

2、【直接連接】當信號發出時,槽函數被立即調用。槽函數在發射器的線程中執行,而發射器的線程不一定是接收器的線程。

3、【隊列連接】當控制返回到接收方線程的事件循環時調用槽,槽函數在接收方的線程中執行。

4、【阻塞排隊連接】槽被調用為排隊連接,除非當前線程阻塞直到槽函數返回。

注意:使用該阻塞排隊連接類型連接同一線程中的對象將導致死鎖。

5、【唯一連接】與自動連接相同,但只在不復制現有連接的情況下才建立連接。也就是說,如果相同的信號已經為相同的對象連接到相同的槽,那么就不創建連接,并且connect()返回false

連接類型可以通過向connect()傳遞一個附加參數來指定。注意,如果事件循環運行在接收方的線程中,當發送方和接收方位于不同線程中時使用直接連接是不安全的,這與調用位于另一個線程中的對象上的函數是不安全的原因相同。

QObject::connect()本身是線程安全的。

對于隊列連接,傳遞的參數必須是Qt元對象系統已知的類型,因為Qt需要復制參數,以便存儲參數;如果參數類型不是Qt元對象系統已知的,使用隊列連接,將獲得錯誤提示信息,這時候則需要在創建連接之前,調用qRegisterMetaType()向元對象系統注冊該數據類型。

四、線程關聯性

在Qt中,QObject實例具有線程相關性,或者可以理解成QObject存在于某個線程中。當QObject接收到排隊的信號或發布的事件時,槽函數或事件處理程序將在該對象所在的線程中運行,這一點很重要。

注意:如果一個QObject沒有線程關聯(也就是說,如果thread()返回0),或者如果它存在于一個沒有運行事件循環的線程中,那么它就不能接收排隊的信號或發布的事件。

默認情況下,QObject實例存在于創建它的線程中,在實際開發中可使用thread()查詢對象的線程關聯,并使用moveToThread()更改對象的線程關聯。

注意:所有QObject必須與它們的父對象生活在同一個線程中。除此之外,還需要知道:

(1)如果涉及的兩個QObject位于不同的線程中,setParent()將失敗。

(2)當一個QObject被移動到另一個線程時,它的所有子線程也會被自動移動。

(3)如果QObject有一個父對象,moveToThread()將失敗。

(4)如果QObject是在QThread::run()中創建的,它們不能成為QThread對象的子對象,因為QThread并不存在于調用QThread::run()的線程中。

QObject的父子關系必須通過傳遞一個指向子構造函數的指針或調用setParent()來設置。如果沒有這個步驟,當調用moveToThread()時,對象的成員變量將保持在舊線程中。

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • API
    API
    +關注

    關注

    2

    文章

    1485

    瀏覽量

    61814
  • 函數
    +關注

    關注

    3

    文章

    4304

    瀏覽量

    62429
  • Qt
    Qt
    +關注

    關注

    1

    文章

    301

    瀏覽量

    37829

原文標題:Qt的萬能承載者QObject,了解多少?

文章出處:【微信號:嵌入式小生,微信公眾號:嵌入式小生】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    C語言定義使用技巧

    寫好C語言,漂亮的定義重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性等等。下面列舉一些成熟軟件
    發表于 07-29 09:35 ?1100次閱讀

    C語言中常用的定義

    寫好C語言,漂亮的定義重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性等等。下面列舉一些成熟軟件
    發表于 10-18 10:05 ?1655次閱讀

    C語言中定義的應用

    在C語言中,定義是一種預處理指令,用于在代碼中定義和使用常量、函數或代碼片段的替代。
    發表于 08-17 15:33 ?755次閱讀

    C編程定義函數該如何修改?

    那么該如何修改呢?不希望寫成函數形式的,寫成定義形式的比較好。
    發表于 12-26 08:51

    c語言中常用的定義有哪些?

    c語言中常用的定義有哪些?
    發表于 04-28 06:01

    C語言定義使用技巧

    寫好C語言,漂亮的定義重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性 等等。下面列舉一些成熟軟件
    發表于 11-13 12:04 ?36次下載

    內聯函數定義的區別介紹

    定義是C語言提供的三種預處理功能的其中一種,這三種預處理包括:定義、文件包含、條件編譯。定義
    發表于 12-15 15:33 ?2332次閱讀
    內聯<b class='flag-5'>函數</b>和<b class='flag-5'>宏</b><b class='flag-5'>定義</b>的區別介紹

    定義 “中斷函數接口”的注意事項

    定義“中斷函數接口”的注意事項
    的頭像 發表于 03-07 16:42 ?2480次閱讀

    ARM Linux中一些重要及地址定義

    ARM Linux中一些重要及地址定義
    的頭像 發表于 06-22 17:02 ?2699次閱讀

    一些成熟軟件中常用的定義

    寫好C語言,漂亮的定義重要,使用定義可以防止出錯,提高可移植性,可讀性,方便 性等等。 下面列舉一些成熟軟件
    的頭像 發表于 01-18 11:21 ?2336次閱讀

    C語言定義與預處理、函數函數

    目錄前言一、C語言預處理二、定義三、函數四、函數庫五、自己制作靜態鏈接庫(ubuntu 環境下,即使用Linux系統平臺上的gcc)六、自己制作動態鏈接庫(ubuntu 環境下,即使
    發表于 12-07 21:06 ?2次下載
    C語言<b class='flag-5'>宏</b><b class='flag-5'>定義</b>與預處理、<b class='flag-5'>函數</b>和<b class='flag-5'>函數</b>庫

    類的申明和成員函數定義分離是什么

    前面我們學習了如何定義類,以及如何使用類的成員,在前面我們把成員函數定義在了類的內部,接下來我們學習,如何把類的
    的頭像 發表于 02-27 15:33 ?884次閱讀

    C語言函數封裝技巧分享

    函數,即包含多條語句的定義,其通常為某一被頻繁調用的功能的語句封裝,且不想通過函數方式封裝來降低額外的彈棧壓棧開銷。
    的頭像 發表于 09-14 09:31 ?608次閱讀

    列舉一些C語言中常用的定義

    寫好C語言,使用定義可以防止出錯,提高可移植性、可讀性等。下文列舉一些成熟軟件中常用的定義
    發表于 10-07 10:54 ?524次閱讀
    列舉一些C語言<b class='flag-5'>中常</b>用的<b class='flag-5'>宏</b><b class='flag-5'>定義</b>

    C語言中函數定義和用法

    函數是一種特殊的函數,與普通函數不同的是,它可以擁有多條語句和局部變量,從而實現更復雜的功
    發表于 10-11 11:32 ?3327次閱讀
    C語言中<b class='flag-5'>宏</b><b class='flag-5'>函數</b>的<b class='flag-5'>定義</b>和用法