Использование QFileSystemModel для синхронизации двух представлений с разными элементами
Я создаю вид, похожий на проводник, с деревом каталогов / панелью навигации, используя QTreeView
на левой стороне и вид значка на правой / основной стороне, используя QListView
, На стороне дерева должны отображаться только каталоги (предпочтительно непустые каталоги... но это другая история), а в значке отображаются только файлы с определенным фильтром имен и без каталогов. И я изо всех сил пытаюсь сделать это правильно.
Первое: я не знаю, стоит ли мне использовать один или два QFileSystemModels
для этого. Используя один я фильтрую с двумя прикрепленными QSortFilterProxyModels
для каждого представления - но у меня больше нет свойств файловой системы.... и использование только RegEx для этого является своего рода ограничением. И использование двух моделей оказалось трудным, потому что я не могу нанести на карту QModelIndex
из одной модели в другую, потому что модели содержат разные элементы. Например, когда я нажимаю на каталог слева, корневой путь справа должен обновляться. Но каталог не входит в модель... так что это не работает.
Любые идеи о том, как сделать это правильно? Спасибо!
1 ответ
Как может взаимодействовать представление дерева каталогов файлов и представление навигации по файлам?
Не настаиваю на том, что это единственный способ, но у меня работает:
- Одна модель просмотра фильтрует только каталоги, а другая - только файлы
- Каждое представление (дерево каталогов и файловая навигация) использует отдельный объект файловой модели того же типа, указывающий на некоторый корень
- Синхронизируйте представления, используя путь в файловой системе: когда одно из представлений меняет выбор (в вашем представлении дерева случаев) пользователем, щелчок другого выбирается по тому же пути.
- Имейте в виду, что имея
QSortFilterProxyModel
сначала мы должны получить текущую позицию просмотра оттуда
void MyFileSystemWidget::startViews()
{
// First, initialize QTreeView and QTableView each with own
// QFileSystemModel/QSortFilterProxyModel(MySortFilterProxyModel)
// with individual selection e.g. QDir::Files or QDir::Dirs
//// //// ////
// Make models to point at the same root to start
const QModelIndex rootTreeViewIdx = m_pTreeSortFilterProxyModel->mapFromSource( m_pTreeDataModel->index(rootDir.path()) );
m_pTreeView->setRootIndex(rootTreeViewIdx);
m_pTreeView->setCurrentIndex(rootTreeViewIdx);
const QModelIndex rootFileViewIdx = m_pListSortFilterProxyModel->mapFromSource( m_pListDataModel->index(rootDir.path()) );
m_pTableView->setRootIndex(rootFileViewIdx);
// now connect tree view clicked signal
connect(m_pTreeView, SIGNAL(clicked(QModelIndex)), SLOT(onTreeViewClicked(QModelIndex)));
}
void MyFileSystemWidget::onTreeViewClicked(const QModelIndex& treeIndex)
{
// see MySortFilterProxyModel::sourceFileInfo
QString modelPath = m_pTreeSortFilterProxyModel->sourceFileInfo( treeIndex ).absoluteFilePath();
if (modelPath.isEmpty())
return;
// see MySortFilterProxyModel::setSourceModelRootPath
const QModelIndex proxyIndex = m_pListSortFilterProxyModel->setSourceModelRootPath(modelPath);
m_pTableView->setRootIndex(proxyIndex);
}
QFileInfo MySortFilterProxyModel::sourceFileInfo(const QModelIndex& index)
{
if (!index.isValid())
return QFileInfo();
const QModelIndex proxyIndex = mapToSource( index );
if (!proxyIndex.isValid())
return QFileInfo();
return static_cast<QFileSystemModel*>(sourceModel())->fileInfo(proxyIndex);
}
QModelIndex MySortFilterProxyModel::setSourceModelRootPath(const QString& modelPath)
{
const QModelIndex fmIndex = static_cast<QFileSystemModel*>(sourceModel())->setRootPath(modelPath);
return mapFromSource( fmIndex );
}