QML學習筆記(一)基本了解和工程配置

前言:

已經從事QT開發幾年了,但對于QML這個東西始終是沒有徹底掌握,一方面實際工作中沒有用到過,其次它的語法對我來說是全新的東西,不像QWidget那一套可以直接在C++中去寫。這就是為什么網上都說qml更簡單,我卻屢屢學不會的原因。
讓我下定決心一定要開始學QML的契機,就是因為最近在找工作,面試官讓我在紙上直接寫一個按鈕,并設置一段文字,結果我猶豫半天,居然沒能動筆。我大概知道是寫button,然后用花括號括起來,但button是否需要大寫,花括號后面有沒有分號,里面的屬性又是什么來著……我一下子陷進了沮喪。
這其實就是沒有真正使用qml寫過代碼的必然結果,即便對此有基本的認知,但別人考到你的時候,實際上是寫不出來的。所以接下來的學習當中,我必須要做好詳細的記錄和筆記,這也是對自己的要求。(偷偷抱怨一句,在這個時代只會qt,是真的難找到工作啊)
話不多說,

一、QML基本了解

QML是Qt框架的聲明式UI開發語言,與傳統的Qt Widgets(基于C++的界面庫)在語法特性、適用場景和視覺效果上存在顯著差異?。

?1.語法特性?: QML采用JSON-like聲明式語法,支持數據綁定和熱重載。? Qt
Widgets使用C++編寫,采用命令式編碼模式。?
2.視覺效果?: QML支持矢量渲染與復雜動畫,可自定義漸變色、圓角等效果。? Qt Widgets基于原生控件,動畫效果有限。?
3.開發場景?: QML適合移動端/嵌入式設備的動態UI(占比65%應用場景)。? Qt Widgets適合傳統桌面軟件(如Office類應用)。?

以上是網上找到的內容,結合我自身的認知,再淺淺談一下。
1.QML常常伴隨Qt Quick這個詞語,看上去好像是同一個東西,實則不然。QML是Quick Markup Language,它是一門語言。而Qt Quick是一個模塊,可以理解為Qt的一個擴展庫,你必須要先引用Qt Quick這個模塊,才能用QML語言來寫代碼。
2.為什么會出現QML這個東西,我猜是為了將界面描述和邏輯代碼徹底分開。如果你深入用QWidget來寫過代碼,你會有個感悟,界面層的代碼和業務功能代碼是深度耦合在一起的,特別是還有信號槽這種東西。而如果我們將界面相關的東西,全部用單獨的文件編寫起來,業務代碼繼續用C++寫,是不是就更清晰明了,分工明確呢。所以說,QML其實是專門做界面+加動畫+小邏輯的語言,為的是不搶C++業務。
3.說到QML的優勢,大家說的基本上可以使用GPU硬件加速和支持動畫效果,但這方面我目前還沒體會到,后面學習再加上。還有一點是,QML更方便應用在嵌入式小設備和移動端。至于“學習成本低”、“語法更簡單”,就見仁見智了。

二、QML工程創建
先說一下,我的QT版本是5.14.2,默認就可以創建Qt Quick工程,如果不行可能是QT安裝的時候沒有安裝對應的模塊,這個就得重新裝下QT了。
咱們先創建新的工程,選Qt Quick的應用工程,這里有好幾個選項,直接選空的即可。后面的步驟和QWidget是一樣的,就不啰嗦了。
在這里插入圖片描述
創建完工程后,直接編譯運行,成功顯示出空白界面。(還很貼心給了個Hello World的提示)
在這里插入圖片描述

三、工程結構

在看具體的qml代碼之前,我們先看一下基本的工程目錄結構。
如果是傳統的QWidget工程,代碼一般放在Headers(頭文件)和Sources(源文件)兩個目錄下標里面,但存放qml代碼的qml文件顯然不是。你可以直觀看到,qml文件默認是放在Resources底下的qrc里面的。而qrc一般存放的是資源文件,最常見的就是各種ui圖片。
在這里插入圖片描述
也就是說,qml作為一種界面描述文件,本質上是當做一種資源來管理的(不知道說得對不對),他區別于其他正式的C++代碼文件,存放在不同的目錄底下。
當然,這里所說的目錄不是文件實際存放的目錄,說得上qt IDE里面顯示的分類目錄哈。
在這里插入圖片描述
咱們打開工程的pro文件,發現它加載的是quick模塊。這里對比一下傳統QWidget應用,這里夾在的事core和gui模塊。
在這里插入圖片描述
當然,這并不是二選一的問題,事實上qml是可以和widget混合使用的,比如從一個qwidget界面跳轉到qt quick界面,是完全可以的。我想表達的是,如果我們在qwidget工程中,想要新增一個qml工程,需要自己手動在pro中添加quick模塊,這樣qml才能正常使用哈。

