最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ Qt屬性系統(tǒng)詳細(xì)介紹

 更新時(shí)間:2016年12月14日 09:47:34   投稿:lqh  
這篇文章主要介紹了C++ Qt屬性系統(tǒng)詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下

C++ Qt屬性系統(tǒng)詳細(xì)介紹

Qt提供了一個(gè)絕妙的屬性系統(tǒng)。跟那些由編譯器提供的屬性差不多。然而,作為一個(gè)獨(dú)立于編譯器和平臺(tái)的庫,Qt不依賴于非標(biāo)準(zhǔn)的編譯特性,比如__property 或[property]。Qt可以在任何平臺(tái)上的標(biāo)準(zhǔn)編譯器下編譯。Qt屬性系統(tǒng)基于元數(shù)據(jù)對(duì)象系統(tǒng)--就是那個(gè)提供了對(duì)象內(nèi)置信號(hào)和槽通訊機(jī)制的家伙。

聲明屬性需要什么

要聲明一個(gè)屬性,需在繼承自QObject的類中使用Q_PROPERTY()宏。

Q_PROPERTY(type name
  READ getFunction
  [WRITE setFunction]
  [RESET resetFunction]
  [NOTIFY notifySignal]
  [DESIGNABLE bool]
  [SCRIPTABLE bool]
  [STORED bool]
  [USER bool]
  [CONSTANT]
  [FINAL])


下面是一些典型的聲明屬性的示例:

Q_PROPERTY(bool focus READ hasFocus) 
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) 
Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor) 
  • 一個(gè)屬性的行為就像類的數(shù)據(jù)成員,但是它還具有附加的特性,這些特性可以被元數(shù)據(jù)對(duì)象系統(tǒng)操作。這些特性是:需要一個(gè)READ訪問器函數(shù)。用于讀屬性的值。理想情況下,有一個(gè)不變的函數(shù)用于此目的,并且它必須返回屬性的類型的值或指針或引用。例如,QWidget::focus是一個(gè)只讀的屬性,它對(duì)應(yīng)一個(gè)讀函數(shù):QWidget::hasFocus()。
  • 一個(gè)可選的WRITE訪問器函數(shù)。它用于設(shè)置屬性的值。它必須返回空并且至少具有一個(gè)參數(shù),參數(shù)是屬性類型的值或指針或引用。例如:QWidget::enabled具有WRITE函數(shù)QWidget::setEnable()。只讀屬性不需要寫函數(shù)。例如,QWidget::focus沒有對(duì)應(yīng)的寫函數(shù)。
  • 一個(gè)可選的RESET函數(shù)。用于設(shè)置屬性的值到它的默認(rèn)值。例如:QWidget::cursor具有典型的READ和WRITE函數(shù),QWidget::cursor()和QWidget::setCursor(),并且它也具有一個(gè)RESET函數(shù),QWidget::unsetCursor()。RESET函數(shù)必須返回void并且不帶有任何參數(shù)。
  • 一個(gè)可選的NOTIFY信號(hào)。如果被定義了,信號(hào)將在屬性的值改變時(shí)發(fā)出。信號(hào)必須帶有一個(gè)參數(shù),這個(gè)參數(shù)的類型必須與屬性相同;參數(shù)保存的是屬性的新值。
  • 一個(gè)DESIGNABLE變量表明此屬性是否在界面設(shè)計(jì)器的屬性編輯器中出現(xiàn)。大多數(shù)屬性是可見的,除了為這個(gè)變量傳入true或false,你還可以指定一個(gè)bool型的成員函數(shù)。
  • SCRIPTABLE變量表明這個(gè)屬性是否可以被一個(gè)腳本引擎操作(默認(rèn)是true)。你也可以賦予它true或false或bool型函數(shù)。
  • STORED變量表明了屬性是否被認(rèn)為是獨(dú)立存在還是依賴于其它的值而存在。它也表明是否在保存對(duì)象狀態(tài)時(shí)保存此屬性的值。大多數(shù)屬性都是需要保存的,但是,如QWidget::minimumWidth()就是不被保存的,因?yàn)樗闹凳菑牧硪粋€(gè)屬性QWidget::minimumSize()得來的。
  • USER變量表明屬性是否被設(shè)計(jì)為面向用戶的或用戶可修改的類屬性。通常,每個(gè)類只有一個(gè)USER屬性。例如,QAbstractButton::checked是按鈕類的用戶可修改屬性。注意QItemDelegate獲取和設(shè)置widget的USER屬性。
  • CONSTANT的出現(xiàn)表明屬性的值是不變的。對(duì)于一個(gè)object實(shí)例,常量屬性的READ方法在每次被調(diào)用時(shí)必須返回相同的值。此常量值可能在不同的object實(shí)例中不相同。一個(gè)常量屬性不能具有WRITE方法或NOYIFY信號(hào)。
  • FINAL變量的出現(xiàn)表明屬性不能被派生類所重寫。有些情況下,這可以用于效率優(yōu)化,但不是被moc強(qiáng)制的。程序員必須永遠(yuǎn)注意不能重寫一個(gè)FINAL屬性。

 READ,WRITE和RESET函數(shù)都可以被繼承。它們也可以是虛函數(shù)。當(dāng)它們?cè)诒欢嘀乩^承中被繼承時(shí),它們必須出現(xiàn)在第一個(gè)被繼承的類中。

