<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

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

3天內不再提示

Qt“靈魂”之Meta-Object系統

嵌入式小生 ? 來源:嵌入式小生 ? 2023-02-10 13:50 ? 次閱讀

一、Meta-Object簡介

Meta-Object即是Qt的元對象系統,下文都以元對象系統進行描述。在Qt中,具有標志性特征的則是信號和槽函數機制,該機制的背后實現本質上則是元對象系統。編寫Qt代碼的時候,在定義類的時候,需要放置一個Q_OBJECT,為什么呢?后文會描述到,例如如下代碼:

f8b5a762-a8dc-11ed-bfe3-dac502259ad0.pngimage-20230207220020441

Q_OBJECT本質上是一個宏定義,在進行Qt開發時,所有QObject的派生類都推薦在頭文件中放置Q_OBJECT宏定義,該宏定義如下(出自qobjectdefs.h文件):

#defineQ_OBJECT
public:
QT_WARNING_PUSH
Q_OBJECT_NO_OVERRIDE_WARNING
staticconstQMetaObjectstaticMetaObject;
virtualconstQMetaObject*metaObject()const;
virtualvoid*qt_metacast(constchar*);
virtualintqt_metacall(QMetaObject::Call,int,void**);
QT_TR_FUNCTIONS
private:
Q_OBJECT_NO_ATTRIBUTES_WARNING
Q_DECL_HIDDEN_STATIC_METACALLstaticvoidqt_static_metacall(QObject*,QMetaObject::Call,int,void**);
QT_WARNING_POP
structQPrivateSignal{};
QT_ANNOTATE_CLASS(qt_qobject,"")

Qt中,元對象系統包含了支持元對象系統的程序,宏定義,基類,接口函數。這些東西共同構成了Qt的元對象系統:

(1)QObject為想要使用元對象系統的對象提供了基類。

(2)Q_OBJECT宏用于啟動元對象特性,例如:動態屬性、信號和槽函數機制等。

(3)元對象編譯器(moc)為每個QObject子類生成實現元對象特性所需要的代碼。

在實際Qt程序設計中,在派生自QObject的類定義中加上Q_OBJECT后,則可以使用元對象系統所支持的特性了。

二、元對象系統背后機制

如果在派生自QObject的類定義中加上了Q_OBJECT后,在編譯構建過程中,元對象系統的moc工具(本文以Windows平臺為例,該工具則位于具體Qt版本目錄下的bin目錄中)

f8cd9250-a8dc-11ed-bfe3-dac502259ad0.png

在Windows命令行下運行,可獲知如下信息

f8f59df4-a8dc-11ed-bfe3-dac502259ad0.png

在QtCreator集成開發環境中,當點擊構建按鈕后,QtCreator會自動調用moc工具,該工具會讀取一個C++源文件,如果它發現一個或多個包含Q_OBJECT宏的類聲明,那么則會生成另外一個C++源文件,源文件中包含每個類的元對象代碼。接著,生成的源文件要么被#include包含到類的源文件中,要么被編譯并鏈接到類的實現中。例如下列一個簡單的項目工程,源碼結構如下:

f91d39cc-a8dc-11ed-bfe3-dac502259ad0.png

從上圖可知,工程中包含了一個main.cpp、一個主窗口描述文件mainwindow.cpp/.h、一個stylesheeteditor.cpp/.h文件,由于mainwindow.cpp/.h、stylesheeteditor.cpp/.h支持Qt的元對象系統,在編譯構建過程中,則會生成支持元對象系統的中間文件,如下圖所示:

f9334500-a8dc-11ed-bfe3-dac502259ad0.png

從上圖可知,這些文件都以moc_xxx方式進行命名,最后結合其他的文件生成了程序可執行體(stylesheet.exe),整個過程可如下圖所示(Windows平臺):

f93fbf6a-a8dc-11ed-bfe3-dac502259ad0.png

三、再談元對象系統

