Results 1 to 9 of 9

Thread: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

  1. #1
    Join Date
    Jul 2013
    Posts
    15
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    Hi all,

    WinXPsp3
    Qt5.0.2 and Qt Creator 2.7.0

    My first Qt GUI App ... been coding C for many many years, have simple basic C++ skills, no GUI experience, Very little OO experience.
    So ALL explained comments and suggestions welcome.
    I'm it it to learn, so if there is a better way ...

    The goal:
    To have a sorted directory only TreeView on the left, the files of the currently selected directory are listed (filtered and sorted) in the ListView (or TableView) in the middle, the elements of the currently selected file are listed in the (yet to be added) TableView to the right.

    Info:
    A TreeView populated with QFileSystemModel wrapped with a QSortFilterProxyModel purely for sort, no filters ... There is also a QItemSelectionModel attached!
    A ListView populated with QFileSystemModel wrapped with a QSortFilterProxyModel for sort and filter purposes ... There is also a QItemSelectionModel attached.

    Question 1:
    Once the proxyModel is attached, how does one setRootPath(...) of the under laying QFileSystemModel.
    I also need the QModelIndex returned from that setRootPath(...) call as well.

    See commented code at end of .cpp to see how I had previously done it prior to the proxyModel.

    Have tried many things, to many to list all (besides I'm sure I've forgotten more then I remember)
    Like casting the proxies sourceModel(...) as I've seen others do in my searches.

    Question 2:
    Maybe my whole design is flawed?

    For the ui:
    TreeView named directoryTreeView
    ListView named filenameListView

    The code:
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include <QFileSystemModel>
    6. #include <QItemSelectionModel>
    7. #include <QSortFilterProxyModel>
    8. #include <QtDebug>
    9.  
    10. namespace Ui {
    11. class MainWindow;
    12. }
    13.  
    14. class MainWindow : public QMainWindow
    15. {
    16. Q_OBJECT
    17.  
    18. public:
    19. explicit MainWindow(QWidget *parent = 0);
    20. ~MainWindow();
    21.  
    22. private slots:
    23. void filenameSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
    24.  
    25. void directorySelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
    26.  
    27. private:
    28. Ui::MainWindow *ui;
    29. // directory Tree View
    30. QFileSystemModel *QFSMdirectoryView;
    31. QItemSelectionModel *directorySelectionModel;
    32. QSortFilterProxyModel *directorySortFilterModel;
    33. // filename List View
    34. QFileSystemModel *QFSMfilenameView;
    35. QItemSelectionModel *filenameSelectionModel;
    36. QSortFilterProxyModel *filenameSortFilterModel;
    37. };
    38.  
    39. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #include "MainWindow.h"
    2. #include "ui_MainWindow.h"
    3.  
    4. MainWindow::MainWindow(QWidget *parent) :
    5. QMainWindow(parent),
    6. ui(new Ui::MainWindow)
    7. {
    8. ui->setupUi(this);
    9.  
    10. QString qsPath = QDir::currentPath();
    11.  
    12. // directory Tree View
    13. QFSMdirectoryView = new QFileSystemModel(this);
    14. QFSMdirectoryView->setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
    15.  
    16. directorySortFilterModel = new QSortFilterProxyModel(this);
    17. directorySortFilterModel->setSourceModel(QFSMdirectoryView);
    18. directorySortFilterModel->sort(0, Qt::AscendingOrder);
    19.  
    20. ui->directoryTreeView->setModel(directorySortFilterModel);
    21. ui->directoryTreeView->setSortingEnabled(true);
    22. ui->directoryTreeView->setColumnHidden(1, true);
    23. ui->directoryTreeView->setColumnHidden(2, true);
    24. ui->directoryTreeView->setColumnHidden(3, true);
    25.  
    26. directorySelectionModel = new QItemSelectionModel(directorySortFilterModel);
    27. ui->directoryTreeView->setSelectionModel(directorySelectionModel);
    28. connect(directorySelectionModel, SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT(directorySelectionChanged(QItemSelection,QItemSelection)));
    29.  
    30. QFSMdirectoryView->setRootPath(qsPath);
    31.  
    32. // filename List View
    33. QFSMfilenameView = new QFileSystemModel(this);
    34. QFSMfilenameView->setFilter(QDir::Files | QDir::NoDotAndDotDot);
    35.  
    36. filenameSortFilterModel = new QSortFilterProxyModel(this);
    37. filenameSortFilterModel->setSourceModel(QFSMfilenameView);
    38. filenameSortFilterModel->sort(0, Qt::AscendingOrder);
    39.  
    40. ui->filenameListView->setModel(filenameSortFilterModel);
    41.  
    42. filenameSelectionModel = new QItemSelectionModel(filenameSortFilterModel);
    43. ui->filenameListView->setSelectionModel(filenameSelectionModel);
    44. connect(filenameSelectionModel, SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT(filenameSelectionChanged(QItemSelection,QItemSelection)));
    45. }
    46.  
    47. MainWindow::~MainWindow()
    48. {
    49. delete ui;
    50. }
    51.  
    52. void MainWindow::filenameSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
    53. {
    54. QString qsPath = QFSMfilenameView->filePath(selected.indexes()[0]);
    55. qDebug() << "Selected filename: " << qsPath;
    56. }
    57.  
    58. void MainWindow::directorySelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
    59. {
    60. QString qsPath = directorySortFilterModel->data(selected.indexes()[0], QFileSystemModel::FilePathRole).toString();
    61.  
    62. // Obviously this no longer works with the proxy ...
    63. // QModelIndex index = QFSMfilenameView->setRootPath(qsPath);
    64. // ui->filenameListView->setRootIndex(index);
    65. }
    To copy to clipboard, switch view to plain text mode 
    -Enjoy
    fh : )_~

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    Keep a pointer to the source model and call setRootPath() on that. Take the returned QModelIndex and call mapFromSource() on the proxy model to get a filtered-side index that corresponds

  3. #3
    Join Date
    Jul 2013
    Posts
    15
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    You mean like this ...
    Qt Code:
    1. QFSMfilenameView = new QFileSystemModel(this);
    To copy to clipboard, switch view to plain text mode 
    and
    Qt Code:
    1. QModelIndex index = QFSMfilenameView->setRootPath(qsPath);
    To copy to clipboard, switch view to plain text mode 

    -Enjoy
    fh : )_~

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    Qt Code:
    1. QModelIndex sourceIndex = QFSMfilenameView->setRootPath(qsPath); // gives a model index on the original model
    2. QModelIndex proxyIndex = filenameSortFilterModel->mapFromSource(sourceIndex); // converts that to an index on the proxy
    3. // do something with the view(s) using the proxy index
    4. ui->filenameListView->setRootIndex(proxyIindex);
    To copy to clipboard, switch view to plain text mode 
    You need the index on the proxy because those are the indexes the view(s) you have attached to the proxy will see and use.

  5. #5
    Join Date
    Jul 2013
    Posts
    15
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    I have done exactly that excluding the proxyIndex (had it at one time), no point in having it because the code
    Qt Code:
    1. QFSMfilenameView->setRootPath(qsPath);
    To copy to clipboard, switch view to plain text mode 
    Returns an invalid index after the QSortFilterProxyModel has been attached.

    And yes, qsPath is valid.

    EDIT:
    Off topic, but ... What tags are used to get the Qt objects to link to the docs like you do in your posts?

    -Enjoy
    fh : )_~

  6. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    The base model is unaware of the proxy which interacts with it no differently than a view would. I guess the question is, what are you trying to achieve?

    Many Qclasses are linked automatically when they are inside [code][/code] tags. Outside of code use can use [qtclass][/qtclass] or [docs=somesuch.html#anchor][/docs]

  7. #7
    Join Date
    Jul 2013
    Posts
    15
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    Hate to be a dink ... But!

    Did you even read the OP?

    Everything that has been discussed so far (other then the Markup tags) is in the unedited OP.
    Including the goal!

    Thanks for the [qtclass] markup tags.

    -Enjoy
    fh : )_~

  8. #8
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    Yes I read the OP. At your kind invitation I have re-read it. Your variable naming had me mildly confused (e.g. models and views with names ending View) and I was assuming that both views sat on the same model. There's no mention of mapFromSource() in your OP, so you've learned something new there.

    You are retrieving a path from the directory view. You have a correct path to a directory.

    You want that path to be the root of the file view. You need the index of that path in the model underlying the file view and QFileSystemModel::index() does that.
    Qt Code:
    1. QModelIndex index = QFSMfilenameView->index(qsPath);
    2. // your view is sitting on the top of a proxy you need to map the index to a proxy index:
    3. QModelIndex proxyIndex = filenameSortFilterModel->mapFromSource(index);
    4. // before you can use that to set the root of the file view:
    5. ui->filenameListView->setRootIndex(proxyIndex);
    To copy to clipboard, switch view to plain text mode 
    Unfortunately this doesn't work because QFSMfilenameView is filtered to exclude directories, and the path you are supplying is a directory, so there is no index in the source model for that path. As a result, both indexes are invalid and the file view does not behave as expected. If you remove the filter on the QFSMfilenameView the indexes are good but the file view displays directories you don't want.

    I cannot see a straightforward way to make this work with the models as is. You may be able to use the file proxy to filter on QFileSystemModel::type() to exclude "Directory" or "Folder".

  9. #9
    Join Date
    Jul 2013
    Posts
    15
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: how to setRootPath(...) on a QSortFilterProxyModel of a QFileSystemModel

    Beautiful ... I understand!

    As already stated I removed the proxyIndex (mapToSource) for the post, it wasn't working, not needed for the question.

    Yup, I agree about the "View" variable names on the data models... I already changed them to be more inline with the others. Hey, It's where I started!

    Working on trying to come up with a different design, ain't visioned one yet ...

    Thank you

    -Enjoy
    fh : )_~

Similar Threads

  1. Replies: 7
    Last Post: 13th February 2014, 07:23
  2. Replies: 2
    Last Post: 9th July 2013, 11:13
  3. Replies: 3
    Last Post: 22nd August 2012, 04:32
  4. Replies: 0
    Last Post: 9th March 2011, 01:08

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.