在QML中,我有一个自定义对象类型(一个单独的QML文件),我想要一种访问和/或修改此类型的每个实例的方法。举个简单的例子:
MyText.qml:
Text {
height: 100
width: 100
color: "red"
function logStuff() {
console.log("This is MyText")
}
}
SomePage.qml:
MyText {
id: text1
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
text: "foo"
}
MyText {
id: text2
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: "bar"
}
当事件发生时(例如,单击SomePage.qml上的按钮或发出信号),我希望能够将MyText的所有实例更改为具有相同的一个属性值,或者调用每个MyText的{ {1}}功能。
注意:在我的实际用例中,实际上有几十个这样的实例,并且还有其他Text元素不是MyText的实例。
我对jQuery有一点经验,并希望有类似于jQuery选择器的东西,但我一直无法找到任何类似的东西。无论是QML还是C ++(或混合)解决方案都可以。
答案 0 :(得分:2)
我想建议一个使用C ++的方法。
由于无法获得QML
对象的基类,因此您可以将搜索基于objectName
属性,可以在C ++中访问。
假设我们有基础QML
对象:
import QtQuick 2.3
Item {
id: base
objectName: "BaseItem"
property int someValue: 0
onSomeValueChanged: {
console.log("'someValue' was changed to " + someValue + " for " + base);
}
}
另一个使用这些对象的QML文件:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
width: 300
height: 300
id: mainWindow
Base {
id: derived1
}
Base {
id: derived2
}
Base {
id: derived3
}
}
这个想法是所有派生对象都从基类继承相同的objectName
。
现在您可以在C++
中找到所有对象:
QObject *root = engine.rootObjects().first();
QList<QObject *> list = root->findChildren<QObject *>("BaseItem");
qsrand(QTime::currentTime().msec());
foreach(QObject *item,list) {
item->setProperty("someValue",qrand());
}
这里我只是更改属性,但您也可以使用QMetaObject::invokeMethod()
等调用某些方法。
答案 1 :(得分:1)
我不确定你是否理解你的需要,但我会像这样使用Connections元素:
SomePage.qml:
MyText {
id: text1
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
text: "foo"
Connections {
target: senderItemId
onFooChanged: logStuff()
}
}
MyText {
id: text2
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: "bar"
Connections {
target: senderItemId
onFooChanged: logStuff()
}
}
答案 2 :(得分:0)
Qt 中没有 API 调用来执行此操作(我可以找到),但是您可以通过在 C++ 中使用 QObject::children() 和 QMetaObject 的类型找到所有 QML QObject。下面是一个实现示例。
QList<QObject *> MySingleton::findObjectsOfComponent(QObject *parent, QQmlComponent *component) const
{
auto object = component->create(QQmlEngine::contextForObject(parent));
auto foundObjects = findObjectsOfObject(parent, object);
delete object;
return foundObjects;
}
QList<QObject *> MySingleton::findObjectsOfObject(QObject *parent, const QObject *object) const
{
auto className = object->metaObject()->className();
QList<QObject*> items;
for(auto child : parent->children()) {
if(child->metaObject()->className() == className) {
items.append(child);
}
items.append(findObjectsOfObject(child, object));
}
return items;
}
然后您应该将 MySingleton 注册为 QML 单例并使用组件来查找类型。
Component {
id: errorLabelComponentId
ErrorLabel {}
}
Button {
onClicked: {
//Un-ignore all error labels
var errorLabels = MySingleton.findObjectsOfComponent(pageId, errorLabelComponentId)
for(var i in errorLabels) {
//ignoreError is a property of ErrorLabel {}
errorLabels[i].ignoreError = false
}
}
}