StupidBeauty
Read times:763Posted at:Mon Jul 3 08:32:15 2023 - no title specified

Qt 6.5文档翻译:Qt QML/将C++中的状态信息暴露给QML模块,Exposing State from C++ to QML

我们通常会需要将C++模块中的某些属性暴露给:某个特定组件中的全部QML 元素;某个模块中的全部QML 元素;甚至就是所有模块中全部的QML 元素。你可以采用两种方法来达到这一目的:引入单实例对象;或是向选定的组件的根对象添加属性。

使用单实例对象

如果你想向某个模块中的全部元素暴露一些全局属性,甚至就是想要向任何模块中全部的元素暴露一些全局属性,那么,你可以在C++代码中定义一个单实例对象。具体的做法就是,向某个类的定义中加入QML_ELEMENTQML_NAMED_ELEMENT任意一个宏,并加入QML_SINGLETON这个宏,再将你想要暴露的属性声明为Q_PROPERTY

// Singleton.h

class Singleton : public QObject

{

Q_OBJECT

Q_PROPERTY( int thing READ thing WRITE setThing NOTIFY thingChanged FINAL)

QML_ELEMENT

QML_SINGLETON

public :

Singleton ( QObject *parent = nullptr ) : QObject (parent) {}

int thing() const { return m_value; }

void setThing( int v)

{

if (v != m_value) {

m_value = v;

emit thingChanged();

}

}

signals:

void thingChanged();

private :

int m_value = 12 ;

};

接下来,你就可以在任何已经引入了该模块的QML 代码中访问到这个单实例的thing属性了:

import QtQml

QtObject {

objectName: "The thing is " + Singleton .thing

}

如果你将那些QML 文件放置在与该模块相同的目录下(强烈建议这么做),那么,该实例就会因你的模块的隐式引入而自动可用。你不需要显式地引入任何东西。如果不是这样放置的,或者说,你想要在其它模块中访问到thing属性,那么,你就需要引入该实例所从属的那个模块了。

要想通过C++代码来设置该属性的值,你需要获取这个单实例。你可以通过QQmlEngine::singletonInstance来做到这一点。建议你提供一个模块名和类型名作为参数:

Singleton *singleton

= engine->singletonInstance< Singleton *>( "MyModule" , "Singleton" );

singleton->setThing( 77 );

使用对象属性

如果你只是想向某个特定的组件中的QML 元素来暴露某些属性,那么,你可以将它们添加为该组件的根元素的常规属性。为了确保它们的值一定会被设置,你可以将它们声明为 必需属性 。具体可在QML 组件中这样写:

pragma ComponentBehavior : Bound

import QtQuick

Window {

id: root

visible: true

required property int thing

Text {

anchors.fill: parent

text: "The thing is " + root.thing

}

component Inner : QtObject {

objectName: "I can see " + root.thing + " because I'm bound."

}

}

我们为该组件的根元素设置了一个标识符(ID),并且在内层对象中通过标识符和名字来访问该属性。为了确保根元素的标识符能够在任何嵌套组件中访问到,我们使用了组件行为定义(ComponentBehavior)。

接下来,在C++中,每当你创建这种组件的一个对象时,你就必须使用QQmlComponent::createWithInitialPropertiesQQmlApplicationEngine::setInitialPropertiesQQuickView::setInitialProperties来对指定的属性进行初始化。例如:

QQmlEngine engine;

QQmlComponent component(&engine, "MyModule" , "RequiredProperties" );

QScopedPointer < QObject > o(component.createWithInitialProperties({

{ "thing" , 11 }

}));

这里,我们假设,你的模块的标识地址(URI)是MyModule,并且该模块可以通过QML 引用路径访问到。

Your opinions

Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands