Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

QFileSystemModel and QSortFilterProxyModel - root index is not preserved


  • Lifetime Qt Champion

    Hi,

    That might be the case.

    One thing you can do to get more answers: provide a minimal compilable example to reproduce that behaviour. While you are giving some code to reproduce it, people will have to rewrite it in order to build something functional that may or may not trigger the issue you have. If everybody has the same code, then it's going to be way easier to find out whether it's a Qt issue or something else.



  • It is minimal example. In the comments at the beginning I've written what base classes are used, and implementation details are not important as they are related to supporting drag and drop only, and custom icons.


  • Qt Champions 2018

    @MasterBLB "minimal compilable example".
    What you provided are some code snippets, nothing one can compile.
    It is important to have a minimal example showing the issue, because the issue could be in other parts of the code than what you posted.
    Also, if you only post code snippets you're actually asking others to create a minimal compilable example...


  • Lifetime Qt Champion

    Sorry but no it's not.

    It's neither minimal nor compilable.

    • It can't be just copied and pasted in a main.cpp to be built.
    • There's no main function to launch the application
    • There's a designer based ui used that is not available
    • You are using subclasses that are maybe doing something or not so we don't know whether it's in that part that something is going on.

    Therefore, you are asking people to write and build themselves that minimal use case to find out whether they can reproduce your issue.



  • Well, I was sure Qt Champions are capable of:

    • creaing a QTreeView instance
    • creating a QFileSystemModel instance
    • creating a QSortFilterProxyModel instance
    • apply a simple filter for the filter model

    well then, here is main:

    int main(int argc, char *argv[])
    {
       QApplication a(argc, argv);
        
       QTreeView treeView;
    
       QFileSystemModel navigationModel;
        navigationModel.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Files);
        navigationModel.setNameFilterDisables(true);
    QString root(/*set it somewhere into directory structure, say C:/Qt/some version*/);
    navigationModel.setRootPath(root);
    
    QSortFilterProxyModel filteringModel;
    filteringModel.setSourceModel(&navigationModel);
        filteringModel.setRecursiveFilteringEnabled(true);
        filteringModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
    
        treeView.setModel(&filteringModel);
        treeView.setRootIndex(filteringModel.mapFromSource(navigationModel.index(root)));
    
    filteringModel.setFilterFixedString(/*put some folder name which appears deeper in the choosen root*/);
    
        treeView.show();
    
       return a.exec();
    }
    

  • Qt Champions 2018

    @MasterBLB said in QFileSystemModel and QSortFilterProxyModel - root index is not preserved:

    Well, I was sure Qt Champions are capable of

    You're the one asking for help. It is not about whether Qt champions are capable of doing this or not, it's simply about to help others to help you. You're aware that your list means work for others, right? People in this forum are not paid workers who have to work for you, but just volunteers spending their own time to help others...



  • And that's why I've written the example within around 60s, as requested. I hope it fulfills expectations, but if needed feel free to ask about implementation details of models, though as mentioned there isn't anything related to manipulating root index.


  • Lifetime Qt Champion

    Hi
    I can confirm it get the same result on Qt5.12.3 and Qt5.9
    so at least we can say its not a local bug of sorts.
    alt text

    #include <QApplication>
    #include <QFileSystemModel>
    #include <QSortFilterProxyModel>
    #include <QTreeView>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QTreeView treeView;
    
        QFileSystemModel navigationModel;
        navigationModel.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Files);
        navigationModel.setNameFilterDisables(true);
        QString root("C:/Qt/5.12.3/msvc2017_64");
        navigationModel.setRootPath(root);
    
        QSortFilterProxyModel filteringModel;
        filteringModel.setSourceModel(&navigationModel);
        filteringModel.setRecursiveFilteringEnabled(true);
        filteringModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
    
        treeView.setModel(&filteringModel);
        treeView.setRootIndex(filteringModel.mapFromSource(navigationModel.index(root)));
    
        filteringModel.setFilterFixedString("Lib");
    
        treeView.show();
    
        return a.exec();
    }
    
    

  • Lifetime Qt Champion

    As @mrjj I can reproduce that on macOS with a recent build of Qt.

    You should check the bug report system to see if there's already something related. If not, then please consider opening a new report providing that minimal compilable example.



  • Oh crap, tough luck :/ How to open a Qt bug report?


  • Lifetime Qt Champion

    @MasterBLB
    Hi
    Well you just go there and login with the credentials you use here.
    A good read is
    https://wiki.qt.io/Reporting_Bugs



  • @mrjj , @SGaist - have you reported the bug? If not I will try when I'll go back home after work.


  • Lifetime Qt Champion

    Personally, I didn't. Since you found it, the honour is yours :)


  • Lifetime Qt Champion

    Hi
    nope, if i had made report, i would have linked url here :)
    So please do.


  • Qt Champions 2018

    I don't think it's a bug.
    setRootIndex is a method of the view. The model has no way of knowing (and shouldn't know) what a view is using as root. The filter set on the proxy applies to the whole model. If the index used as root by a view gets filtered out it's only natural for a view to revert to using QModelIndex() as root.

    What you need is a proxy model that implements the setRootIndex functionality at the model level. This is on the list of nice-things-I-would-like-to-add-to-Qt-models and it's a fairly easy one to do but I need to find time for it :(



  • ...and now I'm confused :/



  • @MasterBLB
    Confused in what way? I have just read this thread and what @VRonin has written seems correct to me. Are you not understanding what he is saying, or what?



  • In the way such behavior breaks SOLID substitute rule - I can't use descendant class QFileSystemModel like it was its base class QAbstractItemModel in QSortFilterProxyModel. While not a 100% bug it's definitely a serious design flaw, and worth to be reported. But where?


  • Qt Champions 2018

    @MasterBLB said in QFileSystemModel and QSortFilterProxyModel - root index is not preserved:

    But where?

    In Qt bug tracker https://bugreports.qt.io/secure/Dashboard.jspa
    Also you can talk to Qt developers on their mailing list.


  • Qt Champions 2018

    breaks SOLID

    It doesn't. In fact, if it worked as you expected it would break SOLID

    it's definitely a serious design flaw

    Sorry to be brutal: No, it's not a flaw, you just didn't understand the design of model/views.
    To help you get a better idea of what is going on, try use the same model with 2 different treeviews. In only one of the view call setRootIndex, and then trigger the filtering.