QTreeView子节点始终指向第一个顶级节点

时间:2011-07-26 18:00:49

标签: c++ qt indexing qtreeview

我已经关注了Qt提供的editableTreeView示例,我遇到了一个有趣的问题。顶级项目可以正确添加,但如果我要给其中一个孩子,它是指向第一个顶级项目的指针。

我的QAbstractItemModel代码如下。

#include "ModelItemNeural.h"

ModelItemNeural::ModelItemNeural(QObject *parent)
    : QAbstractItemModel(parent)
{
    counta = 0;
    rootNode = new NeuralNode();
    addNeuralNode(NeuralNode::NEURAL_NETWORK, 0, 0);
}

QModelIndex ModelItemNeural::index(int row, int column, const QModelIndex &parent) const
{
    // Out of bounds and null rootNode check.
//    if (rootNode == 0 || row < 0 || column < 0)
//    {
//        return QModelIndex();
//    }
    if (parent.isValid() && parent.column() != 0)
    {
        return QModelIndex();
    }

    NeuralNode* parentNode = nodeFromIndex(parent);
    NeuralNode* childNode = parentNode->getInputs().value(row);

    if (childNode == 0)
    {
        return QModelIndex();
    }

    return createIndex(row, column, childNode);
}

QModelIndex ModelItemNeural::parent(const QModelIndex &child) const
{
    NeuralNode* node = nodeFromIndex(child);
    if (node == 0)
    {
        return QModelIndex();
    }

    NeuralNode* parentNode = node->getParent();
    if (parentNode == 0)
    {
        return QModelIndex();
    }

    NeuralNode* grandParentNode = parentNode->getParent();
    if (grandParentNode == 0)
    {
        return QModelIndex();
    }

    int row = grandParentNode->getInputs().indexOf(parentNode);
    return createIndex(row, 0, parentNode);
}

QVariant ModelItemNeural::data(const QModelIndex &index, int role) const
{
    if (index.isValid() == false)
    {
        return QVariant();
    }

    if (role != Qt::DisplayRole)
    {
        return QVariant();
    }

    NeuralNode* node = nodeFromIndex(index);
    if (node == 0)
    {
        return QVariant();
    }

    switch (index.column())
    {
    case 0:
    {
        // Stripping the name of the NeuralNode type.
        QString name = typeid(node).name();
        int index = name.indexOf(" ");
        if (index >= 0)
        {
            name = name.remove(0, index + 1);
        }

        //return "Test";
        return node->getId();
        return name;
    }
    case 1:
    {
        return node->getWeight();
    }
    }

    return QVariant();
}

QVariant ModelItemNeural::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        switch (section)
        {
        case 0:
        {
            return "Node";
        }
        case 1:
        {
            return "Weight";
        }
        }
    }

    return QVariant();
}

int ModelItemNeural::rowCount(const QModelIndex &parent) const
{
    NeuralNode *parentItem = nodeFromIndex(parent);

    return parentItem->childCount();
}
int ModelItemNeural::columnCount(const QModelIndex &parent) const
{
    return rootNode->columnCount();
}

NeuralNode * ModelItemNeural::nodeFromIndex(const QModelIndex &index) const
{
    if (index.isValid() == true)
    {
        return static_cast<NeuralNode *>(index.internalPointer());
    }
    else
    {
        return rootNode;
    }
}

void ModelItemNeural::setRootNode(NeuralNode *rootNode)
{
    delete this->rootNode;
    this->rootNode = rootNode;
    reset();
}

