簡單介紹Qt的屬性子系統

深入理解Qt的屬性系統

? 筆者最近正在大規模的開發Qt的項目和工程,這里筆者需要指出的是,這個玩意在最常規的Qt開發中是相對比較少用的,筆者也只是在Qt的QPropertyAnimation需要動畫感知筆者設置的一個屬性的時候方才知道這個東西的。因此,這篇文章的屬性更加象是整合和消化,請各位Qt大佬批評指正。

先說說Qt的屬性系統可以做啥

? 我不想一上來就扔出來一大堆概念和寫法,這沒意思,看著啥也看不懂就來整一處,只會把人嚇跑。

更加高級的和封閉的屬性讀寫機制(C++的反射和動態屬性)

? 在純 C++ 環境下,通過 QObject::setProperty 和 QObject::property,開發者可以在不知道具體類定義的情況下,以字符串形式讀寫對象屬性,從而實現對第三方或未知類型對象的動態操作,這在插件系統或運行時配置中尤為有用。如果需要在不同線程之間安全地調用方法,也可以借助 QMetaObject::invokeMethod 配合 Qt::QueuedConnection,將對屬性的修改或方法調用排入目標線程的事件隊列,從而避免手動管理互斥鎖和死鎖風險。這個就是把對對象屬性的修改扔到巨大的事件循環隊列中,事件循環隊列是保證我們的數據讀寫不會發生爭奪,必須按照順序一個個執行的。

UI 自動化與 Qt Designer 集成

? Qt Designer 以及 Qt Quick Designer 均依賴元對象系統和屬性系統來生成可視化屬性面板。無論是 QWidget 還是 QML 項目,當在設計器中選中控件時,右側屬性編輯器都會列出該控件所有可設計屬性,包括可腳本化(SCRIPTABLE)和可存儲(STORED)的屬性,通過動態讀取 QMetaObject 數據實現即時更新和回顯,這為界面原型設計和主題定制提供了極大便利。這個事情在筆者之后體驗如何自己制作自己的插件的時候會進行嘗試。

QML 中的數據綁定與模型驅動(這個沒做過,gpt這樣說的)

在 QML 層面,屬性系統是響應式界面的基石。將 C++ 對象通過 QQmlContext 或 qmlRegisterType 暴露給 QML 時,凡是使用 Q_PROPERTY 宏聲明并帶有 NOTIFY 信號的屬性,都可以在 QML 中像普通屬性一樣使用綁定表達式。當模型層的屬性在 C++ 側被修改時,對應的 QML 界面會自動更新,無需手動編寫額外的同步代碼,這使得使用 Qt Quick 構建數據驅動型界面變得直觀而高效。即便是在復雜的邏輯場景下,QML 引擎也會跟蹤屬性的依賴關系,在底層的 BindingEvaluator 中智能地避免多余的計算與重繪,從而兼顧性能和開發效率

動畫、狀態機與屬性驅動

Qt 的動畫框架廣泛使用屬性系統來驅動動畫效果。QPropertyAnimation 類通過屬性名稱來獲取和設置目標對象的屬性值,并在不同時間點上插值更新,例如對 QWidget 的 geometry、opacity 或自定義屬性進行平滑過渡;在狀態機(QStateMachine)中,也可以使用屬性動作(QPropertyAction)根據狀態切換自動修改屬性,從而將動畫與狀態邏輯解耦,簡化狀態驅動的界面行為實現。這個在筆者自己手搓網易云的動畫效果的時候又遇到過,筆者會在那里詳細的說明這個用途

非常心動,所以咋玩

? 很正常的想法!這個屬性非常的有趣,所以我們需要怎么做呢?答案是下面的:

Q_PROPERTY(type name(READ getFunction [WRITE setFunction] |MEMBER memberName [(READ getFunction | WRITE setFunction)])[RESET resetFunction][NOTIFY notifySignal][REVISION int | REVISION(int[, int])][DESIGNABLE bool][SCRIPTABLE bool][STORED bool][USER bool][BINDABLE bindableProperty][CONSTANT][FINAL][REQUIRED])

? 注意,這些代碼實際上啥也不會留下,他是給我們的MOC提供信息用的。告訴我們這個屬性的性質,名稱,如何讀寫等等方法。舉個例子:

Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)

? 依次說明了如下的基本事實:

1. Q_PROPERTY(bool focus READ hasFocus)

聲明了一個名為 focus 的布爾類型屬性:

  • READ:通過 hasFocus() 方法讀取屬性值(無寫入功能)。
  • 用途:通常表示控件是否獲得鍵盤焦點(如輸入框被選中時)。
  • 特點:這是一個只讀屬性,無法直接修改(沒有 WRITEMEMBER 標記)。

2. Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)

