crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QTreeWidget (QTreeView), просмотр элементов дерева
AD
  опции профиля:
сообщение 20.2.2009, 18:37
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Каким образом можно просмотреть все элементы дерева, представленного QTreeWidget? Почитал мануал и не узнал, что и какими функциями это достигается. Можно примерчик либо ссылочку на примерчик?

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

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

Есть ли возможность увидеть соседей второго узла file1?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 20.2.2009, 18:47
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9666
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


была тема вроде "обход дерева" поищи по форуму.

к стати быстрые ссылки в FAQ, которые я собирал - рулят.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 20.2.2009, 19:51
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


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

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

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


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

item->child(int i)
item->childcount();
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 24.2.2009, 10:56
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Вопрос про соседа второго узла file1 не нашел. Сможете помочь? Заранее спасибо.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 24.2.2009, 13:04
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Вот код, который проходит по всем элементам и ищет повторяющиеся. Индексы этих элементов запоминает, а затем чистит их. Но, тут непонятная штука вылезла. Что чистит не все повторяющиеся, а только некоторые, хотя заполнение списка идет правильно. Ну то есть, было 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
  опции профиля:
сообщение 24.2.2009, 16:21
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Блин, неужели никто с подобным не сталкивался?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 26.2.2009, 18:51
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Перешел к 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
  опции профиля:
сообщение 27.2.2009, 11:07
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


На прог-орге подсказали ошибку, исправил. Правильный код прохода по дереву и выуживанию лишних элементов такой:
/// Правка дерева этапов полета
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. Ошибка была в том, что удаляя элемент прямо в цикле, я изменяю счетчик элементов и тем самым перескакиваю элемент, который следует удалить.

Сообщение отредактировал AD - 27.2.2009, 11:09
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 16.1.2021, 14:46