初識Qt:從Hello world到對象樹的深度解析

Qt中的對象樹深度解析

  • Hello world
    • 1.圖形化界面創建
    • 命令行式創建
      • 在棧上創建
      • 在堆上創建
        • 為什么傳文本需要QString,std::string不行嗎?
        • 那為什么要傳入this指針?為什么new后不用顯示調用delete函數呢,不會造成內存泄漏問題嗎?
  • 一、對象樹的基本概念
  • 二、對象樹的創建
    • 驗證對象樹的內存管理
  • 三、對象樹的用途
  • 四、對象樹的注意事項

Hello world

1.圖形化界面創建

在這里插入圖片描述
在這里插入圖片描述
與上述圖片中的樹形結構對應,則XML代碼為在這里插入圖片描述

命令行式創建

在棧上創建

    //構建QLabel標簽QLabel label1;label1.setText(QString("Hello World"));

這里我們采用在棧上創建Label對象,并設置其文本為Hello world,但是為什么在對話框沒有顯示呢?
在這里插入圖片描述

局部變量:label1是一個局部變量,它在構造函數結束時會被銷毀。即使您將其添加到了布局中,由于它在構造函數結束后不再存在,所以標簽也不會顯示出來。

在堆上創建

    //構建QLabel標簽QLabel* label1=new QLabel(this);label1->setText(QString("Hello World"));

在這里插入圖片描述
在這里插入圖片描述

通過上述我們發現,現在可以顯示在對話框了,但是也存在上述幾個問題——

為什么傳文本需要QString,std::string不行嗎?

在Qt中,QString是Qt框架提供的字符串類,它與C++標準庫中的std::string有所不同。盡管在某些情況下,你可以使用std::string,但在Qt應用程序中,通常建議使用QString,因為它具有以下優勢:

  1. 跨平臺性:QString是Qt框架的一部分,而且是跨平臺的。這意味著你可以在不同的操作系統上(如Windows、Linux、macOS等)使用相同的代碼,并且QString的行為將是一致的。相比之下,std::string是C++標準庫的一部分,可能在不同的編譯器或操作系統上有不同的實現和行為。

  2. Unicode支持:QString天生支持Unicode字符集,這意味著它可以輕松處理各種語言和特殊字符,而不會出現亂碼或截斷等問題。與之相比,std::string在處理Unicode字符時可能會面臨一些挑戰,需要謹慎處理。

  3. 方便的API:QString提供了豐富的API,可以方便地進行字符串操作,如拼接、查找、替換、大小寫轉換等。此外,QString還支持使用arg()方法進行字符串格式化,使得字符串處理更加靈活和便捷。

  4. 與Qt框架的集成:QString與Qt框架的其他部分無縫集成,如信號槽機制、國際化支持等。使用QString可以更容易地與其他Qt類進行交互,并且可以利用Qt提供的豐富功能來進行字符串處理。

所以,盡管string也可以作為參數傳入,但是為了防止出現亂碼(編碼不一致)的問題,還是老實用QString傳入較好(不用顯示寫入,通過構造函數,上述 label1->setText("Hello World");也是可以的)

那為什么要傳入this指針?為什么new后不用顯示調用delete函數呢,不會造成內存泄漏問題嗎?

在Qt中,使用this作為父對象參數來創建對象,是為了將新創建的對象添加到當前對象的子對象列表中,并且在當前對象銷毀時,這些子對象也會被自動銷毀。在示例代碼中,通過new QLabel(this)語句創建了一個QLabel對象,并將當前Widget對象作為其父對象

現在來解釋一下為什么要傳遞this:

  1. 對象樹管理:Qt中的對象樹是通過父子關系來管理的,每個QObject都可以有一個父對象。當一個對象擁有父對象時,它就成為父對象的子對象,而且其生命周期也受父對象管理。通過將this作為父對象參數傳遞給new QLabel(),你告訴Qt將新創建的QLabel對象添加到當前Widget對象的子對象列表中。

  2. 內存管理:傳遞this作為父對象參數可以確保在當前Widget對象被銷毀時,其所有子對象也會被自動銷毀。這是因為Qt會自動管理父對象與其子對象之間的關系,并在父對象銷毀時遞歸地銷毀其所有子對象,從而避免內存泄漏。

