在 C++ 中与 Repeater 中的委托 QML 组件交互
Interacting with delegated QML Component in Repeater from C++
我无法从 C++ 访问 Repeater 中的委托 QML 组件。请在下面找到代码。谢谢
main.cpp
#include <QApplication>
#include <QDebug>
#include <QQuickView>
#include <QQuickItem>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:/Main.qml")));
view.show();
QQuickItem *object = view.rootObject();
QObject *rectangle = object->findChild<QObject*>("rect1");
if (!rectangle)
qDebug() << "MyError: rectangle was not found";
app.exec();
}
Main.qml
import QtQuick 2.4
Row {
Repeater {
model: 3
Rectangle {
width: 50; height: 50
color: index %2 ? "black" : "white"
objectName: "rect" + index
}
}
}
控制台输出:
MyError: rectangle was not found
如果您调用 object->dumpObjectTree()
,您将看到类似于以下控制台输出的内容:
QQuickRow::
QQuickRepeater::
QQmlComponent::
如您所见,对象树不包含作为专用 qobject 的矩形。在我对 QML 方面的有限理解中,还有另一棵树包含所有可见的 qml items/components。这些你至少可以通过 qml 中的 'children'-属性 访问。为了证明这一点,我将您的 qml 文件更改为:
Main.qml:
Row {
id: row
Repeater {
model: 3
Rectangle {
width: 50; height: 50
color: index %2 ? "black" : "white"
objectName: "rect" + index
}
}
Component.onCompleted: {
console.log(row.children[0].objectName);
console.log(row.children[1].objectName);
console.log(row.children[2].objectName);
}
}
结果如下:
qml: rect0
qml: rect1
qml: rect2
MyError: rectangle was not found
当然直接访问和索引取决于你的额外items/components。从这里开始,您可以编写自己的递归 'findChild' 函数并将结果对象公开给 C++。这里描述如何:http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html
例如,您可以像这样在 qml 中实现 'findChild':
function findChild(propertyName, propertyValue) {
return findChildRecursivly(row, propertyName, propertyValue)
}
您可以像
一样从 C++ 调用此 qml 函数
QVariant result;
QMetaObject::invokeMethod(object, "findChild",
Q_RETURN_ARG(QVariant, result),
Q_ARG(QVariant, "objectName"),
Q_ARG(QVariant, "rect1"));
rectangle = result.value<QObject *>();
添加以下代码行:
if (!rectangle)
{
qDebug() << "MyError: rectangle was not found";
}
else
{
qDebug() << rectangle;
qDebug() << rectangle->objectName();
}
你得到以下输出:
QQuickRectangle(0x1c1beef, name = "rect1")
"rect1"
我已经在 C++ 中实现了自己的递归函数模板 'findChild' 函数。`
template <class T>
SearchType findChild(QQuickItem* object, const QString& objectName)
{
QList<QQuickItem*> children = object->childItems();
foreach (QQuickItem* item, children)
{
if (QQmlProperty::read(item, "objectName").toString() == objectName)
return item;
T child = findChild<QQuickItem*>(item, objectName);
if (child)
return child;
}
return nullptr;
}
并将其称为默认函数。
QQuickItem *object = view.rootObject();
QQuickItem *rectangle = findChild<QQuickItem*>(object, "rect1");
if (rectangle)
{
qDebug() << rectangle;
qDebug() << rectangle->objectName();
}
并得到输出:
QQuickRectangle(0x2222b40, name="rect1", parent=0x22245b0, geometry=50,0 50x50)
"rect1"
我无法从 C++ 访问 Repeater 中的委托 QML 组件。请在下面找到代码。谢谢
main.cpp
#include <QApplication>
#include <QDebug>
#include <QQuickView>
#include <QQuickItem>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:/Main.qml")));
view.show();
QQuickItem *object = view.rootObject();
QObject *rectangle = object->findChild<QObject*>("rect1");
if (!rectangle)
qDebug() << "MyError: rectangle was not found";
app.exec();
}
Main.qml
import QtQuick 2.4
Row {
Repeater {
model: 3
Rectangle {
width: 50; height: 50
color: index %2 ? "black" : "white"
objectName: "rect" + index
}
}
}
控制台输出:
MyError: rectangle was not found
如果您调用 object->dumpObjectTree()
,您将看到类似于以下控制台输出的内容:
QQuickRow::
QQuickRepeater::
QQmlComponent::
如您所见,对象树不包含作为专用 qobject 的矩形。在我对 QML 方面的有限理解中,还有另一棵树包含所有可见的 qml items/components。这些你至少可以通过 qml 中的 'children'-属性 访问。为了证明这一点,我将您的 qml 文件更改为:
Main.qml:
Row {
id: row
Repeater {
model: 3
Rectangle {
width: 50; height: 50
color: index %2 ? "black" : "white"
objectName: "rect" + index
}
}
Component.onCompleted: {
console.log(row.children[0].objectName);
console.log(row.children[1].objectName);
console.log(row.children[2].objectName);
}
}
结果如下:
qml: rect0
qml: rect1
qml: rect2
MyError: rectangle was not found
当然直接访问和索引取决于你的额外items/components。从这里开始,您可以编写自己的递归 'findChild' 函数并将结果对象公开给 C++。这里描述如何:http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html
例如,您可以像这样在 qml 中实现 'findChild':
function findChild(propertyName, propertyValue) {
return findChildRecursivly(row, propertyName, propertyValue)
}
您可以像
一样从 C++ 调用此 qml 函数QVariant result;
QMetaObject::invokeMethod(object, "findChild",
Q_RETURN_ARG(QVariant, result),
Q_ARG(QVariant, "objectName"),
Q_ARG(QVariant, "rect1"));
rectangle = result.value<QObject *>();
添加以下代码行:
if (!rectangle)
{
qDebug() << "MyError: rectangle was not found";
}
else
{
qDebug() << rectangle;
qDebug() << rectangle->objectName();
}
你得到以下输出:
QQuickRectangle(0x1c1beef, name = "rect1")
"rect1"
我已经在 C++ 中实现了自己的递归函数模板 'findChild' 函数。`
template <class T>
SearchType findChild(QQuickItem* object, const QString& objectName)
{
QList<QQuickItem*> children = object->childItems();
foreach (QQuickItem* item, children)
{
if (QQmlProperty::read(item, "objectName").toString() == objectName)
return item;
T child = findChild<QQuickItem*>(item, objectName);
if (child)
return child;
}
return nullptr;
}
并将其称为默认函数。
QQuickItem *object = view.rootObject();
QQuickItem *rectangle = findChild<QQuickItem*>(object, "rect1");
if (rectangle)
{
qDebug() << rectangle;
qDebug() << rectangle->objectName();
}
并得到输出:
QQuickRectangle(0x2222b40, name="rect1", parent=0x22245b0, geometry=50,0 50x50)
"rect1"