Qt 创建后无法通过对象名称找到子 QML 组件

问题描述 投票:0回答:1

我正在创建一个 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 does not Exist”。 这是我用来开始创建树并创建节点的函数:

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
    }
}

我什至不知道从哪里开始解决这个问题,但我已经能够查明问题所在:

  1. 正在创建的节点超出了范围,因此在函数的下一次迭代中找不到它。
  2. 创建节点时,为节点分配对象名称时出现错误,为了解决此问题,我也在函数外部重复添加对象名称和 id 的行。

我尝试过的其他事情是:

  1. 打印新创建节点的属性以确保它具有对象名称
  2. 添加 if-else 语句来检查 find child 是否返回值

我希望有一个解决这个问题的方法,如果我需要对我的问题进行任何更改,请告诉我。

提前谢谢您。

c++ qt qml qt6
1个回答
0
投票

如果您想出一个创造性的层次结构模型,并且如果您通过递归实现

Loader
,您可以将树逻辑移动到 QML:

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})
            }
        }
    }
}

您可以在线尝试!

© www.soinside.com 2019 - 2024. All rights reserved.