屬性的類型可以是被QVariant支持的所有類型,也可以是用戶定義的類型。在下面的例子中,類QDate被當(dāng)作用戶自定義類型。
Q_PROPERTY(QDate data READ getDate WRITE setDate)

因?yàn)镼Date是用戶定義的,你必須包含<QDate>頭文件。

對(duì)于QMap,QList和QValueList屬性,屬性的值是一個(gè)QVariant,它包含整個(gè)list或map。注意Q_PROPERTY字符串不能包含逗號(hào),因?yàn)槎禾?hào)會(huì)劃分宏的參數(shù)。因此,你必須使用QMap作為屬性的類型而不是QMap<QString,QVariant>。為了保持一致性,也需要用QList和QValueList而不是QList<QVariant>和QValueList<QVariant>。

 通過元數(shù)據(jù)對(duì)象系統(tǒng)讀寫屬性

一個(gè)屬性可以使用常規(guī)函數(shù)QObject::property()和QObject::setProperty()進(jìn)行讀寫,不用知道屬性所在類的任何細(xì)節(jié),除了屬性的名字。在下面的小代碼片段中,調(diào)用QAbstractButton::setDown()和QObject::setProperty()都把屬性設(shè)置為“down”。

QPushButton *button = new QPushButton; 
QObject *object = button; 
button->setDown(true); 
object->setProperty("down", true); 

通過WRITE操作器來操作一個(gè)屬性是上面兩者中更好的,因?yàn)樗觳⑶以诰幾g時(shí)給于更好的診斷幫助,但是以這種方式設(shè)置屬性要求你必須在編譯時(shí)了解其類。通過名字來操作屬性使你可以操作在編譯器你不了解的類。你可以在運(yùn)行時(shí)發(fā)現(xiàn)一個(gè)類的屬性們,通過查詢它的QObject,QMetaObject和QMetaProerties。

QObject *object = ... 
const QMetaObject *metaobject = object->metaObject(); 
int count = metaobject->propertyCount(); 
for (int i=0; i<count; ++i) { 
  QMetaProperty metaproperty = metaobject->property(i); 
  const char *name = metaproperty.name(); 
  QVariant value = object->property(name); 
  ... 
} 

在上面的代碼片段中,QMetaObject::property()被用于獲取未知類中的屬性的metadata。從metadata中獲取屬性名然后傳給QObject::property()來獲取

一個(gè)簡單例子

假設(shè)我們有一個(gè)類MyClass,它從QObject派生并且在它的private區(qū)使用 了Q_OBJECT宏。我們想在MyClass類中聲明一個(gè)屬性來持續(xù)追蹤一個(gè)Priorty值。屬性的值叫做priority,并且它的類型是一個(gè)在類MyClass中定義的叫做Priority的枚舉。