因此,通過將this作為父對象參數傳遞給new QLabel(),可以實現對象之間的正確管理和內存自動釋放。

那么肯定會疑惑,Qt真的能安全地將我們構造的對象釋放嗎?你怎么知道?

引入對象樹

在Qt這個強大的跨平臺C++圖形用戶界面應用程序開發框架中,對象樹是一個核心概念。它不僅為Qt應用程序的內存管理提供了便利,還確保了Qt對象之間的父子關系清晰、易于理解。本文將深入解析Qt中的對象樹機制,幫助讀者更好地理解其在Qt應用程序中的作用。

一、對象樹的基本概念

Qt中的對象樹是一個樹形結構,其中每個節點都是一個QObject或其派生類的實例。這些對象通過父子關系連接在一起,形成了一個層次結構。在這個結構中,每個對象都可以有一個父對象(除了根對象外),并且可以有多個子對象。
如下圖所示為一顆Qt的n叉樹,樹的根節點為QObject
在這里插入圖片描述

二、對象樹的創建

在Qt中,對象的創建通常伴隨著父子關系的建立。當一個QObject對象在創建時指定了一個父對象,那么這個新創建的對象就會自動添加到父對象的子對象列表中。同時,父對象會接管其所有子對象的內存管理。這意味著,當父對象被刪除時,其所有子對象也會被自動刪除,從而避免了內存泄漏的問題。

驗證對象樹的內存管理

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

tips: .h 與 .cpp之間可以通過F4快速切換

在這里插入圖片描述
完成創建后編譯代碼,發現出現了和上述一樣的結果
在這里插入圖片描述
當我們關閉對話框時,則會發現其默認調用了析構函數

在這里插入圖片描述

tips:調?析構函數和釋放內存并?是同?件事情.

因此驗證了對象樹內存管理的機制

三、對象樹的用途

  1. 內存管理:如前所述,對象樹為Qt應用程序提供了自動的內存管理機制。這種機制通過父子關系來確保當一個對象不再需要時,它的所有子對象也會被正確地刪除。
  2. 事件傳播:在Qt中,事件(如鼠標點擊、鍵盤輸入等)是通過事件系統來傳播的。當一個事件發生時,它首先被發送到接收該事件的對象。如果該對象無法處理該事件,那么事件就會沿著對象樹向上傳播,直到找到一個能夠處理該事件的對象為止。這種機制使得Qt能夠輕松地處理復雜的事件傳遞邏輯。
  3. 資源共享:在Qt中,一些資源(如字體、顏色等)可以在對象樹中進行共享。當一個對象設置了某個資源時,它的所有子對象都可以訪問和使用這個資源。這種機制減少了資源的使用量,提高了應用程序的性能。

四、對象樹的注意事項

  1. 避免循環引用:循環引用是指兩個或多個對象相互引用,形成一個環路。在構建對象樹時,要注意避免循環引用的問題。即一個對象不能成為自己的祖先對象的子對象,否則會導致內存泄漏和其他問題。
// 錯誤示例:創建循環引用的對象樹
QObject *parent = new QObject;
QObject *child = new QObject(parent);
parent->setParent(child); // 這里會導致循環引用// 正確示例:避免循環引用
QObject *parent = new QObject;
QObject *child = new QObject(parent); // 正確,child 是 parent 的子對象
  1. 謹慎使用setParent()方法:setParent()方法用于在運行時更改對象的父對象。但是,需要謹慎使用,因為它可能會導致一些意想不到的問題,例如事件傳播錯誤或資源共享問題。在使用setParent()方法時,需要確保不會破壞對象之間的邏輯關系或導致不一致的狀態。
// 示例:謹慎使用 setParent() 方法
QObject *parent = new QObject;
QObject *child = new QObject;// 設置 child 的父對象為 parent
child->setParent(parent);// 如果后續不再需要 parent,要特別小心
delete parent; // 這可能會導致 child 懸空指針,引發錯誤
  1. 注意對象的生命周期:雖然對象樹提供了自動的內存管理機制,但是開發者仍然需要注意對象的生命周期。在不再需要某個對象時,最好顯式地刪除它(而不是僅僅斷開它與父對象的連接),以確保資源的及時釋放。可以通過delete操作符來顯式刪除對象,或者使用QObject的父子關系自動管理機制。
