Qt5 Tutorial ModelView with QTreeView and QDirModel - 2020
In this tutorial, we will learn about ModelView with QTreeView and QDirModel.
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.
We'll use Model-Based TreeView rather than simple Item-Based Tree Widget:
Since we finished layout, now is the time for coding.
Let's setup slots for the three buttons by "Go to slot..."->clicked().
void TreeViewDirModelDialog::on_pushButton_clicked() { // Make directory } void TreeViewDirModelDialog::on_pushButton_2_clicked() { // Delete directory }
Then, we need to make our QDirModel. Put the following line in the private section of treeviewdirmodeldialog.h:
QDirModel *model;
The QDirModel class provides a data model for the local filesystem.
The usage of QDirModel is not recommended anymore. The QFileSystemModel class is a more performant alternative.
This class provides access to the local filesystem, providing functions for renaming and removing files and directories, and for creating new directories. In the simplest case, it can be used with a suitable display widget as part of a browser or filer.
Now, let's do some implementation coding in treeviewdirmodeldialog.cpp:
#include "treeviewdirmodeldialog.h" #include "ui_treeviewdirmodeldialog.h" TreeViewDirModelDialog::TreeViewDirModelDialog(QWidget *parent) : QDialog(parent), ui(new Ui::TreeViewDirModelDialog) { ui->setupUi(this); // Create and populate our model model = new QDirModel(this); // Enable modifying file system model->setReadOnly(false); // Tie TreeView with DirModel // QTreeView::setModel(QAbstractItemModel * model) // Reimplemented from QAbstractItemView::setModel(). ui->treeView->setModel(model); } TreeViewDirModelDialog::~TreeViewDirModelDialog() { delete ui; } void TreeViewDirModelDialog::on_pushButton_clicked() { // Make directory } void TreeViewDirModelDialog::on_pushButton_2_clicked() { // Delete directory }
What we've done:
- Created model.
- Populated our model.
- Enable modifying file system.
- Tied TreeView with DirModel.
At this point, we have already included headers in modelviewdialog.h:
#include <QDirModel> #include <QTreeView> #include <QInputDialog>
To check we're on track, let's run the code:
Yes, it seems OK!
Because the list in the current directory TreeView is not sorted, we need to setup sort criteria:
// Setup sort criteria // directory first, ignore case, // and sort by name model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name);
A little bit more work needed for the initial status of the TreeView:
// Set initial selection QModelIndex index = model->index("C:/"); // Set initial view of directory // for the selected drive as expanded ui->treeView->expand(index); // Make it scroll to the selected ui->treeView->scrollTo(index); // Highlight the selected ui->treeView->setCurrentIndex(index); // Resizing the column - first column ui->treeView->resizeColumnToContents(0);
Again, let's run the code:
Yes, it's sorted, selected, expanded, etc.
Then, as a next step, let's work on the "Make dir" slot:
void TreeViewDirModelDialog::on_pushButton_clicked() { // Make directory QModelIndex index = ui->treeView->currentIndex(); if(!index.isValid()) return; QString name = QInputDialog::getText(this, "Name", "Enter a name"); if(name.isEmpty()) return; model->mkdir(index, name); }
Run the code if we can make a new directory:
Let's see if the directory "000" has been made:
Great!
Now, we're able to make a new directory. So, move on to the next slot which is "delete" slot:
void TreeViewDirModelDialog::on_pushButton_2_clicked() { // Delete directory // Get the current selection QModelIndex index = ui->treeView->currentIndex(); if(!index.isValid()) return; if(model->fileInfo(index).isDir()) { // directory model->rmdir(index); } else { // file model->remove(index); } }
Run the code again.
Note that we were able to delete the previously created "000" directory!
Here are the final codes:
treeviewdirmodeldialog.h:
#ifndef TREEVIEWDIRMODELDIALOG_H #define TREEVIEWDIRMODELDIALOG_H #include <QDialog> #include <QDirModel> #include <QTreeView> #include <QInputDialog> namespace Ui { class TreeViewDirModelDialog; } class TreeViewDirModelDialog : public QDialog { Q_OBJECT public: explicit TreeViewDirModelDialog(QWidget *parent = 0); ~TreeViewDirModelDialog(); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); private: Ui::TreeViewDirModelDialog *ui; // Create a new QDirModel QDirModel *model; }; #endif // TREEVIEWDIRMODELDIALOG_H
treeviewdirmodeldialog.cpp:
#include "treeviewdirmodeldialog.h" #include "ui_treeviewdirmodeldialog.h" TreeViewDirModelDialog::TreeViewDirModelDialog(QWidget *parent) : QDialog(parent), ui(new Ui::TreeViewDirModelDialog) { ui->setupUi(this); // Create and populate our model model = new QDirModel(this); // Enable modifying file system model->setReadOnly(false); // Setup sort criteria // directory first, ignore case, // and sort by name model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name); // QTreeView::setModel(QAbstractItemModel * model) // Reimplemented from QAbstractItemView::setModel(). ui->treeView->setModel(model); // Set initial selection QModelIndex index = model->index("C:/"); // Set initial view of directory // for the selected drive as expanded ui->treeView->expand(index); // Make it scroll to the selected ui->treeView->scrollTo(index); // Highlight the selected ui->treeView->setCurrentIndex(index); // Resizing the column - first column ui->treeView->resizeColumnToContents(0); } TreeViewDirModelDialog::~TreeViewDirModelDialog() { delete ui; } void TreeViewDirModelDialog::on_pushButton_clicked() { // Make directory QModelIndex index = ui->treeView->currentIndex(); if(!index.isValid()) return; QString name = QInputDialog::getText(this, "Name", "Enter a name"); if(name.isEmpty()) return; model->mkdir(index, name); } void TreeViewDirModelDialog::on_pushButton_2_clicked() { // Delete directory // Get the current selection QModelIndex index = ui->treeView->currentIndex(); if(!index.isValid()) return; if(model->fileInfo(index).isDir()) { // directory model->rmdir(index); } else { // file model->remove(index); } }
NOTE: Qt 5 document:
The usage of QDirModel is not recommended anymore. The QFileSystemModel class is a more performant alternative.
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