我有一个继承自 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
中设置源代码 .
连接 widthChanged
和 heightChanged
信号非常频繁地调整我的项目,我不想再执行我的代码 .
有没有办法从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
width
和 height
中是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
parent
是 Window
的 contentItem
. 当我更换
width: parent.width
height: parent.height
至:
width: wnd.width
height: wnd.height
它工作得很完美,在我的 void MyQQuickItem::componentComplete()
中我按照预期初始化了 width
和 height
.
我不明白的一件事是 Window
onCompleted
, contentItem
大小是正确的,但在 MyQQuickItem
onCompleted
中大小为0,0 . 如果有人能向我解释,我将不胜感激:P
2 回答
Qt code使用componentComplete()如下:
您可以执行类似的操作,将
resizeContent()
替换为适用于width
和height
的函数 . 假设每当source
更改时也会调用该函数,则需要isComponentComplete()
检查 . 使用这种方法,您不应该有任何问题 .您可以继承QQmlParserStatus并实现componentComplete() .
componentComplete()将由QML引擎自动调用 .