Qt5 Tutorial ModelView with QTreeView and QFileSystemModel - 2020
In this tutorial, we will learn about ModelView with QTreeView and QFileSystemModel.
QFileSystemModel will not fetch any files or directories until setRootPath() is called. This will prevent any unnecessary querying on the file system until that point such as listing the drives on Windows.
Unlike QDirModel(obsolete) which we discussed in Qt 5 Tutorial, ModelView with QTreeView and QDirModel,
QFileSystemModel uses a separate thread to populate itself so it will not cause the main thread to hang as the file system is being queried.
Calls to rowCount() will return 0 until the model populates a directory. QFileSystemModel keeps a cache with file information. The cache is automatically kept up to date using the QFileSystemWatcher.
In this example, we'll use Qt Gui application with QDialog:
As we discussed in other ModelView tutorials, Qt's MVC may not be the same as the conventional MVC.
If the view and the controller objects are combined, the result is the model/view architecture. This still separates the way that data is stored from the way that it is presented to the user, but provides a simpler framework based on the same principles. This separation makes it possible to display the same data in several different views, and to implement new types of views, without changing the underlying data structures. To allow flexible handling of user input, we introduce the concept of the delegate. The advantage of having a delegate in this framework is that it allows the way items of data are rendered and edited to be customized.However, it's worth investigating their approach of using "delegate" with their Model/View pattern.
In this tutorial, we'll use Model-Based TreeView for folders on the left side and ListView for files on the right side:
Since we finished layout, now is the time for coding.
Let's make two models in qfilesystemmodeldialog.h: one for files and the other for directories. We make two models because we need to filter them separately.
#ifndef QFILESYSTEMMODELDIALOG_H #define QFILESYSTEMMODELDIALOG_H #include <QDialog> #include <QFileSystemModel> namespace Ui { class QFileSystemModelDialog; } class QFileSystemModelDialog : public QDialog { Q_OBJECT public: explicit QFileSystemModelDialog(QWidget *parent = 0); ~QFileSystemModelDialog(); private: Ui::QFileSystemModelDialog *ui; // Make two models instead of one // to filter them separately QFileSystemModel *dirModel; QFileSystemModel *fileModel; }; #endif // QFILESYSTEMMODELDIALOG_H
Move on to the implementation file, qfilesystemmodeldialog.cpp:
#include "qfilesystemmodeldialog.h" #include "ui_qfilesystemmodeldialog.h" QFileSystemModelDialog::QFileSystemModelDialog(QWidget *parent) : QDialog(parent), ui(new Ui::QFileSystemModelDialog) { ui->setupUi(this); // Creates our new model and populate QString mPath = "C:/"; dirModel = new QFileSystemModel(this); // Set filter dirModel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs); // QFileSystemModel requires root path dirModel->setRootPath(mPath); // Attach the model to the view ui->treeView->setModel(dirModel); } QFileSystemModelDialog::~QFileSystemModelDialog() { delete ui; }
Let's run the code to see what we've done.
It shows the TreeView for directories successfully, and it looks like we're on track!
How about files?
We add similar line of code for files in the implementation file, qfilesystemmodeldialog.cpp:
// FILES fileModel = new QFileSystemModel(this); // Set filter fileModel->setFilter(QDir::NoDotAndDotDot | QDir::Files); // QFileSystemModel requires root path fileModel->setRootPath(mPath); // Attach the model to the view ui->listView->setModel(fileModel);
Let's setup a slot for the TreeView by "Go to slot..."->clicked(ModelIndex).
void QFileSystemModelDialog::on_treeView_clicked(const QModelIndex &index;) { // TreeView clicked // 1. We need to extract path // 2. Set that path into our ListView // Get the full path of the item that's user clicked on QString mPath = dirModel->fileInfo(index).absoluteFilePath(); ui->listView->setRootIndex(fileModel->setRootPath(mPath)); }
Again, let's run the code:
Great!
Here are the final codes:
qfilesystemmodeldialog.h:
#ifndef QFILESYSTEMMODELDIALOG_H #define QFILESYSTEMMODELDIALOG_H #include <QDialog> #include <QFileSystemModel> namespace Ui { class QFileSystemModelDialog; } class QFileSystemModelDialog : public QDialog { Q_OBJECT public: explicit QFileSystemModelDialog(QWidget *parent = 0); ~QFileSystemModelDialog(); private slots: void on_treeView_clicked(const QModelIndex &index;); private: Ui::QFileSystemModelDialog *ui; // Make two models instead of one // to filter them separately QFileSystemModel *dirModel; QFileSystemModel *fileModel; }; #endif // QFILESYSTEMMODELDIALOG_H
The implementation file, qfilesystemmodeldialog.cpp:
#include "qfilesystemmodeldialog.h" #include "ui_qfilesystemmodeldialog.h" QFileSystemModelDialog::QFileSystemModelDialog(QWidget *parent) : QDialog(parent), ui(new Ui::QFileSystemModelDialog) { ui->setupUi(this); // Creates our new model and populate QString mPath = "C:/"; // DIRECTORIES dirModel = new QFileSystemModel(this); // Set filter dirModel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs); // QFileSystemModel requires root path dirModel->setRootPath(mPath); // Attach the dir model to the view ui->treeView->setModel(dirModel); // FILES fileModel = new QFileSystemModel(this); // Set filter fileModel->setFilter(QDir::NoDotAndDotDot | QDir::Files); // QFileSystemModel requires root path fileModel->setRootPath(mPath); // Attach the file model to the view ui->listView->setModel(fileModel); } QFileSystemModelDialog::~QFileSystemModelDialog() { delete ui; } void QFileSystemModelDialog::on_treeView_clicked(const QModelIndex &index;) { // TreeView clicked // 1. We need to extract path // 2. Set that path into our ListView // Get the full path of the item that's user clicked on QString mPath = dirModel->fileInfo(index).absoluteFilePath(); ui->listView->setRootIndex(fileModel->setRootPath(mPath)); }
Qt 5 Tutorial
- Hello World
- Signals and Slots
- Q_OBJECT Macro
- MainWindow and Action
- MainWindow and ImageViewer using Designer A
- MainWindow and ImageViewer using Designer B
- Layouts
- Layouts without Designer
- Grid Layouts
- Splitter
- QDir
- QFile (Basic)
- Resource Files (.qrc)
- QComboBox
- QListWidget
- QTreeWidget
- QAction and Icon Resources
- QStatusBar
- QMessageBox
- QTimer
- QList
- QListIterator
- QMutableListIterator
- QLinkedList
- QMap
- QHash
- QStringList
- QTextStream
- QMimeType and QMimeDatabase
- QFile (Serialization I)
- QFile (Serialization II - Class)
- Tool Tips in HTML Style and with Resource Images
- QPainter
- QBrush and QRect
- QPainterPath and QPolygon
- QPen and Cap Style
- QBrush and QGradient
- QPainter and Transformations
- QGraphicsView and QGraphicsScene
- Customizing Items by inheriting QGraphicsItem
- QGraphicsView Animation
- FFmpeg Converter using QProcess
- QProgress Dialog - Modal and Modeless
- QVariant and QMetaType
- QtXML - Writing to a file
- QtXML - QtXML DOM Reading
- QThreads - Introduction
- QThreads - Creating Threads
- Creating QThreads using QtConcurrent
- QThreads - Priority
- QThreads - QMutex
- QThreads - GuiThread
- QtConcurrent QProgressDialog with QFutureWatcher
- QSemaphores - Producer and Consumer
- QThreads - wait()
- MVC - ModelView with QListView and QStringListModel
- MVC - ModelView with QTreeView and QDirModel
- MVC - ModelView with QTreeView and QFileSystemModel
- MVC - ModelView with QTableView and QItemDelegate
- QHttp - Downloading Files
- QNetworkAccessManager and QNetworkRequest - Downloading Files
- Qt's Network Download Example - Reconstructed
- QNetworkAccessManager - Downloading Files with UI and QProgressDialog
- QUdpSocket
- QTcpSocket
- QTcpSocket with Signals and Slots
- QTcpServer - Client and Server
- QTcpServer - Loopback Dialog
- QTcpServer - Client and Server using MultiThreading
- QTcpServer - Client and Server using QThreadPool
- Asynchronous QTcpServer - Client and Server using QThreadPool
- Qt Quick2 QML Animation - A
- Qt Quick2 QML Animation - B
- Short note on Ubuntu Install
- OpenGL with QT5
- Qt5 Webkit : Web Browser with QtCreator using QWebView Part A
- Qt5 Webkit : Web Browser with QtCreator using QWebView Part B
- Video Player with HTML5 QWebView and FFmpeg Converter
- Qt5 Add-in and Visual Studio 2012
- Qt5.3 Installation on Ubuntu 14.04
- Qt5.5 Installation on Ubuntu 14.04
- Short note on deploying to Windows
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization