Russian Qt Forum

Qt => Вопросы новичков => Тема начата: koldun90 от Июль 31, 2014, 13:24



Название: qfilesystemmodel
Отправлено: koldun90 от Июль 31, 2014, 13:24
Здравствуйте вы не могли бы пояснить что нужно сделать что бы модель отображала не всю файловую систему ,а отображала только несколько
каталогов( мне нужно чтоб отображало корень"/",домашнюю директорию "/root"(директория пользователя root), а также еще каталог /mnt. Работаю в linuх. я так понимаю что нужно что то переопределить в qfilesystemmodel но вот что не знаю...
(http://s006.radikal.ru/i213/1407/ee/a2e7e5231afbt.jpg) (http://radikal.ru/fp/362eff5580264b6f8005a687f69d1fc6)


Название: Re: qfilesystemmodel
Отправлено: Пантер от Июль 31, 2014, 13:37
1. void QFileSystemModel::setNameFilters(const QStringList & filters)
2. Можно пропустить ее через QSortFilterProxyModel.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Июль 31, 2014, 14:43
1. void QFileSystemModel::setNameFilters(const QStringList & filters)
2. Можно пропустить ее через QSortFilterProxyModel.

Код:
const QStringList & filters
я так понял этот список должен содержать папки которые я собираюсь отображать
те в моем случае он должен включать /, /mnt, /root

и что значит "Можно пропустить ее через QSortFilterProxyModel." поясните подробнее?


Название: Re: qfilesystemmodel
Отправлено: Пантер от Июль 31, 2014, 14:45
QSortFilterProxyModel используется для того, чтобы отсортировать другую модель, либо применить к ней фильтр. Подробнее ты можешь прочитать в Ассистенте и посмотреть примеры.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Июль 31, 2014, 16:00
ну допустим сделал я так
Код:
QStringList filters;
filters<<"/mnt";
filters<<"/root";
model1->setNameFilters(filters);
в итоге получилось что
(http://s41.radikal.ru/i091/1407/fb/da9b197fa03ft.jpg) (http://radikal.ru/fp/b741b34c40cd428f89a1186c32d6f67d)


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 01, 2014, 07:26
Да, не оно. Тогда через прокси модель.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 01, 2014, 09:22
Цитировать
QSortFilterProxyModel используется для того, чтобы отсортировать другую модель, либо применить к ней фильтр

ВЫ меня неправильно поняли наверно мне нужно чтобы как бы отображалось в моделе всего несколько каталогов допустим:

+/
    +/root
    +/home
    +/mnt
и все собственно мне поможет это сделать QSortFilterProxyModel?

и скажите какой метод смотреть в QSortFilterProxyModel?


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 01, 2014, 09:35
и все собственно мне поможет это сделать QSortFilterProxyModel?
Да. Отнаследуйся от нее и реализуй
Код
C++ (Qt)
bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const [virtual protected]
 


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 09:18
начал я реализовывать сделал так

mainwindow.cpp
Код:
{
    model1=new myqfilesystemmodel;  //модель файловой системы ничего не переопределено

    model2=new myqsortfilterproxymodel;  //переопределен filteracceptrow


    model1->setRootPath(QDir::rootPath());   //QDir::rootPath()--возвращает корень "/"
    model1->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);  //устанавливаю фильтер

    model2->setSourceModel(model1); // засовываю myqfilesystemmodel в
myqsortfilterproxymodel
    ui->treeView->setModel(model2); // в трививеве отображаю myqsortfilterproxymodel
    ui->treeView->hideColumn(2);  // скрываю столбец один
 }


myqsortfilterproxymodel.cpp

Код:
myqsortfilterproxymodel::myqsortfilterproxymodel()
{
    r=new myqfilesystemmodel;
}

Код:
bool myqsortfilterproxymodel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{


    QString str=r->fileInfo(source_parent).absoluteFilePath();  //беру индекс который попадает в метод
 
        if (str=="/" || str=="/root" || str=="/mnt/cdrom")  // затем сравниваю его с заданными //индексами
        {
            return true; // и если индекс является одним из 3ех то я его добавляю в отображение
        }
        else
        {
            return false; // иначе не добавляю
        }

}

p.s я так понял в документации написано так "Returns true if the item in the row indicated by the given source_row and source_parent should be included in the model; otherwise returns false."

ТЕ возвратит true если source_parent должна включаться в отображение, если не должна то false..

В итоге после запуска программы treeview вообще пустой ,те в модель не добавляется ничего хотя по идее там должно быть 3 каталога исходя из вышеприведенного кода
"/"--корневой каталог
"/root"--каталог пользователя root
"/mnt/cdrom"--каталог cdrom


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 04, 2014, 09:35
    r=new myqfilesystemmodel;
нахрена в конструкторе?


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 09:42
мне нужно взять информацию о индексе source_parent для
этого нужно использовать fileinfo это метод класса qfilesystemmodel
как вы предлагаете сделать?


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 04, 2014, 09:43
Допустим:
qobject_cast<QFileSystemModel*> (sourceModel ())


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 09:57
вы имеете ввиду
Код:
qobject_cast<QFileSystemModel*> (sourceModel ())->fileinfo(source_parent); 
??



Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 10:11
а что мне это даст я не понимаю у меня не отображаются каталоги в представлении модели...


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 04, 2014, 10:38
Из моего старого проекта (https://github.com/panter-dsd/QDBFRedactor/blob/master/src/core/dbfredactorsortfilterproxymodel.cpp) - может, поможет.


Название: Re: qfilesystemmodel
Отправлено: gil9red от Август 04, 2014, 10:46
вы имеете ввиду
Код:
qobject_cast<QFileSystemModel*> (sourceModel ())->fileinfo(source_parent); 
??



Скорее так правильнее будет:
Код:
(qobject_cast<QFileSystemModel*> (sourceModel ()))->fileinfo(source_parent); 
А лучше так:
Код:
QFileSystemModel * fileSystemModel = qobject_cast<QFileSystemModel*> (sourceModel());
if (fileSystemModel) {
   const QFileInfo & info = fileSystemModel->fileinfo(source_parent);
   qDebug() << info.absolutePath();
}

 :)


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 11:09
Код:

    QFileSystemModel *t=qobject_cast<QFileSystemModel*> (sourceModel());
    QString str=t->fileInfo(source_parent).absoluteFilePath();


еще я заметил такую штуку
если распечатывать значение str

Код:
   QMessageBox msg;
   msg.setText(str);
   msg.exec
то постоянно выводит "/"


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 04, 2014, 11:20
Так source_parent же один, ты source_row юзай.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 11:33
даже если делаю так
Код:
    QFileSystemModel *t=qobject_cast<QFileSystemModel*> (sourceModel());
    QString str=t->fileInfo(source_parent).absoluteFilePath();

    QFileSystemModel *fileSystemModel = qobject_cast<QFileSystemModel*> (sourceModel());
    if (fileSystemModel)
    {
        const QFileInfo & info=fileSystemModel->fileInfo(source_parent);
       QString str= info.absoluteFilePath();
       QMessageBox msg;
       msg.setText(str);
       msg.exec();
       return true;
    }


то все равно всегда str= "/"


Название: Re: qfilesystemmodel
Отправлено: gil9red от Август 04, 2014, 11:37
даже если делаю так
Код:
    ...
    if (fileSystemModel)
    {
        const QFileInfo & info=fileSystemModel->fileInfo(source_parent);
    ...


то все равно всегда str= "/"

Так source_parent же один, ты source_row юзай.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 12:49
source_row-- я так понимаю это номер строки чтоль?


Название: Re: qfilesystemmodel
Отправлено: gil9red от Август 04, 2014, 13:04
source_row-- я так понимаю это номер строки чтоль?

и все собственно мне поможет это сделать QSortFilterProxyModel?
Да. Отнаследуйся от нее и реализуй
Код
C++ (Qt)
bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const [virtual protected]
 

Ну я думаю, что про это имело ввиду :)


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 13:08
да имел ввиду это
source_row -- я так понимаю это номер строки?


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 04, 2014, 13:09
да имел ввиду это
source_row -- я так понимаю это номер строки?
Да, считая от парента.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 13:25
тогда не совсем понятно допустим начинает выполняться моя программа корневой каталог "/"
при каждом входе в данный метод происходит так

Source_parent="/" постоянно
а source_row меняется от 0 и далее....
так вот как мне определить получается какую строку от парента надо добавить ( в данном случае мне нужно /root и  /mnt/cdrom допустим??


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 04, 2014, 13:30
Разбери примеры по прокси модели, там все не так уж сложно, главное, понять.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 13:39
если считать что source row -- номер строки от парента
я запустил прогу посчитал что строка "mnt" у меня имеет номер 32
а строка "root" имеет номер 42

сделал такое условие
Код:
if ((str=="/" && source_row==32) || (str=="/" && source_row==42)
{
    return true;
}
else
{
    return false;
}
судя по этому он должен вывести в представлении тогда два каталога 32-- это mnt 42--это root
но при выполнении программы модель пустая


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 13:43
извините а не могли бы ссылочку на примеры если не сложно
просто что то совсем непонятно....


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 04, 2014, 13:47
Ты можешь у sourceModel запросить нужный индекс:
sourceModel ()->index (source_row, 0, parent_index)

Примеры поставляются с Кьютом в каталоге examples.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 04, 2014, 14:58
в примере вот так вот написано
Код:
bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,
        const QModelIndex &sourceParent) const
{
    QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
    QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent);
    QModelIndex index2 = sourceModel()->index(sourceRow, 2, sourceParent);

    return (sourceModel()->data(index0).toString().contains(filterRegExp())
            || sourceModel()->data(index1).toString().contains(filterRegExp()))
           && dateInRange(sourceModel()->data(index2).toDate());
}

мне вес равно не понятно

у меня так
Код:
bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,const QModelIndex &sourceParent)
{   
    QMessageBox msg;
    QModelIndex resource=sourceModel()->index(source_row,0,source_parent); // проходимся по всем строкам и суем их в Modelindex
    QFileSystemModel *fileSystemModel = qobject_cast<QFileSystemModel*> (sourceModel());
    if (fileSystemModel)
    {
       const QFileInfo & info2=fileSystemModel->fileInfo(resource);
       QString str=info2.absoluteFilePath();  //берем абсолютный путь reosurce
       if (str.contains("/root")) // если путь содержит папку
       {
           return sourceModel()->data(resource).toString().contains("/root"); //как в примере
           
       }
       else
       {
           return false;
       }
    }
}



Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 05, 2014, 10:46
еще возник вопрос допустим я засовываю свою модель
 model3--myqfilesystemmodel
в модель для сортировки
model4--myqsortsystemmodel
и отображаю ее в тривеве

Код:
model4->setSourceModel(model3)
ui->treeview->setModel(model4)

но возникает вопрос у меня допустим есть метод клика по тривиеву.

Код:
treeview_clicked(QModelIndex &index)

раньше я брал путь вот так когда не было прокси модели

Код:
QString str=model3->fileInfo(index).absolutefilepath();

а когда я стал использовать прокси этот код вызывает краш...

что нужно мне теперь использовать чтоб взять полный путь индекса?


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 05, 2014, 10:53
Читай про mapToSource.


Название: Re: qfilesystemmodel
Отправлено: koldun90 от Август 07, 2014, 14:37
Спасибо за помощь.
Возник у меня еще один вопросик как сделать так
(http://s019.radikal.ru/i622/1408/a4/90a25ce45690.png) (http://www.radikal.ru)

мне нужно чтобы каталог "/" был как бы на одной линии с "/mnt" и "/root"
те у меня сейчас как бы каталоги mnt и root являются подкаталогами корня "/"
а мне нужно сделать чтобы был отдельно каталог / а под ними /mnt и /root
с помощью чего можно это сделать?
И еще скажите как можно отобразить две модели файловой системы в одном виджете( например treeviewe)


Название: Re: qfilesystemmodel
Отправлено: Пантер от Август 08, 2014, 07:47
И еще скажите как можно отобразить две модели файловой системы в одном виджете( например treeviewe)
Написать модель, которая объединит эти 2 модели. :)