Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Proxy for the QFileSystemModel
Qt 6.11 is out! See what's new in the release blog

Proxy for the QFileSystemModel

Scheduled Pinned Locked Moved General and Desktop
9 Posts 3 Posters 6.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    stereomatching
    wrote on last edited by
    #1

    [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

    1 Reply Last reply
    0
    • S Offline
      S Offline
      stereomatching
      wrote on last edited by
      #2

      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

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on last edited by
        #3

        [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.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          stereomatching
          wrote on last edited by
          #4

          Thanks, setting an empty path also work for me.

          1 Reply Last reply
          0
          • D Offline
            D Offline
            domzique
            wrote on last edited by
            #5

            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

            1 Reply Last reply
            0
            • S Offline
              S Offline
              stereomatching
              wrote on last edited by
              #6

              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.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                stereomatching
                wrote on last edited by
                #7

                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.

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  domzique
                  wrote on last edited by
                  #8

                  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.

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    stereomatching
                    wrote on last edited by
                    #9

                    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.

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved