【问题标题】:QAbstractItemModel data() is NEVER calledQAbstractItemModel data() 永远不会被调用
【发布时间】:2011-07-23 16:36:27
【问题描述】:

我正在尝试创建一个 QTreeView 并为其使用自定义模型。我已经在不同的地方放置了qDebug() 语句,并且我确定data()永远不会被调用。我该如何解决这个问题?

模型代码如下

#include "ModelItemNeural.h"

ModelItemNeural::ModelItemNeural(QObject *parent, NeuralNode *rootNode)
    : QAbstractItemModel(parent)
{
    this->rootNode = 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();
    }

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

int ModelItemNeural::rowCount(const QModelIndex& parent) const
{
    if (parent.isValid() == false)
    {
        return 0;
    }

    if (parent.column() > 0)
    {
        return 0;
    }

    NeuralNode* parentNode = nodeFromIndex(parent);
    if (parentNode == 0)
    {
        return 0;
    }

    return parentNode->getInputs().length();
}

int ModelItemNeural::columnCount(const QModelIndex &parent) const
{
    return 2;
}

QVariant ModelItemNeural::data(const QModelIndex &index, int role) const
{
    qDebug() << "Data";
    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);
            }

            qDebug() << "Name Column";
            return "Test";
            return name;
        }

        case 1:
        {
            qDebug() << "Value Column";
            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();
}

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

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

视图所在主窗口的代码如下。

#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    NeuralNetwork* network = new NeuralNetwork();
    modelNeural = new ModelItemNeural();
    modelNeural->setRootNode(network);
    ui->treeView->setModel(modelNeural);

    update();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionNew_triggered()
{
    NeuralNetwork* network = new NeuralNetwork();

    modelNeural->setRootNode(network);
    ui->treeView->update();
}

我应该提到标题确实显示这个模型。但是,即使我设置了一个项目,小部件中也没有显示任何内容,只保存了标题。

哦,NeuralNetworkNeuralNode 的子集。

【问题讨论】:

  • 你的 data() 方法是虚拟的吗?
  • @Sebastian N,它被 QAbstractItemModel 覆盖。
  • 否 data() 方法被 QAbstractItemModel 覆盖。签名是正确的(QTCreator 显示的斜体表示它是一个被覆盖的函数)。
  • 好吧,假设没有魔法,我想,你在某些功能上失败了。检查您是否返回有效索引,行数 > 0。另外,这是什么意思:if (parent.column() &gt; 0) { return 0; }?另外,你不需要写boolVar == true。够了boolVar
  • 考虑使用 ModelTest - 它很可能会发现很多隐藏的错误。 developer.qt.nokia.com/wiki/Model_Test

标签: c++ qt qtreeview qabstractitemmodel


【解决方案1】:

问题是这个片段:

int ModelItemNeural::rowCount(const QModelIndex& parent) const
{
    if (parent.isValid() == false)
    {
        return 0;
    }

您基本上是在说根节点(由无效的父索引指示)有零个子节点,即模型有零个顶级行。所以视图不再查询。

只需删除此检查,它应该可以工作。 nodeFromIndex 似乎可以正确处理根节点。

【讨论】:

  • 我做了这个更改,但仍然没有调用 data()。但是,现在 rowCount() 返回 0(这是正确的)。唯一被调用的其他函数是 headerData() 和 index()。 Index() 现在总是返回一个空白 QModelIndex() 因为根没有孩子。你能有一个 1 项目树吗?随着程序的运行,我将添加更多内容。
  • @jecjackal 如果你的树实际上是空的,你为什么期望 data() 被调用?首先添加一些(顶级)行。一千个,没关系。
  • 我有一个项目(根项目)。我需要手动调用“insertRows()”吗?我会试一试。
  • 我刚刚找到了一个 QT SDK 2.2.1 附带的示例。它被称为“可编辑树模型”。它不在存储大量示例的主页上。这个模型正是我想要做的。感谢大家的帮助
【解决方案2】:

您是否将模型(而不是项目)添加到树视图控件? 您是否创建了派生类型的项目并将它们添加到模型中? 如果您的模型正在被访问,则应该调用 data()。

【讨论】:

  • 是的,我已经将模型设置为树视图并为该模型创建了一个项目。由于发送到树视图的模型是一个指针,因此我执行此操作的顺序无关紧要(添加到树视图与将项目添加到模型)。
  • 如果在将项目添加到模型之前尚未将模型连接到树视图,则不会看到任何告诉视图更新的信号。也许这是一个刷新问题?我还注意到您正在创建自己的索引。也许索引无效,所以它从不尝试使用该索引获取数据?如果您不需要特殊索引,我会使用基类中的方法。少出错;)
  • 我认为 index() 是纯虚拟的
  • 对不起。我使用了一个非抽象类并继承自它。它们提供了大部分方法,我不需要更改它们。
【解决方案3】:

您必须在 QAbstractItemModel 继承的类中覆盖以下方法:

QModelIndex index(int row, int column, const QModelIndex &amp;parent = QModelIndex()) const;

然后写在:

return createIndex(row, column, nullptr);

类似这样的:

QModelIndex index(int row, int column, const QModelIndex &parent) const { return createIndex(row, column, nullptr); }

【讨论】:

    猜你喜欢
    • 2012-10-27
    • 2013-10-12
    • 2012-03-27
    • 2013-08-29
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2015-10-15
    相关资源
    最近更新 更多