是否可以从 C++ 访问 QML 锚点?

Is it possible to access QML anchors from C++?

从 C++ 代码创建 QML QQuickItems 时,是否可以 access/modify anchors?

所有 anchors 属性在 QQuickItem 中声明为 Q_PRIVATE_PROPERTY,我没有看到任何有用的方法。

或者我必须使用 signals/events 和 QLayout 自己实现 anchors 吗?

我需要的是例如:

Rectangle {
    // ...
    anchors.bottom: parent.bottom
    anchors.bottomMargin: 0
    anchors.top: parent.top
    anchors.topMargin: 0
    anchors.right: parent.right
    anchors.rightMargin: -10
    // ...
}   

实际上有一个 class 用于锚点。即QQuickAnchors位于QtQuick/private/qquickanchors_p_p.h,处理它们属于QQuickItemPrivate。但是由于两个 class 都不是 public API 的一部分,所以答案是:不,您不能从 C++ 中访问或修改锚点。

我会认为这个很好的 API 设计而不是限制。它迫使您在 QML 中管理视觉属性。因此,与其通过 new QQmlComponent() 从 C++ 创建 QML 组件,我建议直接在 QML 中使用已注册的自定义类型(可以使用 Repeater and/or Loader 组件静态或动态完成),您可以从那里访问 Itemanchors 和所有其他视觉属性。

对于绑定到父级的锚点,我发现以下解决方案可以解决 "setting anchors.fill: parent from c++" 当您无法在 QML 中实例化自定义类型时出现的问题(例如,您必须提供clean API 以动态创建 QML 对象):

class MyItem : public QQuickItem {
    Q_OBJECT

public:
    explicit MyItem(QQuickItem* parent){
        if(parent){
            connect(parent, SIGNAL(widthChanged()), this, SLOT(parentWidthChanged()));
            connect(parent, SIGNAL(heightChanged()), this, SLOT(parentHeightChanged()));
            setWidth(parent->width());
            setHeight(parent->height());
        }
        else
            qWarning() << "MyItem must be initialized with a parent.";
    }

private slots:
    void parentWidthChanged(){
        setWidth(parentItem()->width());
    }
    void parentHeightChanged(){
        setHeight(parentItem()->height());
    }
};

可以按照类似的逻辑来模拟anchors.topanchors.bottom等,并通过人工计算关联margin,也可能需要setX()setY()来实现这个。

与之前的答案所表明的不同,它是可能的并且有有效的用例。所有 Qt 对象,甚至是私有对象,都有内省 API。您从 QML 引擎使用的那些 API。它们也可以在 C++ 中使用:

qvariant_cast<QObject*>(
    item->property("anchors")
)->setProperty("top", otherItem->property("bottom"));

请注意,由于涉及某些线程,因此存在竞争条件。

QML 仅支持模型列表。显示树或 table 等其他结构要么实施不当(QtQuickControls 1.x),要么效率低得令人难以置信(递归转发器)。对于一些数据结构,C++也是正确实现延迟加载的唯一途径。 QML Loader 走了很长一段路,但不是一路走来。