聲明了一個名為 enabled 的布爾類型屬性:

  • READ:通過 isEnabled() 方法讀取屬性值。
  • WRITE:通過 setEnabled(bool) 方法修改屬性值。
  • 用途:控制控件是否啟用(禁用時通常變灰且不響應用戶輸入)。
  • 特點:支持讀寫,修改時會自動觸發 Qt 的屬性系統通知(如信號或樣式更新)。

3. Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)

聲明了一個名為 cursorQCursor 類型屬性:

  • READ:通過 cursor() 方法獲取當前光標樣式。
  • WRITE:通過 setCursor(QCursor) 方法設置光標樣式(如鼠標懸停時變為手型)。
  • RESET:通過 unsetCursor() 方法恢復默認光標(移除自定義設置)。
  • 用途:動態改變控件的光標外觀。
  • 特點:支持讀、寫和重置操作,靈活性更高。
#include <QObject>
class Person : public QObject
{Q_OBJECTQ_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:explicit Person(QObject *parent = nullptr) : QObject(parent) {}QString name() const { return m_name; }void setName(const QString &name) {if (m_name != name) {m_name = name;emit nameChanged();}}
signals:void nameChanged();
private:QString m_name;
};// 在某處使用
Person p;
p.setProperty("name", "Alice");
QString current = p.property("name").toString();

? 當然,這樣我們就完成了一次對屬性的讀寫。這個的好處其實跟正常的get set接口類似,但是多了Qt上的很多元對象支持,就是我剛剛提到的那些。

附錄:屬性文檔

  • 如果未指定 MEMBER 變量,則需要一個 READ 訪問器函數。該函數用于讀取屬性值。理想情況下,使用 const 函數來實現此目的,并且它必須返回屬性的類型或該類型的 const 引用。例如,QWidget::focus 是一個只讀屬性,其 READ 函數為 QWidget::hasFocus()。如果指定了 BINDABLE 變量,則可以編寫 READ default 來從 BINDABLE 變量生成 READ 訪問器。
  • WRITE 訪問器函數是可選的。它用于設置屬性值。它必須返回 void,并且必須只接受一個參數,該參數可以是屬性的類型、指向該類型的指針或引用。例如,QWidget::enabled 具有 WRITE 函數 QWidget::setEnabled()。只讀屬性不需要 WRITE 函數。例如,QWidget::focus 沒有 WRITE 函數。如果您同時指定了 BINDABLE 和 WRITE 的默認值,則系統會從 BINDABLE 生成一個 WRITE 訪問器。生成的 WRITE 訪問器不會顯式發出任何使用 NOTIFY 聲明的信號。您應該將該信號注冊為 BINDABLE 的變更處理程序,例如使用 Q_OBJECT_BINDABLE_PROPERTY。
  • 如果沒有指定 READ 訪問器函數,則需要 MEMBER 變量關聯。這使得給定的成員變量無需創建 READ 和 WRITE 訪問器函數即可讀寫。如果您需要控制變量訪問,除了 MEMBER 變量關聯之外,仍然可以使用 READ 或 WRITE 訪問器函數(但不能同時使用)。
  • RESET 函數是可選的。它用于將屬性設置回其上下文相關的默認值。例如,QWidget::cursor 具有典型的 READ 和 WRITE 函數,即 QWidget::cursor() 和 QWidget::setCursor(),此外它還具有 RESET 函數,即 QWidget::unsetCursor(),因為任何對 QWidget::setCursor() 的調用都不能重置為上下文特定的游標。RESET 函數必須返回 void 且不接受任何參數。
  • NOTIFY 信號是可選的。如果定義,則應指定該類中一個現有的信號,該信號在屬性值發生變化時發出。MEMBER 變量的 NOTIFY 信號必須接受零個或一個參數,并且該參數必須與屬性的類型相同。該參數將采用屬性的新值。NOTIFY 信號應僅在屬性確實發生更改時發出,以避免在 QML 中不必要地重新評估綁定。當通過 Qt API(QObject::setProperty、QMetaProperty 等)更改屬性時,會自動發出信號,但直接更改 MEMBER 時則不會發出信號。
  • REVISION 編號或 REVISION() 宏是可選的。如果包含,則它定義了在特定 API 版本(通常用于暴露給 QML)中使用的屬性及其通知信號。如果不包含,則默認為 0。
  • DESIGNABLE 屬性指示該屬性是否應在 GUI 設計工具(例如 Qt Widgets Designer)的屬性編輯器中可見。大多數屬性都是 DESIGNABLE(默認為 true)。有效值為 true 和 false。
  • SCRIPTABLE 屬性指示此屬性是否應由腳本引擎訪問(默認為 true)。有效值為 true 和 false。
  • STORED 屬性指示應將屬性視為獨立存在還是依賴于其他值。它還指示在存儲對象狀態時是否必須保存屬性值。大多數屬性都是 STORED 屬性(默認為 true),但例如 QWidget::minimumWidth() 的 STORED 屬性為 false,因為它的值取自 QWidget::minimumSize() 屬性的寬度部分,而該屬性的類型為 QSize。
  • USER 屬性指示該屬性是被指定為面向用戶的屬性還是用戶可編輯的屬性。通常,每個類只有一個 USER 屬性(默認為 false)。例如,QAbstractButton::checked 是(可勾選的)按鈕的用戶可編輯屬性。請注意,QItemDelegate 可以獲取和設置小部件的 USER 屬性。
  • BINDABLE bindableProperty 屬性指示該屬性支持綁定,并且可以通過元對象系統 (QMetaProperty) 設置和檢查與該屬性的綁定。bindableProperty 命名一個 QBindable 類型的類成員,其中 T 是屬性類型。此屬性是在 Qt 6.0 中引入的。
  • CONSTANT 屬性的存在表示該屬性值為常量。對于給定的對象實例,常量屬性的 READ 方法每次調用時必須返回相同的值。對于不同的對象實例,此常量值可能不同。常量屬性不能具有 WRITE 方法或 NOTIFY 信號。
  • FINAL 屬性的存在表示該屬性不會被派生類覆蓋。在某些情況下,這可以用于性能優化,但 moc 并不強制執行。必須注意切勿覆蓋 FINAL 屬性。
  • REQUIRED 屬性的存在表示該屬性應由類的用戶設置。moc 并不強制執行此操作,并且主要用于適用于暴露給 QML 的類。在 QML 中,除非設置了所有必需屬性,否則無法實例化具有必需屬性的類。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/80695.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80695.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/80695.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

