【qml-3】qml與c++交互第二次嘗試(類型方式)

背景:

【qml-1】qml與c++交互第一次嘗試(實例方式)

【qml-2】嘗試一個有模式的qml彈窗-CSDN博客

?【qml-3】qml與c++交互第二次嘗試(類型方式)

還是qml學習筆記。

這次擱置太久了。其實不太會,還是以教程為主,但講課那哥們也是以嘗試為主,只是人家經驗多。這里吐槽一下,qml目前還是差太多。

官方手冊都啥也不是,遠不如widget完善好用。版本差異有些挺大,比如學了5再用6,有些真不一樣。我干脆從最新的6開始搞,因為5早晚淘汰。

寫代碼時有些屬性明明能用,但就是報錯說非法,你得按住ctrl轉到類型定義,還不能跳轉到頭文件,彈窗報錯但能復制那個頭文件的名,然后去文件系統qt安裝目錄里找到它再參考,發現里面有這個屬性可以用。

先吐槽這些,也許是自己太笨。

回顧:

之前寫過實例方式的qml和c++交互。

【qml-1】qml與c++交互第一次嘗試(實例方式)

亦即,在c++里直接把類型實例化,把對象指針注冊到qml上下文,然后qml直接調用它。

這種方式倒是直截了當,但是從qml里看有些晦澀,冷不丁出來個對象名,拿來就用。

個人感覺這種方式還可以,適合規模小的項目,簡單高效。

類型方式:

本次記錄的是類型方式,亦即把c++里寫好的類,不實例化,而是把類型注冊給qml,就像它自己的Button、Item一樣,用的時候使用“{}”給它實例化。這么說起來好像更合適一些。那就上demo。

quick項目說明:

這里要插入一段,我覺得按照官方態度,應該是讓咱們用Design Studio(DS)做ui,導出到c++的quick項目再混合編程。

這個該死的DS熟悉起來別具一格,等有時間再整理。這里主要說quick項目。

如上圖,兩種類型,圖上選中的是分類類型,構建后qml文件會復制到build目錄,發布時跟著exe一起,前后端分離。好處是可以隨時改qml不用編譯exe,不好就是所謂不安全。

compat那個是把qml放到qrc資源文件,它就一起編譯進exe發布,所謂更安全。

隱約記著其實web也有這種概念,以前做c#全棧,我們都是上傳aspx,改著方便。

這次demo我選的分離方式,無所謂,改一下很簡單。

demo:

如上所說我選的不帶compat的quick項目,一路下一步就行,它默認是cmake方式構建。

如上圖,我已經添加了一個MyClass類。代碼如下:

#ifndef MYCLASS_H
#define MYCLASS_H#include <QObject>
#include <QQmlEngine>
#include <QDebug>class MyClass : public QObject
{Q_OBJECTQML_ELEMENT
public:explicit MyClass(QObject *parent = nullptr);public slots:QString onFunc(){qDebug() << "slot in cpp";return "cpp value";}void onFromQml_GetValue(){qDebug() << "onFromQml_GetValue";emit sigToQml_SendValue("cpp_value");}signals:void sigToQml_SendValue(QString);
};#endif // MYCLASS_H
#include "myclass.h"MyClass::MyClass(QObject *parent): QObject{parent}
{qDebug() << "Class is created in cpp.";
}

已經盡量簡單了。主要為了驗證一些事。

上面QString onFunc()這個槽函數加了返回值。各位應該記得,qt手冊里講過,connect的隊列模式下信號是拿不到返回值的,因為是異步。只有direct和阻塞隊列方式可以,也容易理解。這里不深究qt手冊了,您可以自己看,要是我記錯了咱再討論。我這里就是為了驗證qml和c++之間是個啥情況。

onFromQml_GetValue槽函數就再正常不過了,不多解釋。就是讓它接受qml發來的信號,再把“返回值”發給qml。我就是想實現qml調用c++,比如查詢。

再看qml代碼:

