Дочерние элементы QTreeView всегда указывают на первый узел верхнего уровня - PullRequest
0 голосов
/ 26 июля 2011

Я последовал примеру editableTreeView, предоставленному Qt, и у меня возникла интересная проблема. Элементы верхнего уровня могут быть добавлены правильно, но если я хочу дать одному из них дочерний элемент, это указатель на первый элемент верхнего уровня.

Мой код для 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-> treeView-> selectedModel () -> currentIndex () всегда возвращает неверный индекс (root). То же самое верно для ui-> treeView-> currentIndex ().

Я чувствую проблему с указателем где-то, но не могу ее найти. Любая помощь будет принята с благодарностью.

Jec

Редактировать: Вот грубый рисунок проблемы

В настоящее время:

Root->A
      B
      C->A

Что я хочу:

Root->A
      B
      C->D

Где A, B, C и D уникальные нейронные узлы. У меня не должно быть дубликатов на дереве.

Еще раз спасибо.

1 Ответ

2 голосов
/ 27 июля 2011

Оказывается, я забыл связать детей с их родителями.Без действительного parent () узлы верхнего уровня всегда добавляются.

...