如何找出QQuickItem派生类对象的初始化时间?

时间:2017-09-20 17:34:07

标签: c++ qt qml qtquick2

我的课程继承自QQuickItem,而且我在其width height属性内操作。我也暴露了我自己的财产。

class MyQQuickItem : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(QUrl source MEMBER m_source NOTIFY sourceChanged)

    public:
    explicit MyQQuickItem(QQuickItem *a_parent = Q_NULLPTR);
     ~PDFPage();

    signals:
    void sourceChanged(const QUrl a_source);

    private:
    QUrl m_source;
};

在qml中:

...
MyQQuickItem
{
    width: parent.width / 2
    height: parent.height
    source: "someSource"
    Component.onCompleted
    {
        console.log("component onCompleted");
    }
}

sourceChanged被安排时,我正在处理width height个属性,但是第一次发出时它们尚未初始化,并且Component.onCompleted在之后被调用我的NOTIFY信号。

我可以通过调用isComponentComplete来检查组件是否准备就绪,然后通过调用componentComplete并执行我的代码,但是我无法确定它何时发生如果不是,则跳过width的初始值。

当然我可以创建一个插槽height并从source调用它,但我有很多QML使用我的课程,我将来会创建更多,所以我不想制作复制粘贴工作。

我也不想在'itemReady'中设置来源。

连接到Component.onCompletedComponent.onCompleted信号也不是一个好主意,因为我经常调整项目大小,我不想执行我的项目代码然后。

有没有办法从C ++中获取widthChanged信号?

修改

我做了@Mitch说 - 重写Window方法和内部,称它为基类equavilent。 heightChanged返回true,但我仍然从completedisComponentComplete()方法获得0:

width()

实际上我发现QML中的height()也打印0:

void MyQQuickItem::componentComplete()
{
    QQuickItem::componentComplete();
    if(isComponentComplete())
    {
        qDebug() << "c++: oncompleted, width,height: " << width() << height(); //gives 0,0
    }

}

@derM Component.onCompleted没有被... MyQQuickItem { width: parent.width / 2 height: parent.height source: "someSource" Component.onCompleted { console.log("component onCompleted width, height: ", width, height); //it gives 0 too } } 直接发送,因为它在上面的c ++中的qDebug之后打印了它的日志。

因此,虽然它已准备好,但属性未初始化。

EDIT2:

最后我解决了这个问题。 ovation22有罪,因为它使用Component.onCompleted作为其子级的父级,并使用QQuickItem::componentComplete() contentItem Component.onCompletedwidth height他的父母)是0。

当我这样做时:

contentItem

打印:

Window
{
    id: wnd
    width: 640
    height: 480
    Component.onCompleted:
    {
        console.log("Window completed: ", this, width, height);
        console.log("windowContentItem: ", contentItem, width, height);
    }

    MyQQuickItem
    {
        width: parent.width
        height: parent.height
        Component.onCompleted:
        {
            console.log("MyQQuickItem completed: ", this, width, height);
            console.log("MyQQuickItem parent: ", parent, parent.width, parent.height);
        }
    }
}

所以qml: Window completed: QQuickWindowQmlImpl(0x345b5eb4d0) 640 480 qml: windowContentItem: QQuickRootItem(0x345e2cdec0) 640 480 qml: MyQQuickItem completed: MyQQuickItem(0x345b5b99e0) 0 0 qml: MyQQuickItem parent: QQuickRootItem(0x345e2cdec0) 0 0 MyQQuickItemparent&#39; s Window。当我更换

contentItem

为:

width: parent.width
height: parent.height

效果很好,在我的width: wnd.width height: wnd.height 我已按预期初始化void MyQQuickItem::componentComplete()width

我不理解的一件事是height WindowonCompleted大小正确,但在contentItem MyQQuickItem中大小为0, 0。如果有人能向我解释,我将不胜感激:P

2 个答案:

答案 0 :(得分:2)

Qt code使用componentComplete(),如此:

void QQuickControl::componentComplete()
{
    Q_D(QQuickControl);
    QQuickItem::componentComplete();
    d->resizeContent();
    // ...
}

您可以执行类似操作,将resizeContent()替换为适用于widthheight的功能。假设在source发生变化时也会调用该函数,您需要进行isComponentComplete()检查。使用这种方法,你不应该有任何问题。

答案 1 :(得分:-1)

您可以继承QQmlParserStatus并实施componentComplete()。

class MyQQuickItem : public QQuickItem, public QQmlParserStatus
{
    Q_OBJECT
    Q_PROPERTY(QUrl source MEMBER m_source NOTIFY sourceChanged)

public:
    explicit MyQQuickItem(QQuickItem *a_parent = Q_NULLPTR);
    ~PDFPage();

    void classBegin();
    void componentComplete();

signals:
    void sourceChanged(const QUrl a_source);

private:
    QUrl m_source;
};

componentComplete()将由QML引擎自动调用。