除了提供對象之間通信的信號和槽函數機制(這是引入該系統的主要原因),元對象系統還提供以下的功能:

(1)Object::metaObject():返回類的關聯元對象。

(2)QMetaObject::className():在運行時以字符串的形式返回類名,而不需要通過C++編譯器提供本地運行時類型信息(RTTI)支持。

(3)QObject::inherits():函數返回一個對象是否是在QObject繼承樹中繼承指定類實例。

(4)QObject::tr()和QObject::trUtf8()為國際化翻譯字符串。

(5)QObject::setProperty()和QObject::property()根據名稱動態設置和獲取屬性。

(6)QMetaObject::newInstance():構造類的新實例。

除了上述所列的功能,還可以使用qobject_cast()對QObject類執行動態強制類型轉換,qobject_cast()函數的行為類似于標準C++ 的dynamic_cast(),它的優點是不需要RTTI支持,并且可以跨動態庫工作。該函數嘗試將其參數轉換為尖括號中指定的指針類型,如果對象的類型正確(在運行時確定),則返回非零指針;如果對象的類型不兼容,則返回nullptr。

例如,假設有一個MyWidget繼承自QWidget,并使用了Q_OBJECT宏聲明,然后使用new創建該實例:

QObject*obj=newMyWidget;

類型為QObject *的obj變量實際上引用了一個MyWidget對象,所以我們可以對它進行適當的類型轉換,如下代碼:

QWidget*widget=qobject_cast(obj);

從QObject到QWidget的轉換是成功的,因為該對象實際上是一個MyWidget,它是QWidget的一個子類。既然知道obj是一個MyWidget,我們也可以將它cast到MyWidget *,如下代碼:

MyWidget*myWidget=qobject_cast(obj);

上述代碼對MyWidget的轉換是也成功的,因為qobject_cast()在內置Qt類型和自定義類型之間沒有區別。

然而對于下列代碼:

QLabel*label=qobject_cast(obj);

對QLabel的強制轉換將失敗,會將指針設置為0。因此可以在運行時處理不同類型的對象,例如:

if(QLabel*label=qobject_cast(obj))
{
label->setText(tr("iriczhao"));
}
elseif(QPushButton*button=qobject_cast(obj))
{
button->setText(tr("嵌入式小生"));
}

上述代碼使用qobject_case()對obj進行了向QLabel和QPushButton的強制轉換,如果轉換成功,則設置對應的顯示文本。

四、小生總結

在實際Qt開發過程中,雖然可以在沒有Q_OBJECT宏和元對象代碼的情況下將QObject作為基類,但如果沒有使用Q_OBJECT宏,則信號和槽函數機制或在本文中描述的其他特性都不能使用。從元對象系統的角度來看,一個沒有元代碼的QObject子類等價于它最近的有元對象代碼的祖先。這意味著,例如,QMetaObject::className()將不會返回自己類的實際名稱,而是這個祖先的類名稱。

因此,在實際Qt開發過程中,無論實際上是否使用了信號和槽函數機制,都強烈建議QObject的所有子類都使用Q_OBJECT宏。

審核編輯:湯梓紅

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

    關注

    3

    文章

    3882

    瀏覽量

    61310
  • 代碼
    +關注

    關注

    30

    文章

    4556

    瀏覽量

    66784
  • Meta
    +關注

    關注

    0

    文章

    164

    瀏覽量

    11180
  • 編譯器
    +關注

    關注

    1

    文章

    1577

    瀏覽量

    48621
  • Qt
    Qt
    +關注

    關注

    1

    文章

    299

    瀏覽量

    37340

原文標題:Qt“靈魂”之Meta-Object系統

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