四、C++中打開并顯示QML界面

我們直接把main中的代碼放上來。咋一看很復雜,沒事我們慢慢來。

#include <QGuiApplication>
#include <QQmlApplicationEngine>int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);engine.load(url);return app.exec();
}

首先是頭文件,這里引用的QGuiApplication,它實際上對應的是QApplication,QGuiApplication比QApplication會更加輕量級,更適合純QML的工程。這里換成QApplication其實也是可以的,但pro要注意把core和gui模塊加上。
第二個頭文件叫QQmlApplicationEngine
QML 引擎,負責解析+加載+實例化你的 main.qml 文件。
我們看main的代碼,第一行是QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);這是開啟高分辨率自適應,這和qwidget是一樣的,它默認給你添加了。
下一行是QGuiApplication app(argc, argv);這是創建了一個應用對象。
重點是下面的代碼。

QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));

engine = QML 解析器 + 加載器 + 對象工廠。
url = 要加載的 QML 文件(qrc 資源系統路徑)。

QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);
}, Qt::QueuedConnection);

這句信號槽實際上是engine引擎加載url后的結果回調,返回參數是obj和obj的url,這里做了個保險絲判斷,如果 main.qml 加載失敗(文件不存在/語法錯誤),立即退出程序,防止黑屏。

engine.load(url);
return app.exec();

load = 解析 + 實例化整個 QML 對象樹。
exec() = 進入事件循環,直到 QCoreApplication::quit() 或窗口關閉。

最后再說一下我自己的理解。這種寫法更多是初始化一個qml引擎,然后加載url上的文件,把qml描述的界面顯示出來。實際上我更喜歡另一種方法,用到了qt中的QQuickWidget,它是一種組件,可以直接嵌QWidget中。直接調用QQuickWidget中的setSource似乎是一種更方便的做法,當然以我目前的水平,還說不好誰更好。這種方法我在下一篇中會詳細再說。
至此,一個qml界面便顯示出來咯。

五、QML最小可運行實例

我們雙擊main.qml,發現里面有這段代碼。

import QtQuick 2.14
import QtQuick.Window 2.14Window {visible: truewidth: 640height: 480title: qsTr("Hello World")
}

類似于C++代碼,其實還蠻好理解的。

  1. import QtQuick 2.14
    引入 QtQuick 核心庫(對象、動畫、繪制等基礎類)。

  2. import QtQuick.Window 2.14
    引入 Window 組件(ApplicationWindow 的簡化版),提供頂層窗口。

  3. Window { … }
    頂層窗口對象,等價于 QMainWindow 的 QML 版。

  4. visible: true
    立即顯示窗口(false 則隱藏)。

  5. width: 640 / height: 480
    窗口初始大小(像素)。

  6. title: qsTr("Hello World")
    窗口標題,qsTr() 是 Qt 的國際化函數,可被翻譯系統替換。

這 7 行是 QML 的最小可運行模板: 導入 QtQuick 和 Window,創建 640×480 的頂層窗口,標題‘Hello World’,立即顯示。

六、頂層窗口描述

我再補充一點,這里用到的Window事實上并不是固定的,我有見過b站up主用的Rectangle,于是用kimi問了一下:

  • Window = 頂層窗口(有標題欄、系統邊框、任務欄圖標)。
  • Rectangle = 普通矩形對象(無邊框,必須被別的窗口或組件裝載)。

1. 頂層 vs 被裝載

作用是否能獨立顯示
Window頂層窗口(系統邊框、標題欄)? 直接顯示
Rectangle矩形+顏色+子控件? 必須被 Window/ApplicationWindow 裝載

2. 代碼對比

頂層窗口(獨立顯示):

import QtQuick 2.14
import QtQuick.Window 2.14Window {                       ← 頂層窗口visible: truewidth: 640; height: 480Rectangle {                ← 被裝載的矩形width: 200; height: 200color: "red"}
}

僅 Rectangle(無邊框,需被裝載):

import QtQuick 2.14
Rectangle {                    ← 無邊框矩形width: 200; height: 200color: "red"
}

后者無法獨立顯示——必須被 Window/ApplicationWindow 或別的組件裝載。


3. 常用頂層類對照

QML 類作用備注
Window最簡頂層窗口無邊框菜單
ApplicationWindow帶菜單欄/工具欄的主窗口QtQuick.Controls 2 推薦
Rectangle普通矩形+子控件被裝載對象

