Hi,
I don't want to use tree items for my tree view so I have designed my model as below.
I need to build tree based on 0's & 1's
All zeros are top level items, and 1's followed by 0 are child's for 0 & all 2's followed by 1 are child's of 1.
Q_OBJECT
public:
//all necessary functions for model
private:
mutable QVector<int> m_vector;
mutable QVector< QVector<int> > childs; // childs for top level items ex: if vector of vectors is [1 1 1] [1 1 1] [1 1 1] -> 1st top level items has 3 child's & 2nd, 3rd top level items also have 3 childs
};
class Model : public QAbstractItemModel {
Q_OBJECT
public:
//all necessary functions for model
private:
mutable QVector<int> m_vector;
mutable QVector< QVector<int> > childs; // childs for top level items ex: if vector of vectors is [1 1 1] [1 1 1] [1 1 1] -> 1st top level items has 3 child's & 2nd, 3rd top level items also have 3 childs
};
To copy to clipboard, switch view to plain text mode
So my model is:
{
if(!parent.isValid()){
return 5000; // 5000 top level items
}
else if(!parent.parent().isValid()) //limited to 2 levels
{
return childs.at(parent.row()).count(1); // count no.of 1's for top level items which are 0 initially but when data() called there I am inserting 2 child's (1's), so when next time rowCount() is called it returns 2, but first time it would be 0. I am doing this because rowCount() calls for all the top level items initially that time I am simply passing 0, but again when data() is called rowCount() will be called one more time (for visible items only) that time I am inserting 2 items for top level item in data() function so rowCount() will return 2 this time.
}
return 0;
}
{
if(index.isValid()){
QVector<int> row;
row << 1 << 1;
childs[index.row()] = row; // for all top level items inserting 2 child's
}
if(role == Qt::DisplayRole)
return index.row()+1;
}
int Model::rowCount(const QModelIndex &parent) const
{
if(!parent.isValid()){
return 5000; // 5000 top level items
}
else if(!parent.parent().isValid()) //limited to 2 levels
{
return childs.at(parent.row()).count(1); // count no.of 1's for top level items which are 0 initially but when data() called there I am inserting 2 child's (1's), so when next time rowCount() is called it returns 2, but first time it would be 0. I am doing this because rowCount() calls for all the top level items initially that time I am simply passing 0, but again when data() is called rowCount() will be called one more time (for visible items only) that time I am inserting 2 items for top level item in data() function so rowCount() will return 2 this time.
}
return 0;
}
QVariant Model::data(const QModelIndex &index, int role ) const
{
if(index.isValid()){
QVector<int> row;
row << 1 << 1;
childs[index.row()] = row; // for all top level items inserting 2 child's
}
if(role == Qt::DisplayRole)
return index.row()+1;
return QVariant();
}
To copy to clipboard, switch view to plain text mode
But my problem is I am not able to see plus sign for all the top level items in tree view (except 1st top level item).
But if i double click on visible top level item it is expanding with 2 child's (as expected) but there is no + sign which indicates that there are child's.
I implemented hasChildren() also and checked it did not work.
Any idea/suggestions for this ?? (I tested this with Qt4.8.6 & 5.4.0 on windows8)
Thanks in advance.
My complete model is here, if any one want to test:
{
childs.resize(5000);
}
Model::~Model()
{
}
bool Model
::hasChildren(const QModelIndex &parent
) const {
if(!parent.isValid())
return true;
if(!parent.parent().isValid()){
int val = childs.at(parent.row()).count(1);
return ( (0 != val) ? true : false);
}
return false;
}
{
if(index.isValid()){
QVector<int> row;
row << 1 << 1;
childs[index.row()] = row;
}
if(role == Qt::DisplayRole)
return index.row()+1;
}
int Model
::columnCount(const QModelIndex &parent
) const {
return 1; //m_head.size();
}
{
if(!parent.isValid()){
return 5000;
}
else if(!parent.parent().isValid()) //limited to 2 levels
{
return childs.at(parent.row()).count(1);
}
return 0;
}
{
if(!parent.isValid())
{
return createIndex(row, column, -1); // top level item has invalid parent
}
// we only need id of the parent since it identifies the item
return createIndex(row, column, parent.row());
}
{
int id = ind.internalId();
return index(id, 0); // return top-level item
}
Model::Model(QObject *parent): QAbstractItemModel(parent)
{
childs.resize(5000);
}
Model::~Model()
{
}
bool Model::hasChildren(const QModelIndex &parent) const
{
if(!parent.isValid())
return true;
if(!parent.parent().isValid()){
int val = childs.at(parent.row()).count(1);
return ( (0 != val) ? true : false);
}
return false;
}
QVariant Model::data(const QModelIndex &index, int role ) const
{
if(index.isValid()){
QVector<int> row;
row << 1 << 1;
childs[index.row()] = row;
}
if(role == Qt::DisplayRole)
return index.row()+1;
return QVariant();
}
int Model::columnCount(const QModelIndex &parent) const
{
return 1; //m_head.size();
}
int Model::rowCount(const QModelIndex &parent) const
{
if(!parent.isValid()){
return 5000;
}
else if(!parent.parent().isValid()) //limited to 2 levels
{
return childs.at(parent.row()).count(1);
}
return 0;
}
QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
if(!parent.isValid())
{
return createIndex(row, column, -1); // top level item has invalid parent
}
// we only need id of the parent since it identifies the item
return createIndex(row, column, parent.row());
}
QModelIndex Model::parent(const QModelIndex &ind) const
{
if(!ind.isValid()) return QModelIndex();
int id = ind.internalId();
if( id == -1) return QModelIndex();
return index(id, 0); // return top-level item
}
To copy to clipboard, switch view to plain text mode
Bookmarks