我們?cè)陬惖膒rivate區(qū)使用Q_PROPERTY()來聲明屬性。READ函數(shù)叫做priority,并且我們包含一個(gè)WRITE函數(shù)叫做setPriority。枚舉類型必須使用Q_ENUMS()注冊(cè)到元數(shù)據(jù)對(duì)象系統(tǒng)中。注冊(cè)一個(gè)枚舉類型使得枚舉的名字可以在調(diào)用QObject::setProperty()時(shí)使用。我們還必須為READ和WRITE函數(shù)提供我們自己的聲明。MyClass的聲明看起來應(yīng)該是這樣的:

class MyClass : public QObject 
{ 
  Q_OBJECT 
  Q_PROPERTY(Priority priority READ priority WRITE setPriority) 
  Q_ENUMS(Priority) 
public: 
  MyClass(QObject *parent = 0); 
  ~MyClass(); 
  enum Priority { High, Low, VeryHigh, VeryLow }; 
  void setPriority(Priority priority); 
  Priority priority() const; 
}; 

READ函數(shù)是const的并且返回屬性的類型。WRITE函數(shù)返回void并且具有一個(gè)屬性類型的參數(shù)。元數(shù)據(jù)對(duì)象編譯器強(qiáng)制做這些事情。

在有了一個(gè)指向MyClass實(shí)例的指針時(shí),我們有兩種方法來設(shè)置priority屬性:

MyClass *myinstance = new MyClass; 
 QObject *object = myinstance; 
 myinstance->setPriority(MyClass::VeryHigh); 
 object->setProperty("priority", "VeryHigh"); 

在此例子中,枚舉類型在MyClass中聲明并被使用Q_ENUMS()注冊(cè)到元數(shù)據(jù)對(duì)象系統(tǒng)中。這使得枚舉值可以在調(diào)用setProperty()時(shí)做為字符串使用。如果枚舉類型是在其它類中聲明的,那么我們就需要用枚舉的全名(如OtherClass::Priority),并且這個(gè)其它類也必須從QObject中派生并且也要注冊(cè)枚舉類型。

另一個(gè)簡單的Q_FLAGS()也是可用的。就像Q_ENUMS(),它注冊(cè)一個(gè)枚舉類型,但是它把枚舉類型作為一個(gè)flag的集合,也就是,值可以用OR操作來合并。一個(gè)I/O類可能具有枚舉值Read和Write并且QObject::setProperty()可以接受 Read|Write。此時(shí)應(yīng)使用Q_FLAGS()來注冊(cè)枚舉值。

動(dòng)態(tài)屬性

Qobject::setProperty()也可以用來在運(yùn)行時(shí)向一個(gè)類的實(shí)例添加新的屬性。當(dāng)使用一個(gè)名字和值調(diào)用它時(shí),如果一個(gè)對(duì)應(yīng)的屬性已經(jīng)存在,并且如果值的類型與屬性的類型兼容,那么值就被存儲(chǔ)到屬性中,然后返回true。如果值類型不兼容,屬性的值就不會(huì)發(fā)生改變,就會(huì)返回false。但是如果對(duì)應(yīng)名字的屬性不存在,那么一個(gè)新的屬性就誕生了,以傳入的名字為名,以傳入的值為值,但是依然會(huì)返回false。這表示返回值不能用于確定一個(gè)屬性是否被設(shè)置值,除非你已經(jīng)知道這個(gè)屬性已經(jīng)存在于QObject中了。

注意動(dòng)態(tài)屬性被添加到單個(gè)實(shí)現(xiàn)的基礎(chǔ)中,也就是,被添加到QObject,而不是QMetaObject。一個(gè)屬性可以從一個(gè)實(shí)例中刪除,通過傳入屬性的名字和非法的QVariant值給QObject::setProperty()。默認(rèn)的QVariant構(gòu)造器構(gòu)造一個(gè)非法的QVariant。
動(dòng)態(tài)屬性可用QObject::property()來查詢,就行使用Q_PROPERTY()聲明的屬性一樣。

屬性和自定義類型