NestJS 框架深度解析

框架功能分析 NestJS 是一個基于 Node.js 的漸進式框架&#xff0c;專為構建高效、可擴展的服務器端應用程序而設計。其核心理念結合了 面向對象編程&#xff08;OOP&#xff09;、函數式編程&#xff08;FP&#xff09; 和 函數式響應式編程&#xff08;FRP&#xff09;&…

PostgreSQL技術大講堂 - 第89講:重講數據庫完全恢復

PostgreSQL技術大講堂 - 第89講&#xff0c;主題&#xff1a;重講數據庫完全恢復 時間&#xff1a;2025年05月10日19:30 歡迎持續關注CUUG PostgreSQL技術大講堂。

ubuntu部署supabase

安裝supabse https://supabase.com/docs/guides/local-development/cli/getting-started?queryGroupsplatform&platformlinux brew install supabase/tap/supabase supabase init supabase start需要使用brewuser進行安裝&#xff1a; brew安裝參考鏈接&#xff1a; ht…

基于javaweb的SpringBoot酒店管理系統設計與實現(源碼+文檔+部署講解)

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文…

python 上海新聞爬蟲, 東方網 + 澎湃新聞

1. 起因&#xff0c; 目的: 繼續做新聞爬蟲。我之前寫過。此文先記錄2個新聞來源。后面打算進行過濾&#xff0c;比如只選出某一個類型新聞。 2. 先看效果 過濾出某種類型的新聞&#xff0c;然后生成 html 頁面&#xff0c;而且&#xff0c;自動打開這個頁面。 比如科技犯罪…

使用bitNet架構

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、配置二、報錯總結 前言 大型語言模型&#xff08;LLM&#xff09;面臨的挑戰&#xff1a;高能耗、高內存需求、部署門檻高。 微軟提出 BitNet 架構&#x…

筆試強訓(十七)

文章目錄 活動安排題解代碼 哈夫曼編碼題解代碼 奇數位丟棄題解代碼 活動安排 題目鏈接 題解 1. 區間貪心 排序 2. 如果有重疊部分&#xff0c;每次選擇右端點較小的&#xff0c;可以盡可能多的選擇區間個數&#xff0c;如果沒有重疊部分&#xff0c;選擇下一個區間的右端…

數據庫數據清洗、預處理與質量監控、 數據質量的核心概念

數據庫數據清洗、預處理與質量監控、 數據質量的核心概念 準確性 (Accuracy) 準確性指數據正確反映其所描述的實體或事件真實狀況的程度。準確的數據應當與現實世界中的實際情況一致。 一致性 (Consistency) 一致性指數據在不同表、系統或時間點之間保持邏輯上一致的程度。…

Docker組件詳解:核心技術與架構分析

Docker詳解&#xff1a;核心技術與架構分析 Docker作為一種容器化技術&#xff0c;已經徹底改變了軟件的開發、交付和部署方式。要充分理解和利用Docker的強大功能&#xff0c;我們需要深入了解其核心組件以及它們如何協同工作。本文將詳細介紹Docker的主要組件、架構設計以及…

