Читал топики
Нужен компонент обзора директорий компьютера. Есть ли что-то такое в QT? (из разряда: как прилепить чекбоксы к айтемам в тривью) и
QTreeWidget - нажатие на узел дерева ("хочу при клике на чекбоксе в тривью отмечались/снимались галки на чайлдах"). По первому пункту было просто: взял себе
QFileSystemModel, переопределил методы
setData,
data и
flags. По второму вышла лабуда (реализация - добавлен сигнал и слот при смене состояния айтема в первой колонке)... т.е. дочерние видимые айтемы отмечаются ибо модель обновилась при их раскрытии и добавила файло/папки себе, но их содержимое еще не было получено и, соответственно, данные субайтемы не отметились. Понятное дело, пробежка по нижележащим каталогами займет много времени. Но как отметить все без потерь?
И еще 2 нубских вопроса (добавка):
- Как заставить FileSystemModel следить только за директориями и отображать только их // Ответ - void QFileSystemModel::setFilter ( QDir::Filters filters )
- setRootPath, судя по документации, сменяет текущую отслеживаемую директорию. как заставить отображать суб-айтемы ниже определенного без соседей и родителей // Ответ - setRootIndex
ниже - текущая реализация:checkablefilesystemmodel.hC++ (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.cppC++ (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;
}
}
}