init2null
23rd May 2008, 02:18
Hello all,
I've been trying for hours to get this QTreeView / QAbstractItemModel code snippet to work with Qt4.4 and VC++ 2008 Express. When I expand the nested items twice, Qt fails with the assert "ASSERT: "i > -1" in file itemviews\qtreeview.cpp, line 3013". Am I doing something wrong?
#include <QtGui>
class TestModel;
class SceneTest : public QDialog {
public:
SceneTest();
protected:
QTreeView *tree;
TestModel *model;
};
class InternalItem {
public:
InternalItem() {
parent = NULL;
}
~InternalItem() {qDeleteAll(children);}
int row() {
if (parent) {
return parent->children.indexOf(this);
} else {
return 0;
}
}
InternalItem *append(InternalItem *iitem) {children.append(iitem); return (iitem->parent = this);}
InternalItem *parent;
QList < InternalItem * > children;
};
class TestModel : public QAbstractItemModel {
public:
TestModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &) const;
protected:
InternalItem *root;
};
TestModel::TestModel() {
root = new InternalItem();
root->append(new InternalItem());
root->append(new InternalItem());
root->children[1]->append(new InternalItem());
root->children[1]->children[0]->append(new InternalItem());
root->children[1]->children[0]->children[0]->append(new InternalItem());
}
Qt::ItemFlags TestModel::flags(const QModelIndex &index) const {
return index.isValid() ? (Qt::ItemIsEnabled | Qt::ItemIsSelectable) : 0;
}
QVariant TestModel::data(const QModelIndex &index, int role) const {
if (!index.isValid() || index.column() >= 1)
return QVariant();
if (role == Qt::DisplayRole) {
InternalItem *iitem = static_cast < InternalItem * >(index.internalPointer());
if (index.column() == 0) {
return (long)iitem;
}
}
return QVariant();
}
QModelIndex TestModel::index(int row, int column, const QModelIndex &parent) const {
if (!hasIndex(row, column, parent)) {
return QModelIndex();
}
InternalItem *parentItem = NULL;
if (!parent.isValid()) {
parentItem = root;
} else {
parentItem = static_cast<InternalItem*>(parent.internalPointer());
}
InternalItem *child = parentItem->children[row];
if (child) {
return createIndex(row, column, child);
} else {
return QModelIndex();
}
}
QModelIndex TestModel::parent(const QModelIndex &index) const {
if (!index.isValid()) return QModelIndex();
InternalItem *iindex = static_cast < InternalItem * >(index.internalPointer());
if (!iindex->parent || iindex->parent == root) {
return QModelIndex();
} else {
return createIndex(iindex->row(), 0, iindex->parent);
}
}
QVariant TestModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (section == 0 && role == Qt::DisplayRole) {
return QString("A");
} else {
return QVariant();
}
}
int TestModel::rowCount(const QModelIndex &parent) const {
if (parent.column() > 0) return 0;
if (parent.isValid()) {
return static_cast < InternalItem * >(parent.internalPointer())->children.size();
} else {
return root->children.size();
}
}
int TestModel::columnCount(const QModelIndex &parent) const {
return 1;
}
SceneTest::SceneTest() : QDialog(NULL) {
model = new TestModel();
tree = new QTreeView(this);
tree->setModel(model);
QBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(tree);
}
I've been trying for hours to get this QTreeView / QAbstractItemModel code snippet to work with Qt4.4 and VC++ 2008 Express. When I expand the nested items twice, Qt fails with the assert "ASSERT: "i > -1" in file itemviews\qtreeview.cpp, line 3013". Am I doing something wrong?
#include <QtGui>
class TestModel;
class SceneTest : public QDialog {
public:
SceneTest();
protected:
QTreeView *tree;
TestModel *model;
};
class InternalItem {
public:
InternalItem() {
parent = NULL;
}
~InternalItem() {qDeleteAll(children);}
int row() {
if (parent) {
return parent->children.indexOf(this);
} else {
return 0;
}
}
InternalItem *append(InternalItem *iitem) {children.append(iitem); return (iitem->parent = this);}
InternalItem *parent;
QList < InternalItem * > children;
};
class TestModel : public QAbstractItemModel {
public:
TestModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &) const;
protected:
InternalItem *root;
};
TestModel::TestModel() {
root = new InternalItem();
root->append(new InternalItem());
root->append(new InternalItem());
root->children[1]->append(new InternalItem());
root->children[1]->children[0]->append(new InternalItem());
root->children[1]->children[0]->children[0]->append(new InternalItem());
}
Qt::ItemFlags TestModel::flags(const QModelIndex &index) const {
return index.isValid() ? (Qt::ItemIsEnabled | Qt::ItemIsSelectable) : 0;
}
QVariant TestModel::data(const QModelIndex &index, int role) const {
if (!index.isValid() || index.column() >= 1)
return QVariant();
if (role == Qt::DisplayRole) {
InternalItem *iitem = static_cast < InternalItem * >(index.internalPointer());
if (index.column() == 0) {
return (long)iitem;
}
}
return QVariant();
}
QModelIndex TestModel::index(int row, int column, const QModelIndex &parent) const {
if (!hasIndex(row, column, parent)) {
return QModelIndex();
}
InternalItem *parentItem = NULL;
if (!parent.isValid()) {
parentItem = root;
} else {
parentItem = static_cast<InternalItem*>(parent.internalPointer());
}
InternalItem *child = parentItem->children[row];
if (child) {
return createIndex(row, column, child);
} else {
return QModelIndex();
}
}
QModelIndex TestModel::parent(const QModelIndex &index) const {
if (!index.isValid()) return QModelIndex();
InternalItem *iindex = static_cast < InternalItem * >(index.internalPointer());
if (!iindex->parent || iindex->parent == root) {
return QModelIndex();
} else {
return createIndex(iindex->row(), 0, iindex->parent);
}
}
QVariant TestModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (section == 0 && role == Qt::DisplayRole) {
return QString("A");
} else {
return QVariant();
}
}
int TestModel::rowCount(const QModelIndex &parent) const {
if (parent.column() > 0) return 0;
if (parent.isValid()) {
return static_cast < InternalItem * >(parent.internalPointer())->children.size();
} else {
return root->children.size();
}
}
int TestModel::columnCount(const QModelIndex &parent) const {
return 1;
}
SceneTest::SceneTest() : QDialog(NULL) {
model = new TestModel();
tree = new QTreeView(this);
tree->setModel(model);
QBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(tree);
}