首页 文章

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

提问于
浏览
0

我有一个继承自 QQuickItem 的类,而我正在运行它的 width height 属性 . 我也暴露了我自己的 property .

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 属性,但是在第一次发射时它们尚未初始化,并且在我的NOTIFY信号之后调用 Component.onCompleted .

通过调用isComponentComplete然后执行我的代码,我可以检查组件是否准备好,然后执行我的代码,但是当它发生时我无法找到并且当它不是时跳过 source 的初始值 .

当然我可以创建插槽 'itemReady' 并从 Component.onCompleted 调用它,但我有很多QML使用我的类,我将来会创建更多,所以我不想做复制粘贴工作 .

我也不想在 Component.onCompleted 中设置源代码 .

连接 widthChangedheightChanged 信号非常频繁地调整我的项目,我不想再执行我的代码 .

有没有办法从C获得 completed 信号?

EDIT:

我做了@Mitch说 - overriten componentComplete方法和里面,称它的基类equavilent . isComponentComplete() 返回true,但我仍然从 width()height() 方法得到0:

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

}

实际上我发现QML中的 Component.onCompleted 也打印0:

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

@derM Component.onCompleted 没有被 QQuickItem::componentComplete() 直接发送,因为它在上面的c中的qDebug之后打印了它的日志 .

因此,虽然它已准备就绪,但属性未初始化 .

EDIT2:

最后我解决了 . Window是有罪的,因为它使用 contentItem 作为他孩子的父母,并且在他的父母的MyQQuickItem Component.onCompleted widthheight 中是0 .

当我这样做时:

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

所以 MyQQuickItem parentWindowcontentItem . 当我更换

width: parent.width
height: parent.height

至:

width: wnd.width
height: wnd.height

它工作得很完美,在我的 void MyQQuickItem::componentComplete() 中我按照预期初始化了 widthheight .

我不明白的一件事是 Window onCompletedcontentItem 大小是正确的,但在 MyQQuickItem onCompleted 中大小为0,0 . 如果有人能向我解释,我将不胜感激:P

2 回答

  • 2

    Qt code使用componentComplete()如下:

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

    您可以执行类似的操作,将 resizeContent() 替换为适用于 widthheight 的函数 . 假设每当 source 更改时也会调用该函数,则需要 isComponentComplete() 检查 . 使用这种方法,您不应该有任何问题 .

  • -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引擎自动调用 .

相关问题