【言語】刷題3

front&#xff1a;刷題2 題干 超限效應介紹冰桶挑戰要避免超限效應 B明星的作用只是病痛挑戰的一個因素&#xff0c;把握程度才是重點&#xff0c;不是強化弱化明星作用&#xff0c;排除 A雖沒有超限效應&#xff0c;但是唯一的點出“冰桶效應”的選項&#xff0c;“作秀之嫌…

【fastadmin開發實戰】在前端頁面中使用bootstraptable以及表格中實現文件上傳

先看效果&#xff1a; 1、前端頁面中引入了表格 2、表格中實現文件上傳 3、增加截止時間頁面 難點在哪呢&#xff1f; 1、這是前端頁面&#xff0c;并不支持直接使用btn-dialog的類屬性實現彈窗&#xff1b; 2、前端頁面一般綁定了layout模板&#xff0c;如何實現某個頁面不…

豆包:基于多模態交互的智能心理咨詢機器人系統設計與效果評估——情感計算框架下的對話機制創新

豆包:基于多模態交互的智能心理咨詢機器人系統設計與效果評估——情感計算框架下的對話機制創新 摘要 隨著人工智能在心理健康領域的應用深化,本文提出一種融合情感計算與動態對話管理的智能心理咨詢機器人系統架構。通過構建“用戶狀態-情感響應-策略生成”三層模型,結合…

【漫話機器學習系列】257.填補缺失值(Imputing Missing Values)

數據科學必備技能&#xff1a;填補缺失值&#xff08;Imputing Missing Values&#xff09; 在數據分析和機器學習項目中&#xff0c;缺失值&#xff08;Missing Values&#xff09; 是非常常見的問題。缺失的數據如果處理不當&#xff0c;會嚴重影響模型的訓練效果&#xff0…

基于千眼狼高速攝像機與三色掩模的體三維粒子圖像測速PIV技術

研究背景 航空航天、能源動力領域&#xff0c;測量三維瞬態流場的速度場信息對于理解流體力學行為、優化系統設計非常關鍵。 傳統三維粒子圖像測速技術如Tomo層析PIV&#xff0c;因依賴多相機陣列&#xff0c;存在系統體積、操作復雜&#xff0c;在封閉空間測量存在困難&#…

MongoDB 的主要優勢和劣勢是什么?適用于哪些場景?

MongoDB 的主要優勢 (Advantages) 靈活的文檔模型 (Flexible Document Model): 無需預定義模式 (Schemaless/Flexible Schema): 這是 MongoDB 最核心的優勢之一。它存儲 JSON 格式的文檔&#xff0c;每個文檔可以有不同的字段和結構。這使得在開發過程中修改數據結構非常容易&a…

css iconfont圖標樣式修改,js 點擊后更改樣式

背景&#xff1a; 在vue項目中&#xff0c;通過點擊/鼠標覆蓋&#xff0c;更改選中元素的樣式&#xff0c;可以通過js邏輯&#xff0c;也可以根據css樣式修改。包括以下內容&#xff1a;iconfont圖標的引入以及使用&#xff0c;iconfont圖標樣式修改【導入文件是純白&#xff0…

CosyVoice介紹

CosyVoice介紹 CosyVoice是阿里開源的一個多語言語音生成大模型&#xff0c;可應用于TTS(Text To Speech) 工具的開發。它支持內置預制語音生成、語音克隆、自然語言控制語音生成等功能。CosyVoice的另一個亮點在于它對生成語音情感和韻律的精細控制&#xff0c;這是通過富文本…

分布式任務調度XXL-Job

? XXL-Job 是一款輕量級、分布式的任務調度平臺&#xff0c;其核心設計解決了傳統任務調度&#xff08;如Quartz&#xff09;在分布式場景下的?任務分片?、?高可用?、?可視化管控?等痛點。以下從原理、核心架構、應用場景、代碼示例及關聯中間件展開詳解 一、主流任務…

GOOSE 協議中MAC配置

在 GOOSE&#xff08;Generic Object Oriented Substation Event&#xff09;協議中&#xff0c;主站&#xff08;Publisher&#xff09;發送的 MAC 地址不需要與從站&#xff08;Listener&#xff09;的 MAC 地址一致&#xff0c;其通信機制與 MAC 地址的匹配邏輯取決于 GOOSE…

交流充電樁IEC 61851-1和IEC 61851-21-2標準測試項目

交流充電樁IEC 61851-1和IEC 61851-21-2標準測試項目 立訊檢測的光儲充實驗室專注于光伏、儲能、充電設施等新能源領域的檢測與認證服務&#xff0c;以下是詳細介紹&#xff1a; ?1. 實驗室概況? ?覆蓋領域?&#xff1a;光伏逆變器、儲能電池系統、充電樁、便攜式儲能電…