Друзья, помогите, пожалуйста!
Исправляю свою модель дерева, учитывая что источник данных должен располагаться внутри самой модели.
Исходник с оболочкой для теста положил во вложения к посту.
Имею такой заголовок для каждого узла:
C++ (Qt)
class treeNodeClient
{
public:
treeNodeClient(treeNodeClient *parent,
const int &p_id,
const QString &p_name,
const QString &p_phone,
const QString &p_email,
const QString &p_referal,
const bool &p_haschildren);
~treeNodeClient();
// Набор данных для каждой из записей
int clientId;
QString clientName;
QString clientPhone;
QString clientEmail;
QString clientReferal;
bool clientHasChildren; // Переменная, показывающая, может ли этот узел иметь детей
int row() const;
treeNodeClient *parentNode;
QList<treeNodeClient*> childrenList;
};
Модель наследуется от QAbstractItemModel, в конструкторе создается корневой узел, который никогда не будет показан пользователям:
C++ (Qt)
modelClients::modelClients(QObject *parent)
:QAbstractItemModel(parent)
{
// Создание первичной ветви модели, никогда не отображается
rootNode = new treeNodeClient(0,-1,"root","","","",true);
}
Вот некоторые необходимые функции:
C++ (Qt)
// Подсчет количества строк
int modelClients::rowCount(const QModelIndex &parent) const
{
treeNodeClient *node;
if (parent.isValid()) node = static_cast<treeNodeClient*>(parent.internalPointer());
else node = rootNode;
return node->childrenList.count();
}
bool modelClients::canFetchMore ( const QModelIndex & parent ) const
{
if (!parent.isValid()) return false;
treeNodeClient *node = static_cast<treeNodeClient*>(parent.internalPointer());
return node->clientHasChildren && !node->childrenList.count();
}
void modelClients::fetchMore ( const QModelIndex & parent )
{
if (!canFetchMore(parent)) return;
treeNodeClient *node = static_cast<treeNodeClient*>(parent.internalPointer());
beginInsertRows(parent,0,3);
node->childrenList.append(new treeNodeClient(node, 11,"Subnode 1","","","",false));
node->childrenList.append(new treeNodeClient(node, 12,"Subnode 2","","","",false));
node->childrenList.append(new treeNodeClient(node, 13,"Subnode 3","","","",false));
endInsertRows();
}
bool modelClients::hasChildren (const QModelIndex & parent) const
{
if (!parent.isValid()) return true;
treeNodeClient *node = static_cast<treeNodeClient*>(parent.internalPointer());
return node->clientHasChildren;
}
В функции fetchMore пока заменяю реальный источник данных на его абстракцию, просто добавляя три нераскрываемых дочерних узла.
Первичное заполнение модели выполняю в функции make MainTree, где на данный момент вставляется три узла, два из которых раскрываемы:
C++ (Qt)
void modelClients::makeMainTree()
{
// Очистка корневого узла
qDeleteAll(rootNode->childrenList);
rootNode->childrenList.clear();
rootNode->childrenList.append( new treeNodeClient(rootNode, 1,"First", "111-11-11","email 1","Referal 1",true) );
rootNode->childrenList.append( new treeNodeClient(rootNode, 2,"Second","222-22-22","email 2","Referal 2",false) );
rootNode->childrenList.append( new treeNodeClient(rootNode, 3,"Third", "333-33-33","email 3","Referal 3",true) );
reset();
}
Есть проблемы с hasChildren (или где-то еще):
Если я опущу эту функцию, деревья становятся впринципе нераскрываемы.
Если ее первую строчку заменяю на
if (!parent.isValid()) return false, то дерево никогда не будет показано.
Если же на
if (!parent.isValid()) return true, то подузлы вставляются два раза при первом раскрытии
Переопределить canFetchMore(QModelIndex parent). Здесь вернуть true, если rowCount(parent) < чем кол-во имеющихся где-то данных.
А что если я не знаю заранее, сколько узлов я смогу добавить в fetchMore? Я знаю только то, что я имею возможность их добавить, и их число больше нуля.