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();
我应该提到标题确实显示这个模型。但是,即使我设置了一个项目,小部件中也没有显示任何内容,只保存了标题。
哦,NeuralNetwork
是 NeuralNode
的子集。
【问题讨论】:
你的 data() 方法是虚拟的吗? @Sebastian N,它被 QAbstractItemModel 覆盖。 否 data() 方法被 QAbstractItemModel 覆盖。签名是正确的(QTCreator 显示的斜体表示它是一个被覆盖的函数)。 好吧,假设没有魔法,我想,你在某些功能上失败了。检查您是否返回有效索引,行数 > 0。另外,这是什么意思:if (parent.column() > 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 &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::columnCount - 每行的可变列数
QTreeView 的 QAbstractItemModel:我做错了啥?