Qt::ItemFlags ModelItemNeural::flags(const QModelIndex &index) const
{
    if (!index.isValid())
    {
        return 0;
    }

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

bool ModelItemNeural::insertColumns(int position, int columns, const QModelIndex &parent)
{
    bool success;

    beginInsertColumns(parent, position, position + columns - 1);
    success = rootNode->insertColumns(position, columns);
    endInsertColumns();

    return success;
}

bool ModelItemNeural::removeColumns(int position, int columns, const QModelIndex &parent)
{
    bool success;

    beginRemoveColumns(parent, position, position + columns - 1);
    success = rootNode->removeColumns(position, columns);
    endRemoveColumns();

    if (rootNode->columnCount() == 0)
    {
        removeRows(0, rowCount());
    }

    return success;
}

bool ModelItemNeural::insertRows(int position, int rows, const QModelIndex &parent)
{
    NeuralNode *parentItem = nodeFromIndex(parent);
    counta++;
    bool success;

    beginInsertRows(parent, position, position + rows - 1);
    switch (addedNode)
    {
    case NeuralNode::NEURALNODE:
    {
    default:
        break;
    }
    case NeuralNode::NEURON:
    {
        success = parentItem->insertChildren(position, rows, new Neuron(NeuralNode::NEURON, counta + 100, counta));
        break;
    }
    case NeuralNode::NEURAL_NETWORK:
    {
        success = parentItem->insertChildren(position, rows, new NeuralNetwork());
        break;
    }
    case NeuralNode::SENSOR_INT:
    {
        success = parentItem->insertChildren(position, rows, new SensorInt());
        break;
    }
    case NeuralNode::SENSOR_DOUBLE:
    {
        success = parentItem->insertChildren(position, rows, new SensorDouble());
        break;
    }
    }
    endInsertRows();

    return success;
}

bool ModelItemNeural::removeRows(int position, int rows, const QModelIndex &parent)
{
    NeuralNode *parentItem = nodeFromIndex(parent);
    bool success = true;

    beginRemoveRows(parent, position, position + rows - 1);
    success = parentItem->removeChildren(position, rows);
    endRemoveRows();

    return success;
}

void ModelItemNeural::addNeuralNode(const NeuralNode::NeuralType& type, int position, int columns, const QModelIndex &parent)
{
    addedNode = type;
    if (columnCount(parent) == 0)
    {
        if (insertColumn(0, parent) == false)
        {
            return;
        }
    }

    if (insertRow(0, parent) == false)
    {
        return;
    }
    //insertRows(position, columns, parent);
}

void ModelItemNeural::removeNeuralNode(const NeuralNode::NeuralType& type, int position, int columns, const QModelIndex &parent)
{

}

NeuralNode的代码(树的项目)如下所示

#include "NeuralNode.h"

NeuralNode::NeuralNode(NeuralNode *parent)
    : id(0), type(NeuralNode::NEURALNODE), weight(0), parent(parent)
{
}

NeuralNode::NeuralNode(const NeuralType &type, NeuralNode *parent)
    : id(id), type(type), weight(0), parent(parent)
{
}

NeuralNode::NeuralNode(const NeuralType &type, const int &id, NeuralNode *parent)
    : id(id), type(type), weight(weight), parent(parent)
{
}

NeuralNode::NeuralNode(const NeuralType &type, const int &id, const double &weight, NeuralNode *parent)
    : id(id), type(type), weight(weight), parent(parent)
{
}

bool NeuralNode::operator ==(const NeuralNode &node) const
{
    if (this->id != node.id)        // The id of this Neuron.
    {
        return false;
    }
    else if (weight != node.weight) // The weight of this Neuron.
    {
        return false;
    }
    else if (inputs != node.inputs)   // The inputs to this NeuralNode.
    {
        return false;
    }
    else if (parent != node.parent) // The parent of the NeuralNode.
    {
        return false;
    }
    else
    {
        return true;
    }
}

NeuralNode * NeuralNode::getParent() const
{
    return parent;
}

void NeuralNode::setParent(NeuralNode *parent)
{
    this->parent = parent;
}

QList<NeuralNode*> NeuralNode::getInputs() const
{
    return inputs;
}

void NeuralNode::setInputs(const QList<NeuralNode*> &inputs)
{
    this->inputs = inputs;
}

NeuralNode * NeuralNode::child(int number)
{
    return inputs.value(number);
}

int NeuralNode::childCount() const
{
    return inputs.count();
}

int NeuralNode::columnCount() const
{
    return 2;
}

bool NeuralNode::insertChildren(int position, int count, NeuralNode* node)
{
    if (position < 0 || position > inputs.length())
    {
        return false;
    }

    for (int row = 0; row < count; ++row)
    {
       inputs.insert(position, node);
    }

    return true;
}

bool NeuralNode::removeChildren(int position, int count)
{
    if (position < 0 || position + count > inputs.length())
    {
        return false;
    }

    for (int row = 0; row < count; ++row)
    {
        delete inputs.takeAt(position);
    }

    return true;
}

int NeuralNode::childNumber() const
{
    return inputs.length();
}

bool NeuralNode::insertColumns(int position, int columns)
{
    if (position < 0)
    {
        return false;
    }

    for (int a = 0; a < inputs.length(); ++a)
    {
        inputs.at(a)->insertColumns(position, columns);
    }

    return true;
}

bool NeuralNode::removeColumns(int position, int columns)
{
    if (position < 0)
    {
        return false;
    }

    for (int a = 0; inputs.length(); ++a)
    {
        inputs.at(a)->removeColumns(position, columns);
    }

    return true;
}

这是我注意到的。

  • 跟踪我的模型的index()调用返回顶级节点子项的索引。
  • 调用ui-&gt; treeView-&gt; selectedModel() - &gt; currentIndex()始终返回无效索引(root)。对于ui-> treeView-&gt; currentIndex()。
  • 也是如此

我在某个地方发现指针有问题,但我找不到它。任何帮助将不胜感激。

JEC

编辑:这是问题的粗略图形

目前:

Root->A
      B
      C->A

我想要的:

Root->A
      B
      C->D

其中A,B,C和D是唯一 NeuralNodes。我应该在树中没有重复。

再次感谢。

1 个答案:

答案 0 :(得分:2)

事实证明,我忘记将孩子与父母联系起来。如果没有有效的parent(),则始终会添加顶级节点。