c++ - 如何找出 QQuickItem 派生类对象何时初始化?

标签 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 获取 widthheight 之前检查组件是否准备就绪 |并在它发生时执行我的代码,但我无法确定它何时发生并且 source 的初始值在它不发生时被跳过。

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

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

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

有什么方法可以从 C++ 获取 completed 信号吗?

编辑:

我按照@Mitch 所说的做了 - 覆盖 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 之后打印了它的日志。

所以,虽然已经准备好了,但是属性还没有初始化。

编辑 2:

终于解决了。 Window是有罪的,因为它使用 contentItem 作为他 child 的 parent ,并且在 MyQQuickItem Component.onCompleted widthheight contentItem(他的父项)的 > 为 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 onCompleted 中,contentItem 大小是正确的,但在 MyQQuickItem onCompleted 大小为 0,0。如果有人能给我解释一下,我将不胜感激:P

最佳答案

Qt code使用 componentComplete()像这样:

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

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

关于c++ - 如何找出 QQuickItem 派生类对象何时初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46328429/

相关文章:

xcode - 从一开始逐步逐步/最快的方法到在OS X上 “code sign”我的Qt应用程序是什么,以便可以分发?

qml - ListView 突出显示项目未显示

c++ - Qt QML 数据模型似乎不适用于 C++

javascript - QML Canvas - 为什么 requestPaint() 函数不调用绘画?

C++/Qt : passing variables to be changed in the class

c++ - 没有从 'value_type'(又名 'char')到 'string'(又名 'basic_string<char, char_traits<char>, allocator<char>>')的可行转换

c++ - 在C++中,当手指在触摸屏上移动时如何更改标签文本?

c++ - 是否可以在 QCalendarWidget 中禁用星期六和星期日?

c++ - 是否可以在没有接收器实例的情况下将信号连接到静态插槽?

c++ - 类的函数声明后的 "default"是什么意思?