這就能解釋得通了,因為Rectangle的方式是加載在QQuickWidget控件里面的,不像main.qml中的Window必須是頂層窗口。(我嘗試直接將Window改成Rectangle,結果QQmlApplicationEngine加載返回的信號槽沒有出錯,但界面沒有彈出來,不符合我們的預期。)
這一點跟QMainWindow和QWidget的設計是類似的。只是QWidget不僅可以作為子控件,其實還可以用作頂層窗口,如果做了相關設置,甚至可以變成dialog彈窗,不過這個就不細說了。

七、總結

寫到這里,我已經盡可能說得很詳細,也努力讓自己印象深刻一點,畢竟這其實是自學筆記嘛。如果有人真的讀到這里,有什么問題也可以在評論區提出。
如果可以的話,接下來我會按照自己的節奏,按照自己的理解,一點點更新這個學習筆記,要是能成為一個教程就更棒了。

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

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

相關文章

SAP HANA Scale-out 04:緩存

結果緩存靜態結果緩存 Vs 動態結果緩存FeatureStatic Result CacheDynamic Result CacheTarget Scenario對復雜視圖&#xff08;通常是頂層視圖&#xff09;的查詢頻繁更新的大表&#xff08;例如ACDOCA&#xff09;上的聚合查詢Query result非實時數據實時數據ScopeTarget obj…

嘉興禾潤 HTR7216 (S) LED 驅動芯片:特性與應用

在如今智能設備飛速普及的時代&#xff0c;無論是智能家居的氛圍營造、IoT 設備的狀態提示&#xff0c;還是個人消費電子的視覺呈現&#xff0c;都離不開高性能 LED 驅動芯片的支撐。嘉興禾潤推出的 HTR7216 (S) LED 驅動芯片&#xff0c;憑借豐富的功能、精準的控制以及出色的…

Python實現劍龍優化算法 (Stegosaurus Optimization Algorithm, SOA)優化函數(付完整代碼)

Python實現劍龍優化算法 (Stegosaurus Optimization Algorithm, SOA)優化函數&#xff08;付完整代碼&#xff09;1.劍龍優化算法介紹劍龍優化算法&#xff08;Stegosaurus Optimization Algorithm&#xff0c;SOA&#xff09;是一種受劍龍獨特生理結構和行為模式啟發而設計的元…

分布式拜占庭容錯算法——權益證明(PoS)算法詳解

Java 實現權益證明&#xff08;PoS&#xff09;算法詳解 一、PoS 核心機制 #mermaid-svg-Sbj0HU6MjOl1yo5L {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Sbj0HU6MjOl1yo5L .error-icon{fill:#552222;}#mermaid-s…

【論文閱讀】谷歌:生成式數據優化,只需請求更好的數據

谷歌DeepMind團隊通過Generative Data Refinement&#xff08;GDR&#xff09;技術&#xff0c;成功將極端有毒的4chan討論數據轉化為安全且語義豐富的訓練素材&#xff0c;推動了LLM訓練數據凈化的新范式&#xff1a; ? GDR利用預訓練大模型對原始數據進行“重寫”&#xff0…

C++ 多線程實戰 10|C++20 的信號量、閂鎖與屏障

目錄 前言 學習目標 1. 信號量&#xff08;Semaphore&#xff09; 示例&#xff1a;限制并發下載任務 2. 閂鎖&#xff08;Latch&#xff09; 示例&#xff1a;賽跑 3. 屏障&#xff08;Barrier&#xff09; 示例&#xff1a;圖像處理流水線 4. 常見坑與對策 5. 實踐作…

【Java SE】01. 初識Java

1. 認識Java Java是一種優秀的程序設計語言&#xff0c;它具有令人賞心悅目的語法和易于理解的語義。Java還是一個有一系列計算機軟件和規范形成的技術體系&#xff0c;這個技術體系提供了完整的用于軟件開發和跨平臺部署的支持環境&#xff0c;并廣泛應用于嵌入式系統、移動終…

解鎖倉儲智能調度、運輸路徑優化、數據實時追蹤,全功能降本提效的智慧物流開源了

AI 視頻監控平臺&#xff1a;全鏈路協同驅動的智能監控解決方案AI 視頻監控平臺是一款融合高性能功能與輕量化操作的實時算法驅動型視頻監控系統&#xff0c;其核心愿景在于深度破除不同芯片廠商間的技術壁壘&#xff0c;省去冗余重復的適配環節&#xff0c;最終達成芯片、算法…

冒泡排序與選擇排序以及單鏈表與雙鏈表

1. 冒泡排序&#xff08;Bubble Sort&#xff09; 1. 原理 冒泡排序是一種 簡單的排序算法&#xff0c;通過 兩兩比較相鄰元素&#xff0c;把較大的元素逐漸 “冒泡” 到數組末尾。 思路&#xff1a; 從數組頭開始&#xff0c;比較相鄰兩個元素。 如果前一個比后一個大&…

