Russian Qt Forum
Сентябрь 30, 2024, 20:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QFileSystemModel + QTreeView + Checkboxes  (Прочитано 5787 раз)
CL0NE
Гость
« : Май 17, 2010, 04:04 »

Читал топики Нужен компонент обзора директорий компьютера. Есть ли что-то такое в QT? (из разряда: как прилепить чекбоксы к айтемам в тривью) и QTreeWidget - нажатие на узел дерева ("хочу при клике на чекбоксе в тривью отмечались/снимались галки на чайлдах"). По первому пункту было просто: взял себе QFileSystemModel, переопределил методы setData, data и flags. По второму вышла лабуда (реализация - добавлен сигнал и слот при смене состояния айтема в первой колонке)... т.е. дочерние видимые айтемы отмечаются ибо модель обновилась при их раскрытии и добавила файло/папки себе, но их содержимое еще не было получено и, соответственно, данные субайтемы не отметились. Понятное дело, пробежка по нижележащим каталогами займет много времени. Но как отметить все без потерь? Улыбающийся

И еще 2 нубских вопроса (добавка):
  • Как заставить FileSystemModel следить только за директориями и отображать только их // Ответ - void QFileSystemModel::setFilter ( QDir::Filters filters )
  • setRootPath, судя по документации, сменяет текущую отслеживаемую директорию. как заставить отображать суб-айтемы ниже определенного без соседей и родителей // Ответ - setRootIndex

ниже - текущая реализация:

checkablefilesystemmodel.h
Код
C++ (Qt)
#ifndef CHECKABLEFILESYSTEMMODEL_H
#define CHECKABLEFILESYSTEMMODEL_H
 
#include <QFileSystemModel>
#include <QStandardItem>
 
class CheckableFileSystemModel : public QFileSystemModel
{
   Q_OBJECT
public:
   CheckableFileSystemModel();
   virtual bool setData( const QModelIndex& index, const QVariant& value, int role );
   virtual Qt::ItemFlags flags( const QModelIndex & index ) const;
   virtual QVariant data( const QModelIndex &index, int role )const;
signals:
   void itemChecked(const QModelIndex&);
protected slots:
   void onItemChecked(const QModelIndex& index);
private:
   mutable QMap <qint64, Qt::CheckState> checkedItems;
};
 
#endif // CHECKABLEFILESYSTEMMODEL_H
 

checkablefilesystemmodel.cpp
Код
C++ (Qt)
#include "checkablefilesystemmodel.h"
 
CheckableFileSystemModel::CheckableFileSystemModel()
{
   connect(this, SIGNAL(itemChecked(const QModelIndex&)), SLOT(onItemChecked(const QModelIndex&)));
}
 
bool CheckableFileSystemModel::setData( const QModelIndex& index, const QVariant& value, int role ) {
 
   if( role == Qt::CheckStateRole && index.column() == 0 ) {
 
       checkedItems[ index.internalId() ] = static_cast<Qt::CheckState>( value.toInt() );
       emit itemChecked(index);
       emit dataChanged(index, index.sibling(0,0));
       return true;
 
   }
 
   return QFileSystemModel::setData(index, value, role);
 
}
 
Qt::ItemFlags CheckableFileSystemModel::flags( const QModelIndex & index ) const {
 
   return QFileSystemModel::flags( index ) | Qt::ItemIsUserCheckable;
 
}
 
QVariant CheckableFileSystemModel::data( const QModelIndex& index, int role ) const {
 
   if( role == Qt::CheckStateRole && index.column()==0 ) {
       return QVariant( checkedItems[ index.internalId() ] );
   }
 
   return QFileSystemModel::data( index, role );
}
 
void CheckableFileSystemModel::onItemChecked(const QModelIndex &index)
{
   Qt::CheckState state = checkedItems [index.internalId()];
   fetchMore(index);
   if ( state == Qt::Checked || state == Qt::Unchecked ) {
       for ( int i = 0; i < rowCount(index); i++ ) {
           QModelIndex child = index.child(i, 0);
           if (checkedItems [child.internalId()] != state )
               setData(child, state, Qt::CheckStateRole);
       }
   }
 
   QModelIndex parent = index.parent();
   if (parent.isValid()) {
       state = checkedItems [parent.child(0, 0).internalId()];
       if (state == Qt::PartiallyChecked)
           checkedItems[parent.internalId()] = state;
       else {
           int i = 1;
           while (i < rowCount(parent) && checkedItems [parent.child(i, 0).internalId()] == state)
               i++;
           if (i != rowCount(index))
               state = Qt::PartiallyChecked;
           //setData(parent, state, Qt::CheckStateRole);
           checkedItems [parent.internalId()] = state;
       }
   }
 
}
 
« Последнее редактирование: Май 18, 2010, 02:35 от CL0NE » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.091 секунд. Запросов: 20.