The QDir class can be used to retrieve information about a given path, delete or rename a file, query if a given path exists, and more. This example will explain the difference between a QDir absolute path and a canonical path.
#include <QtCore>
#include <QtGui>
class MainWindow : public QWidget
{
public:
MainWindow();
private:
void updateDirValues();
QLineEdit *text_1;
QLineEdit *text_2;
QLineEdit *text_3;
QLineEdit *text_4;
QLineEdit *text_5;
QLineEdit *text_6;
};
Our declaration for MainWindow includes the constructor, a private method which is a slot, and several declarations for QLineEdit fields which will be updated when the slot method is invoked.
MainWindow::MainWindow()
{
setMinimumSize(600, 350);
QLabel *label_1 = new QLabel("Enter a Path: ");
text_1 = new QLineEdit(".");
QLabel *label_2 = new QLabel("Absolute Path:");
text_2 = new QLineEdit();
text_2->setReadOnly(true);
QLabel *label_3 = new QLabel("Canonical Path: ");;
text_3 = new QLineEdit();
text_3->setReadOnly(true);
QLabel *label_4 = new QLabel("Path Exists:");
text_4 = new QLineEdit();
text_4->setReadOnly(true);
QLabel *label_5 = new QLabel("Path for home path: ");
text_5 = new QLineEdit();
text_5->setText(QDir::homePath());
text_5->setReadOnly(true);
QLabel *label_6 = new QLabel("Path for temporary files: ");
text_6 = new QLineEdit();
text_6->setText(QDir::tempPath());
text_6->setReadOnly(true);
QPushButton *pb_close = new QPushButton();
pb_close->setText("Close");
QGridLayout *grid = new QGridLayout();
grid->setHorizontalSpacing(20);
grid->setVerticalSpacing(15);
grid->addWidget(label_1, 3, 1);
grid->addWidget(text_1, 3, 2);
grid->addWidget(label_2, 4, 1);
grid->addWidget(text_2, 4, 2);
grid->addWidget(label_3, 5, 1);
grid->addWidget(text_3, 5, 2);
grid->addWidget(label_4, 6, 1);
grid->addWidget(text_4, 6, 2);
grid->addItem(new QSpacerItem(0, 20,
QSizePolicy::Fixed, QSizePolicy::Fixed), 7, 1);
grid->addWidget(label_5, 8, 1);
grid->addWidget(text_5, 8, 2);
grid->addWidget(label_6, 9, 1);
grid->addWidget(text_6, 9, 2);
grid->addItem(new QSpacerItem(0, 0,
QSizePolicy::Fixed, QSizePolicy::Expanding), 10, 1);
QHBoxLayout *layoutPB = new QHBoxLayout();
layoutPB->addStretch();
layoutPB->addWidget(pb_close);
layoutPB->addStretch();
QVBoxLayout *layoutMain = new QVBoxLayout(this);
layoutMain->setContentsMargins(30, 40, 30, 15);
layoutMain->addLayout(grid);
layoutMain->addLayout(layoutPB);
connect(text_1, &QLineEdit::textChanged,
this, &MainWindow::updateDirValues);
connect(close_pb, &QPushButton::clicked,
this, &QWidget::close);
updateDirValues();
}
The user interface setup creates six QLineEdit widgets. Users can change the text in the first widget to enter any path. The initial path is set to the current directory as indicated by the “.” value shown on line 6. As this path is modified the other read only widgets will be updated.
The values for widgets 5 and 6 will not change since these are defined values set by the operating system. The value for homePath() is the user’s home directory. On Windows this directory is the user’s profile. On Linux and Mac OS X the HOME environment variable is used if it exists, otherwise the returned value is the root path.
The value for tempPath() is the location where temporary files should be stored. The actual path depends on the given operating system.
Lines 33 to 69 define the grid layout for our user interface. The last line is a direct call to the updateDirValues() slot which is responsible for populating values which will change based on the given path for text_1.
Signal / Slot Connection
Line 71 in the prior block calls connect() which sets up a signal / slot connection. When the user modifies the data in the first QLineEdit widget, the updateDirValues() method will be invoked.
void MainWindow::updateDirValues()
{
QDir userDirPath;
userDirPath = QDir(text_1->text());
QString absolutePath = userDirPath.absolutePath();
QString canonicalPath = userDirPath.canonicalPath();
text_2->setText(absolutePath);
text_3->setText(canonicalPath);
if (userDirPath.exists()) {
text_4->setText("Path exists");
} else {
text_4->setText("Path does not exist");
}
}
On line 4 of our slot method the text entered by the user in the text_1 widget is retrieved and saved to a local variable. This data is then passed to a constructor for a new QDir and the result is assigned to the variable userDirPath.
On lines 6 and 7 the methods absolutePath() and canonicalPath() are called and the values for the text_2 and text_3 widgets are updated. These widgets were set to read only on lines 10 and 14 when the user interface was created in the prior block of code.
So what is the difference between an absolute path and a canonical path? An absolute path describes a path location in comparison to the root directory. This path must begin with a directory separator. On Windows this can be preceded by a drive letter.
A canonical path is an absolute path where any redundant “.” or “..” symbols are resolved. After this resolution, if the canonical path refers to an invalid folder or directory which does not exist, the value for the canonical path will be empty.
(1) For this example, change the path for text_1 from the current directory to the root folder or just a drive letter if you are using Windows, observe the new values.
(2) Then enter a path which you know is invalid. The absolute path will be displayed however the canonical path will be empty.
Main Function
Since the source code for main() has not changed there is no need to show it again. Refer to example 3 or download the full source for this example.
Running the Example
To build and run this example use the same CMake build file and commands as we showed for the first example. The only suggested modification is on line 2 of the CMakeLists.txt file, change “example_1” to “example_47”.