import QtQuick
import QtQuick.Controls
import cpp.MyClassWindow {id: rootwidth: 640height: 480visible: truetitle: qsTr("Hello World")//qml查詢信號signal sigToCpp_GetValueonSigToCpp_GetValue: {myclass.onFromQml_GetValue();}//c++返回信號Connections {target: myclass//以下兩種方式都可以,非要共存那就下面的傳統方式優先,我試出來的。//Connections里面,function方式推薦,官方已經不推薦傳統方式了。        function onSigToQml_SendValue(s) {btn.text = s;print("-----" + s);}// onSigToQml_SendValue: (s) => { root.title = s; }}//C++實例化MyClass {id: myclass}Button {id: btnwidth:  100height: 40text: "press me"onClicked: {// text = myclass.onFunc();//這是可以的sigToCpp_GetValue();//發送qml信號}}
}

CMakeLists.txt

...
qt_add_executable(appuntitledmain.cpp# myclass.h myclass.cpp #注意這里
)qt_add_qml_module(appuntitledURI cpp.MyClass #注意這里VERSION 1.0QML_FILESMain.qmlSOURCES myclass.h myclass.cpp #注意這里
)
...

對于CMakeList.txt的內容,說明一下。在qml分離方式的項目中添加類,它會在CMakeLists.txt中把頭文件和源文件加到qt_add_qml_module函數中,在qml資源方式的項目中,它會加到qt_add_executable函數中。親測效果沒影響,但是個人感覺加在qt_add_executable中更合適。這算一個討論點。因為目前我沒試出來區別。

注意,cmake里設置的URI是qml里import時用的模塊,同時對應build目錄中那個擴展名是qmltypes的文件路徑。至于自己定義的c++類名,和這個沒有直接關系。如果有多個c++類要為qml服務,可以都加到某個模塊中。就像QtQuick.Controls一樣,里面有好多類。

我之前以為,C++里只要寫了那個QML_ELEMENT宏就可以自動實現了,但不幸還得改cmake文件,這個URI是個地址,對應build目錄里的情況。

之前默認可不是這樣的,qt會默認一個untitile,你把它改成自己想要的就行了。當然對應main函數也要改。

因為項目選擇的是分離模式,理論上qml是不參與編譯,而是單獨的文件,所以這里寫的路徑其實對應build目錄里的文件路徑,發布時一并復制給目標機即可。

(我實測結果大相徑庭!qrc模式的exe編譯出來很小,一個文件包括所有,感覺很快很好用。分離模式exe很大,編譯很慢,也并不是所有qml文件復制過去修改就生效,我試出來的也就第一個加載的qml可以,其余被調用的qml修改不能反應到界面,跟想象差距太大,個人感覺非常難用。希望用qml做過大項目的朋友指點。或者以后總結出經驗再專門寫筆記。)

效果:

沒問題的,就是點擊按鈕,由qml向c++發送請求,c++返回數據。

解析:

其實最直接簡單的方式就是直接調c++的槽函數就行了,可以帶返回值,目前感覺最方便。

之前我以為普通函數也可以,實測不行,必須是槽函數。(后面有補充Q_INVOKABLE)

非要發信號走個流程就是上面那樣,跟第一篇博客(實例方式)一樣道理。就是實例化的時機不一樣。

問題:

無論是哪種方式的項目,看教程以及我親測都會有個問題。每次做完了運行不影響,但qml文件里總有警告,以下三步操作后警告會消失,不一定第幾步有效。

1、先運行一下,讓它生成build目錄,尋址需要。

2、關閉項目,重新打開項目。

3、關閉creator,重新打開。

到這里忍不住還是要吐槽,這可不是我一個人的問題,教程視頻里也是如此。還是不完善。您說呢?

補充:

上面說直接調用c++普通函數不行,其實是如果是普通函數,聲明時需要在前面加一個宏Q_INVOKABLE。具體看手冊吧,這個宏的意義就是讓函數可以被元對象系統調用。熟悉qt信號槽的朋友到這里應該明白原因了。qt推崇的松散耦合就是信號槽,元對象系統實現的,qml這種前后端分離的東西顯然也是基于元對象的信號槽。這就是為什么直接調用普通函數不可以,而是要加上這個宏。

先記錄到這里,本文完。

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

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

相關文章