Python實現計算點云投影面積

本次我們分享一種基于 Open3D 的快速、穩健方法&#xff0c;用于從激光點云中自動提取“地面”并計算其投影面積。算法先自適應估計地面高程&#xff0c;再將地面點投影至水平面&#xff0c;隨后用凸包或最小外接矩形求取面積。整個流程無需人工干預&#xff0c;單文件即可運行…

AXI4 協議

一、AXI4簡介AXI4&#xff08;Advanced eXtensible Interface 4&#xff09;是ARM公司推出的高性能片上總線協議&#xff0c;屬于AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;標準的一部分。它專為高帶寬、低延遲的片上通信設計&#xff0c;廣泛應用…

《餓殍:明末千里行》Switch版試玩發布 3月13日發售

使用jQuery的常用方法與返回值分析 jQuery是一個輕量級的JavaScript庫&#xff0c;旨在簡化HTML文檔遍歷和操作、事件處理以及動畫效果的創建。本文將介紹一些常用的jQuery方法及其返回值&#xff0c;幫助開發者更好地理解和運用這一強大的庫。 1. 選擇器方法 jQuery提供了多種…

[特殊字符] 認識用戶手冊用戶手冊(也稱用戶指南、產品手冊)是通過對產品功能的清

一份優秀的用戶手冊能有效降低用戶的使用門檻&#xff0c;提升用戶體驗和工作效率。下面我將為你梳理編寫用戶手冊的核心要點、步驟和技巧。&#x1f4d6; 認識用戶手冊用戶手冊&#xff08;也稱用戶指南、產品手冊&#xff09;是??通過對產品功能的清晰解釋&#xff0c;為特…

蘋果軟件代碼混淆,iOS混淆、iOS加固、ipa安全與合規取證注意事項(實戰指南)

在移動軟件交付與合規審計中&#xff0c;蘋果軟件代碼混淆已成為保護知識產權與用戶數據的常規手段。但混淆帶來的不僅是逆向難度的提升&#xff0c;也會觸發崩潰取證、符號化&#xff08;symbolication&#xff09;、審計合規與法律證據保存等問題。本文從工程與合規雙視角出發…

Redis框架詳解

目錄 1. redis是什么 主要特點 2. redis中存儲的數據類型 2.1 String類型 2.2 List類型 2.3 Hash類型 2.4 Set類型 2.5 Zset類型 2.6 其它類型 3.redis高可用框架 1. redis是什么 Redis 是一個開源的、基于內存的數據結構存儲系統&#xff0c;是 Remote Dictionary…

每日隨機展示10個wordpress置頂文章

WordPress 置頂文章是博主根據自己的需要設置的&#xff0c;通常用于展示重要或熱門的文章。 以下是一個示例代碼&#xff0c;用于在 WordPress 主題中展示 10 個置頂文章&#xff1a; <?php // 查詢置頂文章 $sticky get_option(sticky_posts); $args array(post__in …

金融工程vs金融數學:誰更貼近量化交易?

在金融行業邁向高度數字化的今天&#xff0c;量化交易已成為頂尖金融機構的核心競爭力之一。它以數學模型為基礎&#xff0c;借助編程技術實現策略自動化&#xff0c;在高頻、中低頻、套利、因子投資等多個領域展現出強大生命力。對于有志于此的大學生而言&#xff0c;選擇一個…

實測AI Ping,一個大模型服務選型的實用工具

作為一名長期奮戰在一線的AI應用工程師&#xff0c;我在技術選型中最頭疼的問題就是&#xff1a;“這個模型服務的真實性能到底如何&#xff1f;” 官方的基準測試總是在理想環境下進行&#xff0c;而一旦投入使用&#xff0c;延遲波動、吞吐下降、高峰期服務不可用等問題就接踵…

深信服軟件:aTrustAgent異常占用問題處理

問題&#xff1a;aTrustAgent占用CPU 大早上開電腦&#xff0c;風扇轉的飛起&#xff0c;任務管理器看&#xff0c;發現是有幾個 aTrustAgent 進程搞得鬼。 印象中&#xff0c;好像沒有裝過這個軟件&#xff0c;搜了下&#xff0c;是深信服的軟件&#xff0c;不知道是不是裝哪…

基于國產銀河麒麟服務器SP3項目實戰(Nginx+Keepalive)實現高可用負載均衡

一、環境準備 192.168.113.11NginxKeepalive(Master)192.168.113.22Nginxkeepalive(Backup)192.168.113.33Nginx(web服務器)192.168.113.44 Nginx(服務器&#xff09; 二、環境搭建準備 2.1 Nginx源碼編譯安裝 參考作責之前發布《Nginx源碼編譯安裝》https://blog.csdn.net…