提问人:Zues 提问时间:11/9/2023 更新时间:11/10/2023 访问量:76
创建子QML组件后,Qt无法通过对象名称找到它
Qt can't find child QML Component by object name after it has been created
问:
我正在创建一个qml qt项目,该项目基于用户输入创建二进制文件,用于教育目的。你可以说我是qt的新手,但我确实知道一些基本概念。我正在使用递归函数创建一个具有用户输入值的二进制节点。递归函数检查使用二叉树的根节点输入的值,然后递归地继续,直到找到树中没有节点的位置。我只计算了这棵树的左侧,因此它仅适用于小于节点的值。以下是插入节点的算法:
void BinaryTree::insert_node(QQuickItem* parent_node, QString node_text) {
double node_value = node_text.toDouble();
root_node_value = parent_node->property("node_text").toInt();
if (node_value < root_node_value) {
if (!parent_node->property("has_left_node").toBool()) {
QQuickItem *left_node = create_binary_node(parent_node, node_text, "left_node");
QObject *node_anchors = qvariant_cast<QObject*>(left_node->property("anchors"));
node_anchors->setProperty("right", parent_node->property("right"));
node_anchors->setProperty("rightMargin", 60);
left_node->setProperty("id", "left_node");
left_node->setProperty("objectName", "left_node");
parent_node->setProperty("has_left_node", true);
} else {
QQuickItem* left_node = parent_node->findChild<QQuickItem*>("left_node");
if (left_node) {
insert_node(left_node, node_text);
} else {
std::cout << "left_node doesn't exist" << std::endl;
}
}
}
};
该函数适用于根节点和第二个节点,但对于第三个节点,它找不到创建的第二个节点,它只是打印“left_node不存在”。 这是我用来开始创建树和创建节点的函数:
void BinaryTree::create_node(QString node_text) {
if (node_count == 0) {
double node_value = node_text.toDouble();
QString node_id = "node_" + QString::number(node_count);
QQuickItem *node = qobject_cast<QQuickItem*>(node_component->create());
node->setParentItem(qobject_cast<QQuickItem*>(node_parent));
node->setProperty("node_text", node_text);
node->setProperty("id", node_id);
QObject *node_anchors = qvariant_cast<QObject*>(node->property("anchors"));
node_anchors->setProperty("horizontalCenter", node_parent->property("horizontalCenter"));
node_anchors->setProperty("top", node_parent->property("top"));
node_anchors->setProperty("topMargin", 10);
root_node = node;
root_node_value = node_value;
} else {
insert_node(root_node, node_text);
}
node_count++;
};
QQuickItem* BinaryTree::create_binary_node(QQuickItem* parent_node, QString node_text, QString node_id) {
QQuickItem* node = qobject_cast<QQuickItem*>(node_component->create());
node->setParentItem(parent_node);
node->setProperty("node_text", node_text);
node->setProperty("id", node_id);
node->setProperty("objectName", node_id);
QObject *node_anchors = qvariant_cast<QObject*>(node->property("anchors"));
node_anchors->setProperty("top", parent_node->property("top"));
node_anchors->setProperty("topMargin", 60);
return node;
}
正在创建的 Node 组件是一个 qml 文件,其中包含以下内容:
Rectangle {
width: 50
height: 50
radius: Math.min(width, height)/2
color: "cyan"
property string node_text
property bool has_right_node: false
property bool has_left_node: false
Text {
font.pixelSize: 12
anchors.centerIn: parent
text: node_text
}
}
我什至不知道从哪里开始解决这个问题,但我已经能够将问题确定为以下任一:
- 正在创建的节点超出范围,因此在函数的下一次迭代中找不到它。
- 创建节点时,为节点分配对象名称时出错,为了解决这个问题,我重复了在函数之外添加对象名称和 id 的行。
我尝试过的其他事情是:
- 打印新创建的节点的属性,以确保它具有对象名称
- 添加 if-else 语句以检查 find 子项是否返回值
我希望这个问题的解决方案,如果我需要用我的问题来改变任何事情,请告诉我。
先谢谢你。
答:
0赞
Stephen Quan
11/10/2023
#1
如果你想出一个创造性的层次结构模型,并且,如果你意识到一个递归,你可以把你的树逻辑移动到QML上:Loader
import QtQuick
import QtQuick.Controls
Page {
background: Rectangle { color: "#888" }
DrawNode {
anchors.fill: parent
model: ({
txt: "root",
children: [
{
txt: "child1",
children: [
{
txt: "gchild1",
children: [
{
txt: "ggchild1"
},
{
txt: "ggchild2"
}
]
},
{
txt: "gchild2"
}
]
},
{
txt: "child2",
children: [
{
txt: "gchild3"
}
]
}
]
})
}
}
// DrawNode.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Shapes
Item {
id: frame
property var model
Rectangle {
x: frame.width / 2 - width / 2
y: 10
width: 80
height: 80
radius: 40
border.color: "black"
Text {
anchors.centerIn: parent
text: model.txt
}
}
Repeater {
model: frame.model.children
Item {
anchors.fill: parent
z: -1
Shape {
ShapePath {
startX: frame.width / 2
startY: 50
strokeColor: "black"
PathLine {
x: index * frame.width / 2 + frame.width / 4
y: 150
}
}
}
Loader {
x: index * frame.width / 2
y: 100
width: frame.width / 2
height: frame.height - 100
Component.onCompleted: setSource("DrawNode.qml",{model:modelData})
}
}
}
}
您可以在线试用!
评论
id
不是一个常规的属性,我认为你不能这样设置它,而是使用objectName
objectName
id