Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QTreeWidget (QTreeView)
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt GUI
AD
Каким образом можно просмотреть все элементы дерева, представленного QTreeWidget? Почитал мануал и не узнал, что и какими функциями это достигается. Можно примерчик либо ссылочку на примерчик?

Сильно ли изменится алгоритм просмотра элементов, если вместо QTreeWidget используется QTreeView?

В ситуации такой:
Tracks
|
|--OnGround
|
|--file1
|
|--file1
|
|--file2
|
|--file3

Есть ли возможность увидеть соседей второго узла file1?
Litkevich Yuriy
была тема вроде "обход дерева" поищи по форуму.

к стати быстрые ссылки в FAQ, которые я собирал - рулят.
AD
Вот нашел кое-что. Кидаю ответ сюда, чтобы быстрее можно было найти, не переходя 5 раз по ссылкам.
Цитата
Всё вопрос решён

Перебор всех корневых элментов:

QTreeWidgetItem* item;
for(i=0; i < treeWidget->topLevelItemCount(); i++)
{
item = treeWidget->topLevelItem(i);
}


ну а по всем элементам через рекурсию

item->child(int i)
item->childcount();
AD
Вопрос про соседа второго узла file1 не нашел. Сможете помочь? Заранее спасибо.
AD
Вот код, который проходит по всем элементам и ищет повторяющиеся. Индексы этих элементов запоминает, а затем чистит их. Но, тут непонятная штука вылезла. Что чистит не все повторяющиеся, а только некоторые, хотя заполнение списка идет правильно. Ну то есть, было 5 повторяющихся элементов, осталось 2. Почему так???? Вот код этой штуковины.
/// Правка дерева этапов полета
void TLV::editTreeView()
{
    QTreeWidgetItem* header = treePhaseView -> topLevelItem(0);
    QTreeWidgetItem *phaseNode = 0, *fileNode = 0, *revFileNode = 0;
    for(register int i=0; i<header -> childCount(); ++i)
    {
        phaseNode = header -> child(i);
        if(phaseNode == 0) break;
        string ph(phaseNode -> text(0).toStdString());
        QList<int> indexList;
        for(register int j=0; j<phaseNode -> childCount(); ++j)
        {
            fileNode = phaseNode -> child(j);
            if(fileNode == 0) break;
            string sj(fileNode -> text(0).toStdString());
            for(register int k=j+1; k<phaseNode -> childCount(); ++k)
            {
                revFileNode = phaseNode -> child(k);
                if(revFileNode == 0) break;
                string pj(revFileNode -> text(0).toStdString());
                if(revFileNode -> text(0) == fileNode -> text(0))
                    indexList.append(k);
            }
        }
        for(register int j=0; j<indexList.size(); ++j)
            phaseNode -> removeChild(phaseNode -> child(indexList[j]));
        int p = 900;
    }
}
AD
Блин, неужели никто с подобным не сталкивался?
AD
Перешел к QTreeView. соответственно, теперь делаю модель-представление.
Вот сама используемая модель. То есть проблема с нажатием решена полностью и довольно удобно
TreeModel
/// файл ObjectTreeModel.h
#ifndef OBJECT_TREE_MODEL_H
#define OBJECT_TREE_MODEL_H

#include <QStandardItemModel>

/// Класс модели описания дерева этапов полета
class ObjectTreeModel: public QStandardItemModel
{
    Q_OBJECT

public:
    ObjectTreeModel(QObject* parent = 0): QStandardItemModel(parent)
    { connect(this, SIGNAL(itemChanged(QStandardItem*)), SLOT(itemPress(QStandardItem*))); }
    ~ObjectTreeModel() {}

protected slots:
    void itemPress(QStandardItem* item);
};

#endif // OBJECT_TREE_MODEL_H


/// Файл ObjectTreeModel.cpp

#include "ObjectTreeModel.h"

/// Нажатие на элемент дерева
void ObjectTreeModel::itemPress(QStandardItem* item)
{
    if(!item -> isCheckable() || item -> column() != 0) return;

    Qt::CheckState state = item -> checkState();
    if(state == Qt::Checked || state == Qt::Unchecked)
    {
        for(register int i=0; i<item -> rowCount(); ++i)
        {
            QStandardItem* child = item -> child(i);
            if(child -> isCheckable() && child -> checkState() != state)
                child -> setCheckState(state);
        }
    }

    QStandardItem* parent = item -> parent();
    if(parent && parent -> isCheckable())
    {
        state = parent -> child(0) -> checkState();
        if(state == Qt::PartiallyChecked) parent -> setCheckState(state);
        else
        {
            register int i = 1;
            while(i<parent -> rowCount() && parent -> child(i) -> checkState()==state) ++i;
            if(i != parent -> rowCount()) state = Qt::PartiallyChecked;
            parent -> setCheckState(state);
        }                
    }
}


Но проблему с некоторыми лишними узлами пока решить не удалось. То есть при проходе по модели дерева, остаются лишние элементы. И как с этим бороться - не знаю! :( Помогите, пожалуйста:
/// Правка дерева этапов полета
void TLV::editTreeView()
{
    QStandardItem* header = treeModel -> item(0);
    QStandardItem *phaseNode = 0, *fileNode = 0, *revFileNode = 0;
    for(register int i=0; i<header -> rowCount(); ++i)
    {
        phaseNode = header -> child(i);
        if(phaseNode == 0) break;
        string ph(phaseNode -> text().toStdString());
        for(register int j=0; j<phaseNode -> rowCount(); ++j)
        {
            fileNode = phaseNode -> child(j);
            if(fileNode == 0) break;
            string sj(fileNode -> text().toStdString());
            for(register int k=j+1; k<phaseNode -> rowCount(); ++k)
            {
                revFileNode = phaseNode -> child(k);
                if(revFileNode == 0) break;
                string pj(revFileNode -> text().toStdString());
                if(revFileNode -> text() == fileNode -> text())
                    phaseNode -> removeRow(k);
            }
        }
    }
}
AD
На прог-орге подсказали ошибку, исправил. Правильный код прохода по дереву и выуживанию лишних элементов такой:
/// Правка дерева этапов полета
void TreeModel::editTreeModel()
{
    QStandardItem *header = model -> item(0), *phaseNode = 0, *fileNode = 0, *revFileNode = 0;
    for(register int i=0; i<header -> rowCount(); ++i)
    {
        phaseNode = header -> child(i);
        if(phaseNode == 0) break;
        for(register int j=0; j<phaseNode -> rowCount(); ++j)
        {
            fileNode = phaseNode -> child(j);
            if(fileNode == 0) break;
            for(register int k=j+1, x=j; k<phaseNode -> rowCount() && x<=phaseNode -> rowCount(); ++x)
            {
                revFileNode = phaseNode -> child(k);
                if(revFileNode == 0) break;
                if(revFileNode -> text() == fileNode -> text()) phaseNode -> removeRow(k);
            }
        }
    }
}


P.S. Ошибка была в том, что удаляя элемент прямо в цикле, я изменяю счетчик элементов и тем самым перескакиваю элемент, который следует удалить.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.