QAbstractItemModel data() 永远不会被调用

Posted

技术标签:

【中文标题】QAbstractItemModel data() 永远不会被调用【英文标题】:QAbstractItemModel data() is NEVER called 【发布时间】: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 【参考方案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);

【讨论】:

以上是关于QAbstractItemModel data() 永远不会被调用的主要内容,如果未能解决你的问题,请参考以下文章

谁熟悉QTreeView+QAbstractItemModel 多选删除功能

QAbstractItemModel Class

QAbstractItemModel::columnCount - 每行的可变列数

QTreeView 的 QAbstractItemModel:我做错了啥?

QAbstractItemModel - QModelIndex 对象在创建时是不是应该被缓存?

QAbstractItemModel index() 和 parent() 方法