// 示例:注意對象的生命周期
QObject *parent = new QObject;
QObject *child = new QObject(parent);// 顯式刪除對象
delete parent; // 這將同時刪除 parent 和 child// 或者使用父子關系自動管理
// 當 parent 被刪除時,child 會自動刪除

總結

Qt中的對象樹是一個強大而靈活的概念,它為Qt應用程序提供了自動的內存管理、事件傳播和資源共享等機制。通過深入理解對象樹的工作原理和使用方法,開發者可以更加高效、安全地開發Qt應用程序。

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

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

相關文章

python:__class_getitem__使用以及cached_property源碼分析

python:__class_getitem__使用以及cached_property源碼分析 1 前言 Python中如何模擬泛型類型? 當使用類型標注時,使用 Python 的方括號標記來形參化一個 generic type 往往會很有用處。 例如,list[int] 這樣的標注可以被用來表…

深入 OpenFeign:探索緩存、QueryMap、MatrixVariable 和 CollectionFormat 的高級用法以實現優雅的遠程調用

免費多模型AI網站,支持豆包、GPT-4o、谷歌Gemini等AI模型,無限制使用,快去白嫖👉海鯨AI 一、OpenFeign簡介 OpenFeign 是一個聲明式的 HTTP 客戶端,它使得我們可以通過簡單的注解和接口定義來調用遠程 HTTP 服務。與傳統的 HTTP …

K8S集群再搭建

前述:總體是非常簡單的,就是過程繁瑣,不過都是些重復的操作 master成員: [controller-manager, scheduler, api-server, etcd, proxy,kubelet] node成員: [kubelet, proxy] master要修改的配置文件有 1. vi /etc/etcd/etcd.conf # 數…

Mokito的一些API

Mockito是一個Java單元測試框架,它允許開發者創建和配置模擬對象(mock objects),以便在隔離的環境中測試代碼,尤其是當實際對象難以構造或其行為不確定時。下面是一些核心的Mockito API及其使用場景和代碼示例。 基礎…

wordpress教程視頻 wordpress教程網盤 wordpress教程推薦wordpress教程網

WordPress,作為一款強大且靈活的開源內容管理系統,已成為許多網站開發者與運營者的首選。其強大的功能、豐富的插件以及易于上手的特點,使得無論是初學者還是專業開發者都能輕松構建出個性化的網站。然而,對于初學者來說&#xff…

JUnit5標記測試用例

使用場景: 通過Tag對用例分組: 環境分組:測試環境、預發布環境階段分組:冒煙用例版本分組:V1.1、V1.2 Tag標記用例: 設置標簽根據標簽執行 結合Maven執行結合測試套件執行 設置標簽: 通過T…

NER 數據集格式轉換

NER 數據集格式 格式一 某些地方的數據和標簽拆成兩個文件了 sentences.txt 如 何 解 決 足 球 界 長 期 存 在 的 諸 多 矛 盾 , 重 振 昔 日 津 門 足 球 的 雄 風 , 成 為 天 津 足 壇 上 下 內 外 到 處 議 論 的 話 題 。 該 縣 一 手 抓 農 業…

【Spring Cloud】全面解析服務容錯中間件 Sentinel 持久化兩種模式

文章目錄 推送模式本地文件持久化(拉模式)配置yml編寫處理類添加配置演示 配置中心持久化(推模式)修改nacos在sentinel中生效引入依賴配置文件 修改sentinel在nacos中生效下載源碼更改代碼演示 總結 推送模式 Sentinel 規則的推送…

allegro 無法刪除Xnet

allegro 無法刪除Xnet Orcad中打開Constraint Manager之后,再生成網表,導入PCB后就會出現一堆Xnet網絡。無法去除Xnet。 解決辦法 在原理圖ORCAD中, 1、打開Edit Object properties 2、選擇Filter by:Capture 3、點擊New Property 4、設置…