輸電線路觀冰精靈在線監測裝置:科技賦能電網安全的新利器

一、技術架構與工作原理輸電線路觀冰精靈在線監測裝置&#xff08;簡稱“觀冰精靈”&#xff09;是一款集成多源感知、智能分析、遠程通信于一體的專業化覆冰監測設備。其核心功能通過以下技術路徑實現&#xff1a;1. 數據采集模塊視覺識別系統&#xff1a;搭載工業級夜視攝像機…

Ubuntu22 上,用C++ gSoap 創建一個簡單的webservice

創建calc.h// calc.h // gSOAP 服務定義 int ns__add(double a, double b, double &result); int ns__subtract(double a, double b, double &result);創建my_server.cpp#include "soapService.h" #include "ns.nsmap" class MyService : public S…

Java(LinkedList和ArrayList底層分析)

LinkedList全面說明:LinkedList底層操作機制:LinkedList的方法:add():增加節點對象remove():刪除一個節點對象(默認刪除第一個節點對象)set():修改一個節點對象get():得到一個節點對象LinkedList的遍歷:增強for循環迭代器普通for循化LinkedList的源碼解讀:增加源碼:1. LinkedLi…

開源項目XBuilder的user邏輯

stores \ userquery-keys.ts 統一管理Vue Query&#xff08;TanStack Query的Vue適配版本&#xff09;緩存鍵&#xff0c;在下面的文件中復用index.ts 入口文件&#xff0c;統一用戶信息查詢signed-in.ts 登錄狀態管理、認證邏輯在用戶登錄后&#xff0c;系統頒發一個令牌&…

第十五章 SEO的簡單免費工具

SEO的基礎工具和檢測 前文中主要是講一些SEO的網站基本功&#xff0c;而在這一章那&#xff0c;會講到一些非常基本的工具&#xff0c;主要是關于&#xff1a;網站的流量、停留時長、關鍵詞密度、內容、以及Google的站長工具。 Google Search Console Google Search Console這是…

SSL 證書與 HTTPS 的關系:一文理清核心關聯

HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;和 SSL 證書&#xff08;Secure Sockets Layer Certificate&#xff09;是網絡安全的兩大基石&#xff0c;它們共同保障了互聯網通信的安全性和可信度。以下從定義、功能、關系及實際應用層面進行解析&#xf…

使用Jmeter參數化實現接口自動化測試

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 本文記錄如何使用Jmeter參數化&#xff08;csv)實現接口自動化——測試Token不同入參情況下&#xff0c;接口請求能夠返回正確的結果1. 首先需要使用Jmeter獲取一個…

X-plore File Manager v4.34.02 修改版:安卓設備上的全能文件管理器

在使用安卓設備時&#xff0c;文件管理是日常操作中不可或缺的一部分。X-plore File Manager 作為一款功能強大的文件管理器&#xff0c;憑借其豐富的功能和便捷的操作&#xff0c;成為安卓用戶管理文件的首選工具之一。最新版 v4.34.02 修改版更是解鎖了更多高級功能&#xff…

React+threejs兩種3D多場景渲染方案

在現代 Web 開發中&#xff0c;3D 可視化需求日益增長&#xff0c;特別是在 React 生態系統中實現多 3D 場景的展示與交互。本文通過對比兩種實現方案&#xff0c;探討 React 中構建多 3D 場景的最佳實踐&#xff0c;分析它們的技術特點、性能表現和適用場景。方案一&#xff1…

React性能優化終極指南:memo、useCallback、useMemo全解析

掌握 React.memo、useCallback、useMemo 的正確使用姿勢&#xff0c;讓你的 React 應用性能飛起來&#xff01; &#x1f3af; React.memo 作用 React.memo 是一個高階組件&#xff0c;用于函數組件&#xff0c;通過淺比較 props 的變化來決定是否重新渲染。如果 props 沒有變…

借助 VR 消防技術開展應急演練,檢驗完善應急預案?

應急演練是企業應對火災事故的重要手段&#xff0c;而 VR 消防技術的應用&#xff0c;為應急演練帶來了全新的體驗和更高的效率。VR 消防技術通過虛擬現實技術模擬逼真的火災場景&#xff0c;讓參與者能夠身臨其境地感受火災發生時的緊張氛圍。某知名物流企業&#xff0c;倉庫眾…

