玩轉Qml 5 Qml與C 互動

2021-10-13 07:23:08 字數 3995 閱讀 3799

qml訪問c++

qml已經有很多功能,不過終歸會有不夠用或不適用的地方,需要通過與c++的互動進行功能擴充套件。

這回濤哥嘗試把所有qml與c++互動相關的知識點都寫出來,做乙個透徹、全面的總結。

《玩轉qml》系列文章,配套了乙個優秀的開源專案:taoquick

github

訪問不了或者速度太慢,可以用國內的映象**gitee

c++訪問qml有兩種方式: findchild和 qqmlcomponent。

了解qt的人都知道,qt的很多物件是qobject的子類,這些qobject只要設定了parent,就是有父子關係的,會產生一棵 「物件樹」。

只要有了根節點,樹上的任意節點都可以通過findchild的方式獲取到。

寫個簡單的taoobject,來示意一下:

class taoobject

}//析構函式,析構children。即子物件自動**機制。

~taoobject()

m_children.clear();

}//獲取name

const qstring &getname() const

//設定name

void setname(const qstring &name)

//查詢子object

taoobject *findchild(const qstring &name)

//遍歷子object,查詢

for (auto pobj : m_children)

}return nullptr;

}protected:

private:

//儲存名字

qstring m_name;

//子物件列表

std::vectorm_children;

//父物件指標

taoobject *m_pparent = nullptr;

};

qml的基本元素,大多是繼承於qquickitem,而qquickitem繼承於qobject。

所以qml大多數物件都是qobject的子類,也是可以通過findchild的方式獲取到物件指標。

拿到了qobject,可以通過qobject_cast轉換成具體的型別來使用,也可以直接用qobject的invok方法。

例如有如下qml**:

item 

}...

}

那麼在c++ 中訪問的方式是:

qquickview view;

...qobject *centerobj = view.rootobject()->findchild("centerrect");

if (!centerobj)

拿到了物件指標,接下來就好辦了

訪問其屬性

bool cansee = centerobj->property("cansee").tobool();
發射其訊號(其實就是函式呼叫)

qobject::invokemethod(centerobj, "sayhello");

qobject::invokemethod(centerobj, "sayhelloto", q_arg(qstring, "tao"))

呼叫其js函式,可以傳引數過去,可以取得返回值

bool ok;

qobject::invokemethod(centerobj, "rotatetoangle", q_return_arg(bool, ok), q_arg(qreal 180));

這裡再補充一下, qml中給自定義的訊號寫槽或連線到別的槽(qml中的槽就是js函式):

item 

onsayhello:

onsayhelloto:

component.oncompleted:

}...

function rootsayhello(name)

}

c++中的qqmlcomponent可以用來動態載入qml檔案,並可以建立多個例項,

對應qml中的component。qml中還有乙個loader,也可以動態載入並建立單個例項。

(qqmlcomponent這種方式不太多見,不過濤哥之前參與過開發乙個框架,使用的就是qqmlcomponent動態載入qml,

完全在c++中控制介面的載入,載入效率、記憶體占用上都比純qml優秀。)

來看乙個例子:

// circle.qml

rectangle

qqmlengine engine;

qqmlcomponent component(&engine, qurl::fromlocalfile("circle.qml"));

qobject *circleobject = component.create();

qquickitem *item = qobject_cast(circleobject);

int width = item->width();

拿到物件指標,就和前面的一樣了,這裡不再贅述了。

qml要訪問c++的內容,需要先從c++把要訪問的內容註冊進qml。

先說說能用哪些:

註冊過後,qml中可以訪問的內容,包括 q_invokable 修飾的函式、列舉、 qobject的屬性 訊號 槽

q_invokable 函式可以用在普通的結構體或者類中,但是這種用法不常見/不方便。常見的是在qobject的子類中,給非槽函式設定為q_invokable

列舉的註冊qt幫助文件很詳細,而且5.10以後可以在qml中定義列舉了,這裡濤哥就不展開了。

qobject的屬性 訊號 槽,都是可以通過註冊後,在qml中使用的。訊號、槽都可以帶引數,槽可以有返回值。

class brothertao : public qobject 

;

這裡要說的是,屬性、函式引數、返回值的型別,都需要是qml能識別的型別。

qt的常用型別已經在qt內部註冊好了,自定義的需要單獨註冊。

再說說怎麼用:

註冊分為兩種:註冊型別和註冊例項。

qmlregistertyle

("brothertao",1, 0, "brothertao");

import brothertao 1.0

item else if (foodname === "水餃") }}

...button

}button }}

brothertao tao;     //c++中建立的例項

//如果用qq'u'ic'kview載入qml

qquickview view;

...view.rootcontext()->setcontextproperty("tao", &tao); //注意這個名字不要用大寫字母開頭,規則和qml中的id不能用大寫字母開頭一樣。

//如果用qqmlengine載入qml

qqmlengine engine;

...engine..rootcontext()->setcontextproperty("tao", &tao); //注意這個名字不要用大寫字母開頭,規則和qml中的id不能用大寫字母開頭一樣。

//這種不用再import了

item else if (foodname === "水餃") }}

...button

}button }}

qml與C 的互動

簡單說下我自己對qml與c 的互動的理解流程 1.介面互動,很多新手可能會寫qt介面或者qml介面,但想要把qml與c 結合起來就一臉矇逼了。首先我提供個簡單的方法實現qml和c 的介面互動,首先引入幾個重要的標頭檔案,當然在專案檔案中需要加qt quickwidgets才能引用以下標頭檔案 inc...

QML如何與C 互動

大家都知道,qml作為構建介面的語言是非常簡潔的,但是介面的後台有些時候是經常要與c 互動的,那麼這個時候,如何與c 進行互動就尤為重要了,在這裡就需要用到 template int qmlregistertype const char uri,int versionmajor,int versio...

qml與C 的互動

qml與c 的互動,簡單說下我自己對qml與c 的互動的理解流程 1.介面互動,很多新手可能會寫qt介面或者qml介面,但要把qml與c 結合起來就一臉矇逼了。首先我提供個簡單的方法實現qml和c 的介面互動。首先引入幾個重要的標頭檔案 include include include widget ...