被屬性使用的自定義類型需要使用Q_DECLARE_METATYPE()宏注冊(cè),以使它們的值能被保存在QVariant對(duì)象中。這使得它們可以用于被Q_PROPERTY()聲明的靜態(tài)類型中,也可以被用于動(dòng)態(tài)類型中。

 感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • C++11如何實(shí)現(xiàn)無鎖隊(duì)列

    C++11如何實(shí)現(xiàn)無鎖隊(duì)列

    這篇文章主要介紹了C++11如何實(shí)現(xiàn)無鎖隊(duì)列,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • 深入解析C++中的auto自動(dòng)類型推導(dǎo)

    深入解析C++中的auto自動(dòng)類型推導(dǎo)

    C++標(biāo)準(zhǔn)委員會(huì)在C++11標(biāo)準(zhǔn)中改變了auto關(guān)鍵字的語義,使它變成一個(gè)類型占位符,允許在定義變量時(shí)不必明確寫出確切的類型,讓編譯器在編譯期間根據(jù)初始值自動(dòng)推導(dǎo)出它的類型,下面我們就來看看auto自動(dòng)類型推導(dǎo)的推導(dǎo)規(guī)則吧
    2024-04-04
  • VSCode插件開發(fā)全攻略之package.json詳解

    VSCode插件開發(fā)全攻略之package.json詳解

    這篇文章主要介紹了VSCode插件開發(fā)全攻略之package.json的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Qt與QWebEngineView交互完整參考示例代碼

    Qt與QWebEngineView交互完整參考示例代碼

    QWebEngineView是Qt框架中的一個(gè)組件,它是基于Chromium內(nèi)核的Web瀏覽器引擎,用于在Qt應(yīng)用程序中嵌入網(wǎng)頁內(nèi)容和實(shí)現(xiàn)各種Web應(yīng)用功能,這篇文章主要給大家介紹了關(guān)于Qt與QWebEngineView交互完整參考的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • 通過c++的sort函數(shù)實(shí)現(xiàn)成績排序功能

    通過c++的sort函數(shù)實(shí)現(xiàn)成績排序功能

    這篇文章主要介紹了通過c++的sort函數(shù)實(shí)現(xiàn)成績排序,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 關(guān)于c語言指針的兩處小tip分享

    關(guān)于c語言指針的兩處小tip分享

    本篇文章是對(duì)c語言中指針的兩處小tip進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 基于WTL 雙緩沖(double buffer)繪圖的分析詳解

    基于WTL 雙緩沖(double buffer)繪圖的分析詳解

    本篇文章是對(duì)WTL下使用雙緩沖(double buffer)繪圖進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言的遞歸思想實(shí)例分析

    C語言的遞歸思想實(shí)例分析

    這篇文章主要介紹了C語言的遞歸思想,以一個(gè)實(shí)例的形式針對(duì)數(shù)據(jù)變化規(guī)律分析了遞歸思想的本質(zhì),需要的朋友可以參考下
    2014-09-09
  • 嵌入式C語言輕量級(jí)程序架構(gòu)內(nèi)核編寫

    嵌入式C語言輕量級(jí)程序架構(gòu)內(nèi)核編寫

    這篇文章主要介紹了嵌入式C語言輕量級(jí)程序架構(gòu)內(nèi)核編寫,文章將讓大家學(xué)到輕量級(jí)程序架構(gòu)的內(nèi)核實(shí)現(xiàn)原理、輕量級(jí)程序架構(gòu)的設(shè)計(jì)思想、了解單片機(jī)常用的程序架構(gòu)等更多C語言輕量級(jí)程序架構(gòu)相關(guān)內(nèi)容,需要的朋友可以參考一下
    2022-03-03
  • c++中new和delete操作符用法

    c++中new和delete操作符用法

    c++中new和delete運(yùn)算符是用于動(dòng)態(tài)分配和撤銷內(nèi)存的運(yùn)算符,下面是示例,大家參考使用吧
    2014-04-04

最新評(píng)論

扶风县| 本溪市| 鄂州市| 德惠市| 福贡县| 宜兰县| 会同县| 桂林市| 筠连县| 桐梓县| 蓬安县| 大英县| 邓州市| 商城县| 南靖县| 兰州市| 措勤县| 论坛| 青龙| 芷江| 呼图壁县| 乌兰浩特市| 平顺县| 台北县| 金沙县| 东乡县| 静安区| 靖宇县| 西吉县| 开封县| 永清县| 秦安县| 德钦县| 尤溪县| 阿克| 张掖市| 临安市| 铜川市| 柘城县| 台湾省| 江孜县|