Proxy for the QFileSystemModel



  • [code]
    #include <QtCore>
    #include <QtGui>

    class busyProxy : public QSortFilterProxyModel
    {
    Q_OBJECT
    public:
    explicit busyProxy(QObject *parent = 0) : QSortFilterProxyModel(parent) {}

    bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
    {
        QModelIndex index = sourceModel()->index(source_row, 0, source_parent);        
        QString const &text = sourceModel()->data(index).toString();
        //the folder "very big" contains a lot of jpg, and I only want
        //to show one of it which name "kkk0.jpg"        
        if(text == "kkk0.jpg" || text == "kkk1000.jpg" || text == "kkk10.jpg") return true;
        
        if(text == "very big") return true;              
    
        return false;
    }
    
    bool lessThan(const QModelIndex &left, const QModelIndex &right) const
     {
         QString const leftString = sourceModel()->data(left).toString();
         QString const rightString = sourceModel()->data(right).toString();
    
         qDebug() << leftString << ", " << rightString;
    
         return leftString > rightString;
     }
    

    };

    //Do nothing, only want to compare with the busyProxy
    class lazyProxy : public QSortFilterProxyModel
    {
    Q_OBJECT
    public:
    explicit lazyProxy(QObject *parent = 0) : QSortFilterProxyModel(parent) {}
    };

    class testProxyFiles : public QWidget
    {
    public:
    testProxyFiles()
    {
    QFileSystemModel *model = new QFileSystemModel(this);

        lazyProxy *lazyPro = new lazyProxy(this);
        lazyPro->setSourceModel(model);
    
        QTableView *sourceView = new QTableView(this);
        sourceView->setModel(lazyPro);
        QString const rootPath = "E:/file_test/very big";
        sourceView->setRootIndex(lazyPro->mapFromSource(model->setRootPath(rootPath)));
    
        QTableView *proxyView = new QTableView(this);
        busyProxy *busyPro = new busyProxy(this);
        busyPro->setSourceModel(model);
        proxyView->setModel(busyPro);
        proxyView->setRootIndex(busyPro->mapFromSource(model->setRootPath(rootPath)));
    
        QHBoxLayout *layout = new QHBoxLayout(this);
        layout->addWidget(sourceView);
        layout->addWidget(proxyView);
    
        setLayout(layout);
    }    
    

    };

    inline int proxyFiles(QApplication &app)
    {
    testProxyFiles proxy;
    proxy.show();

    return app.exec();
    

    }

    int main( int argc, char **argv )
    {
    QApplication app( argc, argv );

    proxyFiles(app);

    return 0;
    }
    [/code]

    I have several questions :
    1 : On line 16~18, do I have other solution to filter out the item of the QFileSystemModel?
    The QFileSystemModel would navigate the root first, if I don't return true when the text
    equal to "very big", the proxy wouldn't navigate the files inside "very big"

    2 : when I show the item by busyProxy or lazyProxy, the indexes on the leftside are weird, how could
    I edit them?When I set the QFileSystemModel as the model of QtableView, the indexes looks fine.

    3 : the lessThan function never print anything, but why?

    4 : Do you have any easy examples for the proxy of QFileSystemModel? I can't find a topic
    talk about how to design a proxy for QFileSystemModel

    Thanks a lot



  • Besides, how could I ask the view to display all of the drives(win7)?
    [code]
    sourceView->setRootIndex(lazyPro->mapFromSource(model->setRootPath(rootPath)));
    [/code]

    What kind of path should I set at the "setRootPath" function?Thanks



  • [quote author="stereomatching" date="1343302015"]Besides, how could I ask the view to display all of the drives(win7)?
    [code]
    sourceView->setRootIndex(lazyPro->mapFromSource(model->setRootPath(rootPath)));
    [/code]

    What kind of path should I set at the "setRootPath" function?Thanks[/quote]

    Setting an empty path works for me.



  • Thanks, setting an empty path also work for me.



  • Hi stereoMatching,
    Did you find a way the filtred files ?

    I am pulling my hair for a week to find a way to display with a treeview and qfilesystemmodel and a SFPModel...

    And I agree with you => 4 : Do you have any easy examples for the proxy of QFileSystemModel? I can’t find a topic talk about how to design a proxy for QFileSystemModel

    there is no exemples to use, in my case, a QfilesystemModel + treeview + SFPM to filter dirs only and/or files



  • Sort of, but I have to design many filters to meet my requirement.
    I think I would choose custom widget to solve my problem in
    the future.

    Currently I am using two QDirModel to design my app, because
    QFileSystemModel(maybe)has some bug and design a lot of proxy
    will make my codes become harder to maintain.
    "bug of QFileSystemModel?":http://qt-project.org/forums/viewthread/19168/

    @
    #ifndef PROXYTEST2_HPP
    #define PROXYTEST2_HPP

    #include <QtCore>
    #include <QtGui>

    class fileProxy : public QSortFilterProxyModel
    {
    Q_OBJECT

    public:
    explicit fileProxy(QObject *parent = 0) : QSortFilterProxyModel(parent) {}
    QString currentAbsPath_;

    protected:
    virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
    {
    QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
    QDirModel* filemodel = qobject_cast<QDirModel*>(sourceModel());
    QFileInfo info = filemodel->fileInfo(index);
    if(info.absolutePath() != currentAbsPath_)
    {
    return true;
    }

        /*
        //filter files
        if(info.isFile&#40;&#41; && info.absolutePath(&#41; == currentAbsPath_)
        {
            return false;
        }*/
    
        //filter directories, you must add info.absolutePath() != info.absoluteFilePath() to prevent
        //the filter filter out the absolutePath
        if(info.isDir() && info.absolutePath() != info.absoluteFilePath() && info.absolutePath() == currentAbsPath_)
        {
            return false;
        }
    
        return true;
    }
    

    };

    class Proxy2 : public QWidget
    {
    Q_OBJECT

    public:
    Proxy2()
    {
    model_ = new QDirModel(this);

        normalProxy_ = new QSortFilterProxyModel(this);
        normalProxy_->setSourceModel(model_);
    
        proxy_ = new fileProxy(this);
        proxy_->setSourceModel(model_);
    
        treeView_ = new QTreeView(this);
        treeView_->setModel(normalProxy_);
        connect(treeView_, SIGNAL(clicked(QModelIndex)), this, SLOT(changeTableRootIndex(QModelIndex)));
    
        tableView_ = new QTableView(this);
        tableView_->setModel(normalProxy_);
    
        fileBox_ = new QCheckBox(this);
        fileBox_->setText("file");
        connect(fileBox_, SIGNAL(clicked(bool)), this, SLOT(changeProxy(bool)));
    
        QHBoxLayout *layout = new QHBoxLayout(this);
        layout->addWidget(treeView_);
        layout->addWidget(tableView_);
        layout->addWidget(fileBox_);
    
        setLayout(layout);
    }
    

    private slots:
    //if you need different criteria to filter out the files,
    //you have to change the proxy dynamically
    void changeProxy(bool enable)
    {
    if(enable)
    {
    QModelIndex index = treeView_->currentIndex();
    proxy_->currentAbsPath_ = model_->fileInfo(normalProxy_->mapToSource(index) ).absolutePath();

            tableView_->setModel(proxy_);
            changeTableRootIndex(index);
        }
        else
        {
            tableView_->setModel(normalProxy_);
            changeTableRootIndex(treeView_->currentIndex() );
        }
    }
    
    void changeTableRootIndex(QModelIndex const &index)
    {
        if(fileBox_->isChecked())
        {
            QModelIndex sourceIndex = normalProxy_->mapToSource(index);
            tableView_->setRootIndex(proxy_->mapFromSource(sourceIndex));
        }
        else
            tableView_->setRootIndex(index);
    }
    

    private:
    QDirModel *model_;
    QSortFilterProxyModel *normalProxy_;
    fileProxy *proxy_;
    QTableView *tableView_;
    QTreeView *treeView_;
    QCheckBox *fileBox_;
    };

    //I am lazy to separate declaration and implement, so I inline it
    inline int testProxy2(QApplication &app)
    {
    Proxy2 p2;
    p2.show();

    return app.exec&#40;&#41;;
    

    }

    #endif // PROXYTEST2_HPP

    @

    The codes are pretty messy and full of poor coding style
    it is just for experiment, only show you how to filter the
    files.



  • The view(?) will traverse the treemodel recursively
    Assume there are a path "E:/D/C/B/A"
    if you return false when the path is "E:/"
    All of the path will be filter out(D/C/B/A)

    Using this filter is not a good solution for my app,
    so I give up already and turn my target to custom widget,
    ch6 of "advanced Qt programming" teach you how to do that.
    Design a customize QWidget to display the model data is pretty cumbersome.

    Frankly speaking, current model/view architecture is pretty
    complicated, especially when you want to deal with treeModel.



  • Hi stereoMatching,
    Thank you very much for sharing your code and for your help.
    I will test your code and try to obtain what I want, but I think I will leave the treeview to another type of view with which I am comfortable.

    I thought It will be a good idea to use it for a file managing part of my soft, but I am wasting a lot of my time to just find a way to do some few simple thinks.

    Best regards.
    DomZique.



  • I share your pain, me also spend a lot of times to figure out how to implement the filter for treemodel
    Filter of tableModel is easy and straight forward, but treemodel is like a black box for me,
    I study three books and document but none of them talk about it.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.