收藏 人收藏

    評論

    相關推薦

    【AWorks試用體驗】學習筆記(3)一個關于 Qt 的 demo

    器。Qt是面向對象的框架,使用特殊的代碼生成擴展(稱為元對象編譯器(Meta Object Compiler, moc))以及一些宏,易于擴展,允許組件編程。2008年,奇趣科技被諾基亞公司收購,
    發表于 09-03 19:51

    做儀表的,用qt怎么做的?

    fsl-imx-fb-glibc-x86_64-meta-toolchain-qt5-cortexa9hf-neon-toolchain-4.1.15-2.1.0報錯:/mnt/hgfs/zlmQtAPP/opengl/hellowindow/hellowindow.h:86: error
    發表于 12-21 10:22

    qt creator編譯QT5應用

    +xfsl-imx-fb-glibc-x86_64-meta-toolchain-qt
    發表于 05-05 15:17

    如何對meta-toolchain-qt5進行bitbake?

    大家好,我設法在我的 STM32MP157C-DK2 上構建了具有一些額外圖像功能的 st-example-image-qt?,F在我只想運行 bitbake meta-toolchain-qt5 但構建最終會出現我無法解決的錯誤。當我嘗試構建它時,我附上了輸出控制臺。你知
    發表于 02-07 10:14

    Qt 跨平臺C++圖形用戶界面應用程序開發框架

    的代碼生成擴展(稱為元對象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴展,并且允許真正地組件編程。
    發表于 03-28 21:03

    Yocto添加meta-webkit層時出現do_compile錯誤怎么解決?

    大家好,我正在研究 VAR-SOM IMX8,我正在構建 Qt5 圖像,yocto 版本是dunfell-fslc-5.4-2.1.x-mx8-v1.5。當我嘗試將 meta-webkit 層添加到
    發表于 03-30 07:45

    【米爾MYD-JX8MMA7開發板-ARM+FPGA架構試用體驗】十一、QT-HMI V2.0系統

    代碼進行方便的交互,使用起來非常方便。QMl是一種高效的開發UI 的語言。QML(Qt Meta-Object Language,Qt元對象語言)是一種聲明式編程語言,并且它是Qt框架
    發表于 05-23 09:34

    bitbake imx-image-full時出現qt6錯誤怎么解決?

    /imx-yocto-bsp/sources/meta-qt6/recipes-qt/qt6/qtbase_git.bb: do_compile) 失敗,退出代碼為“1” 有什么辦法可以解決這個問題嗎?謝謝
    發表于 05-29 08:11

    Java Object Serialization Spec

    Java Object Serialization SpecificationObject serialization in the Java™system is the process
    發表于 10-14 17:39 ?7次下載

    什么是CORBA (Common Object Reques

    什么是CORBA (Common Object Request Broker Architecture)  英文縮寫: CORBA (Common Object Request Broker Architecture) 中文譯名: 通用對象請求
    發表于 02-22 11:48 ?888次閱讀

    qt4圖形設計與嵌入式開發

    生成擴展(稱為元對象編譯器(meta object Compiler moc))以及一些宏,易于擴展,允許組件編程。
    發表于 11-18 16:59 ?10次下載

    基于ARM和Qt的液氨罐區監控系統的設計_婁海強

    基于ARM和Qt的液氨罐區監控系統的設計_婁海強
    發表于 02-07 18:11 ?1次下載

    物聯網軟件系統中的關鍵和靈魂是什么

    RFID中間件是物聯網軟件系統中的關鍵和靈魂,為解決分布異構問題,人們提出了中間件的概念。
    發表于 11-19 09:29 ?2651次閱讀

    Windows下的QT系統開發環境搭建

    生成擴展(稱為元對象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴展,并且允許真正地組件編程。
    的頭像 發表于 05-17 11:39 ?2265次閱讀
    Windows下的<b class='flag-5'>QT</b><b class='flag-5'>系統</b>開發環境搭建

    Object類中的所有方法

    Object 類屬于 java.lang 包,此包下的所有類在使用時無需手動導入,系統會在程序編譯期間自動導入。Object 類是所有類的基類,當一個類沒有直接繼承某個類時,默認繼承Objec
    的頭像 發表于 10-13 11:50 ?276次閱讀
    <b class='flag-5'>Object</b>類中的所有方法
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>