火山引擎邊緣云亮相 Force 原動力大會,探索 AI 應用新范式

5月15日,2024 春季火山引擎 FORCE 原動力大會在北京正式舉辦。大會聚焦 AI 主題,以大模型應用為核心、以 AI 落地為導向,展示了火山引擎在大模型、云計算領域的實踐應用,攜手汽車、手機終端、金融、消費、互聯網等領域的專家和企業…

2024042102-array-list

數組 Array 一、前言 數組是數據結構還是數據類型? 數組只是個名稱,它可以描述一組操作,也可以命名這組操作。數組的數據操作,是通過 idx->val 的方式來處理。它不是具體要求內存上要存儲著連續的數據才叫數據,而…

js積累三(web頁面一段時間未操作,退出登錄)

//核心代碼,已封裝function CountDownLogout() {/* if 30 seconds no operation then logout */var maxTime 30; // seconds,可自行修改時長var time_time maxTime;/* 鼠標點擊事件 */$(document).mousedown(function(){time_time maxTime; //…

Spring Aop對本地事務的影響

1.Transactional聲明式事物也是基于aop實現的,public方法加了Transactional注解后,已經成功的創建了事務,但是當前方法仍在方法攔截器中 2.業務方法發生異常之后的處理 判斷回滾條件: 如果自定義了RollbackRuleAttribute列表&am…

EI會議的最佳論文獎是什么?如何申請?

EI會議的最佳論文獎通常是指在EI(工程索引,Engineering Index)收錄的學術會議中,評選出的表現最優秀的論文獎項。以下是關于該獎項的一些基本信息及申請步驟: 最佳論文獎的含義 評選標準:最佳論文獎通常基…

多線程、進程、線程五種狀態、synchronized、volatile、Lock、CAS、死鎖、ThreadLocal

1、并發編程 并發編程三要素 原子性:只一個操作要么全部成功,要么全部失敗可見性:一個線程對共享變量的修改,其他線程能夠立刻看到有序性:程序執行的順序按照代碼的先后順序執行 synchronized,Lock解決原…

前端vue 動態加載ts文件,動態調用ts內的方法

業務場景: 在某個業務場景中, 我們需要在數據庫配置ts文件路徑,和需要調用的函數名稱, 前端需要再指定的場景下,觸發對應的函數, 并執行處理邏輯,返回結果. 實現: 這是一個數據庫配置生成的動態表單 動態校驗的例子, 需要引用動態的函數校驗 任意一個js文件, common1.ts c…

大模型日報|今日必讀的 13 篇大模型論文

大家好,今日必讀的大模型論文來啦! 1.MIT新研究:并非所有語言模型特征都是線性的 最近的研究提出了線性表征假說:語言模型通過操作激活空間中概念(“特征”)的一維表征來執行計算。與此相反,來…

CHI dataless 傳輸——CHI(4)

上篇介紹了read的操作類型,本篇我們來介紹一下dataless 目錄 一、dataless操作概覽 二、Non-CMO (Non-Cache Maintenance Operation) 1、CleanUnique 2、StashOnce and StashOnceSep 3、Evict 三、CMO (Cache Maintenance Operation) 一、dataless操作概覽 名…

C# 中的 Dictionary<TKey, TValue> 類

Dictionary<TKey, TValue> 是 C# 中的一個泛型集合類,它提供了一種鍵值對的存儲結構,可以用來存儲和快速訪問數據。它的主要特點如下: 鍵值對結構: Dictionary 中的每個元素都是一個鍵值對,鍵必須是唯一的,值可以重復。 快速訪問: Dictionary 基于哈希表實現,可以提供 O…

大白話聊聊MySQL查詢之五子句(知識簡單但重要)

前言&#xff1a; 在日常開發中&#xff0c;查詢數據占很大的比重&#xff0c;在使用 MySQL 數據庫進行查詢時&#xff0c;我們經常需要通過各種條件和規則來篩選和排序數據。要實現這些功能&#xff0c;就不得不使用以下這些子句&#xff1a;WHERE、ORDER BY、GROUP BY、HAVI…