Здравствуйте!
Делаю древовидную модель, которая представляет иерархию текстовых данных.
Файл заголовка
#ifndef SENSOR_LINKS_MODEL
#define SENSOR_LINKS_MODEL
/*
This class shows links between sensors and elements.
*/
#include <QtCore/QAbstractItemModel>
#include <QtCore/QStringList>
#include <QtCore/QHash>
//Pre-declarations.
class QObject;
class QString;
class SensorLinksModel : public QAbstractItemModel
{
Q_OBJECT
public:
SensorLinksModel(QObject *parent); //Constructor.
virtual ~SensorLinksModel(); //Destructor.
void setNewData(QString strTextData); //Setup new data, update model.
virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
virtual QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const;
virtual QModelIndex parent ( const QModelIndex & index ) const;
virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; //Make header data.
private:
QStringList m_TextStorageList; //Storage of text data.
typedef QHash<qint64, int> IdTextLinkageHash;
IdTextLinkageHash m_IdTextLinkageHash; //Map - linkage between Id to TextData.
};
#endif
Файл реализации:
#include "SensorLinksModel.h"
#include <QtDebug>
//Includes forpre-declarations.
#include <QtCore/QObject>
#include <QtCore/QString>
//Constructor.
SensorLinksModel::SensorLinksModel(QObject *parent)
: QAbstractItemModel(parent)
{
;
}
//Destructor.
SensorLinksModel::~SensorLinksModel()
{
//Clear storages.
m_IdTextLinkageHash.clear();
}
//Setup new data, update model.
void SensorLinksModel::setNewData(QString strTextData)
{
beginResetModel ();
;
//Form, load internal text storage.
strTextData.remove("\r"); //Remove all '\r' from source string.
m_TextStorageList.clear();
m_TextStorageList = strTextData.split("\n", QString::SkipEmptyParts); //Form list by splitting source string by "\n".
//Form ids, linkage between id and text list elemem num.
qint64 parent_num=0, child_num=0, list_index=0;
for(list_index=0; list_index<m_TextStorageList.count(); list_index++)
{
/*Id format: PPCC (2 bytes). PP - parent num (1 byte), CC - child num. PP - begins from 0. CC - begins from 1.
*/
//Check for parent sign - its string begins by '#'.
if(m_TextStorageList[list_index].at(0) == '#')
{
//Debugging.
//qDebug() << "Item" << list_index << QString().sprintf("%.4X", parent_num * 0x100);
m_IdTextLinkageHash[parent_num++ * 0x100] = list_index;
child_num = 1;
}
//Else this is child.
else
{
//Debugging.
//qDebug() << "Item" << list_index << QString().sprintf("%.4X", (parent_num-1) * 0x100 + child_num);
m_IdTextLinkageHash[(parent_num-1) * 0x100 + child_num++] = list_index;
}
}
//Output storage to console.
//foreach(quint16 id, m_IdTextLinkageHash.keys())
// qDebug() << QString().sprintf("%.4X",id) << m_IdTextLinkageHash[id];
endResetModel();
}
//virtual
int SensorLinksModel::columnCount ( const QModelIndex & parent ) const
{
return 1;
}
//virtual
int SensorLinksModel::rowCount ( const QModelIndex & parent ) const
{
//If parent is most root - rows count is the count of #-items.Begin.
if(parent == QModelIndex())
{
int parents_count = 0;
//Scan parents.
foreach(qint64 id, m_IdTextLinkageHash.keys()) //Count only parents, whithout childs.
{
if(id % 0x100 == 0x00)
parents_count++;
}
return parents_count;
}
//If parent is most root - rows count is the count of #-items.End.
//Else if it is not the most root - parent item - count the clind items num.Begin.
//else if((parent != QModelIndex()) && (parent.isValid()) && (parent.internalId() % 0x100 == 0x00))
else if(parent.internalId() % 0x100 == 0x00)
{
int childs_count = 0;
const quint8 high_byte = (quint8)(parent.internalId()/0x100);
//Debug.
//qDebug() << "High byte:" << QString().sprintf("%.2X", high_byte);
//Scan childs to count the items whith high byte = high_byte.
foreach(qint64 id, m_IdTextLinkageHash.keys())
{
if( (id / 0x100 == high_byte) && (id % 0x100 != 0x00) ) //Count onlu childs items, whithout parent item.
{
//Debug.
//qDebug() << QString().sprintf("id: %.4X", id);
childs_count++;
}
}
//qDebug() << "Childs count:" << childs_count;
//return 9;
return childs_count;
}
//If it is not the most root - parent item - count the clind items num.End.
//Else if this is the most child item - return no rows count.
else if(parent.internalId() % 0x100 != 0x00)
{
return 0;
}
return 0; //Return by default.
}
//virtual
QVariant SensorLinksModel::data ( const QModelIndex & index, int role ) const
{
if(role == Qt::DisplayRole)
{
//Get the id from cur index.
const qint64 id = index.internalId();
//Check for valid id.
if(m_IdTextLinkageHash.contains(id))
{
if( m_TextStorageList.size() > m_IdTextLinkageHash[id] )
{
//qDebug() << "SensorLinksModel::data: correct id:" << QString().sprintf("%.4X", id);
return m_TextStorageList[m_IdTextLinkageHash[id]];
}
}
else //Else if there is no such id in storage 'm_IdTextLinkageHash'.
{
//qDebug() << "SensorLinksModel::data: wrong id: id ==" << QString().sprintf("%.4X", id);
return QVariant("No data");
}
}
return QVariant();
}
//virtual
QModelIndex SensorLinksModel::index ( int row, int column, const QModelIndex & parent ) const
{
//Do not check 'hasIndex' there. Otherwize would work uncorrect.
//If this is index on parent item.
if(parent == QModelIndex())
{
return createIndex(row, column, (quint32)(row) * 0x100);
}
//Else if it is child item.
else if(parent.isValid())
{
const qint64 id = parent.row() * 0x100 + row + 1;
//qDebug() << "SensorLinksModel::index id:" << id;
return createIndex(row, column, (quint32)id);
}
//Return by default.
return QModelIndex();
}
//virtual
QModelIndex SensorLinksModel::parent ( const QModelIndex & index ) const
{
//Protection.
if (!index.isValid())
return QModelIndex();
qint64 id = index.internalId();
//Check if this is the parent item index - in this case create and return empty index.
if( id % 0x100 == 0)
return QModelIndex();
//If this is child item index - create and return index for parent.
else
return createIndex( id/0x100, 0, (quint32)((id % 0x100) * 0x100) );
//Return by default.
return QModelIndex();
}
//Make header data.
//virtual
QVariant SensorLinksModel::headerData ( int section, Qt::Orientation orientation, int role ) const
{
if( (section == 0) && (orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
return QVariant("Sensors-Linkage");
else
return QVariant();
}
Создаю модель. После этого вызываю свой метод 'setNewData(QString strTextData)' чтобы заполнить модель данными.
Дальше мне нужно обновить модель - сбросить все старые данные и заполнить новыми данными. Для этого вызываю 'setNewData' еще раз, передав туда новые данные. Текст при этом меняется. Но! Размерность модели остается старой, остаются те же количества строк, те же ветки. Только пустые, без текста.
Вопрос: как полностью очистить модель, и заполнить ее новыми данными? Какой метод нужно вызвать? Или что то нужно вызвать из представления?