【電賽學習筆記】MaxiCAM 項目實踐——二維云臺追蹤指定目標

前言 本文是對視覺模塊MaixCam實現二維云臺人臉跟蹤_嗶哩嗶哩_bilibili大佬的項目實踐整理與拓展&#xff0c;侵權即刪。 單路舵機基本控制 #導入必要模塊 from maix import pwm, time , pinmap#定義全局變量&#xff0c;設初值 SERVO_FREQ 50 #主頻 SERVO_MIN_DUT…

深入解析 ArkUI 觸摸事件機制:從點擊到滑動的開發全流程

摘要 隨著 HarmonyOS NEXT 的不斷發展&#xff0c;ArkUI 逐漸成為主流的 UI 構建方式。而用戶交互在任何應用中都是基礎而又關鍵的一環&#xff0c;如何利用 ArkUI 提供的觸摸事件機制&#xff0c;如 onTouch、onClick、onSwipe 等&#xff0c;來實現自然、順滑、用戶友好的交互…

Tailwind CSS 自定義工具類與主題配置指南

一、自定義工具類配置在 src/tailwind.css 文件中&#xff0c;我們可以通過 layer utilities 指令添加自定義工具類&#xff1a;tailwind base; tailwind components; tailwind utilities;layer utilities {/* 自定義工具 上下浮動效果 */.animate-floatY {animation: floatY 3…

【代碼隨想錄二刷|704.二分查找、27.移除元素、977.有序數組的平方】

704.二分查找 題目鏈接&#xff1a;704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int search(vector<int>& nums, int target) {//不用二分查找&#xff0c;直接求// for(int i0;i<nums.size();i){// if(nums[i]target)…

基于Vue的工業設備大屏可視化模板(含設備地圖分布+宣傳模塊+報表展示+三維模型加載預覽)

場景 為實現工業設備可視化大屏需求&#xff0c;可實現基于地圖的設備數據管理&#xff0c;點擊具體設備可進行詳細介紹和三維模型展示。 可播放宣傳視頻&#xff0c;可展示PM數據報表等數據&#xff0c;可接受報警數據提醒、統計等數據。 基于現有開源平臺框架進行二次改造…

堆(Heap)優先級隊列(Priority Queue)

一、堆的概念堆&#xff08;Heap&#xff09;是一種特殊的基于樹的數據結構&#xff0c;通常分為最大堆和最小堆兩種類型。它滿足堆屬性&#xff1a;對于最大堆&#xff0c;父節點的值總是大于或等于其子節點的值&#xff1b;而對于最小堆&#xff0c;父節點的值總是小于或等于…

踩坑記錄:因版本不匹配導致 Boost 1.85 編譯失敗的完整解決過程

踩坑記錄&#xff1a;因版本不匹配導致 Boost 1.85 編譯失敗的完整解決過程 轉載請注明出處&#xff0c;歡迎評論區交流。 背景 最近在 Windows 11 VS2022 環境下嘗試用 b2 編譯 Boost 1.85.0&#xff0c;結果一路踩坑&#xff0c;最后發現罪魁禍首是 Boost.Build 自帶的 msv…

InfluxDB Line Protocol 協議深度剖析(二)

四、Line Protocol 寫入操作與實踐&#xff08;一&#xff09;HTTP API 寫入使用 HTTP API 是通過 Line Protocol 寫入數據到 InfluxDB 的常用方式。InfluxDB 1.x&#xff1a;請求方式為 POST&#xff0c;URL 格式為 “http://host:port/write?dbdatabase_name”。其中&#x…

負載均衡:提升業務性能的關鍵技術

一.負載均衡&#xff08;3.6 &#xff09;1.1.什么是負載均衡&#xff1a;負載均衡&#xff1a;Load Balance&#xff0c;簡稱LB&#xff0c;是一種服務或基于硬件設備等實現的高可用反向代理技術&#xff0c;負載均 衡將特定的業務(web服務、網絡流量等)分擔給指定的一個或多個…