FAQ Qt
FAQ QtConsultez toutes les FAQ
Nombre d'auteurs : 26, nombre de questions : 298, dernière mise à jour : 15 juin 2021
- Comment effacer un fichier ?
- Comment vérifier si un fichier existe ?
- Comment copier un fichier ?
- Comment récupérer le chemin des répertoires spéciaux ?
- Comment sélectionner un nom de fichier ou répertoire à partir d'une boîte de dialogue ?
- Comment lister les fichiers d'un répertoire et de ses sous-répertoires ?
- Comment connaître le chemin du répertoire courant ?
- Comment récupérer le chemin du répertoire de l'exécutable ?
- Comment récupérer le contenu d'un QIODevice dans un QString ?
- Comment lister tous les lecteurs disponibles sous Windows ?
- Comment supprimer un répertoire et son contenu ?
Pour cela il faut utiliser les méthodes suivantes de QFile :
- boolQFile::remove() : permet d'effacer le fichier référencé par l'objet QFile ;
- static boolQFile::remove(constQString& fileName) : permet d'effacer le fichier fileName.
// On référence l'objet file au fichier
QFile
file("C:/existe.txt"
);
// Efface le fichier "existe.txt" et renvoie true ou false si l'opération a bien réussi
bool
valid =
file.remove();
// Efface le fichier "existe.txt" et renvoie true ou false si l'opération a bien réussi
bool
valid =
QFile
::
remove("C:/existe.txt"
);
Pour cela il faut utiliser les méthodes suivantes de QFile :
- boolQFile::exists()const : permet de vérifier si le fichier pointé par l'objet QFile existe ;
- static boolQFile::exists(constQString& fileName) : permet de vérifier si le fichier "fileName" existe.
// On référence l'objet file au fichier
QFile
file("C:/existe.txt"
);
// Si valid == true, le fichier existe
bool
valid =
file.exists();
//Si valid == true, le fichier existe
bool
valid =
QFile
::
exists("C:/existe.txt"
);
Pour cela QFile met à notre disposition les méthodes suivantes :
- boolQFile::copy(constQString& newName) : permet la copie du fichier contenu dans l'objet QFile ;
- static boolQFile::copy(constQString& fileName,constQString& newName) : permet la copie du fichier "fileName" en "newName".
Remarque : ces deux méthodes renvoient true si la copie s'est bien passée et false dans le cas contraire. Si le fichier spécifié newName existe déjà, la copie sera annulée et la méthode renverra false.
// On référence l'objet file au fichier
QFile
file("C:/copie.txt"
);
// On copie le fichier copie.txt vers copieNext.txt
bool
valid =
file.copy("C:/copieNext.txt"
);
// On copie le fichier copie.txt vers copieNext.txt
bool
valid =
QFile
::
copy ("C:/copie.txt"
, "C:/copieNext.txt"
);
Qt, à partir de sa version 4.4, permet, avec la classe
QDesktopServices,
de récupérer les différents chemins des répertoires spéciaux tels que Movies, Pictures, Temp, etc.
C'est la méthode statique storageLocation(),
qui prend en argument une énumération de type
StandardLocation,
qui permet d'effectuer cela.
Exemple : on souhaite récupérer le répertoire Pictures de l'utilisateur.
QString
PicturesPath =
QDesktopServices
::
storageLocation(QDesktopServices
::
PicturesLocation);
La liste de tous les répertoires pouvant être récupérés correspond à l'énumération StandardLocation.
Remarque : si vous utilisez l'option QDesktopServices::DataLocation, il est impératif que vous ayez défini préalablement le nom de l'application et le nom de l'organisation à l'aide des méthodes setApplicationName() et setOrganizationDomain() de la classe QCoreApplication.
Qt permet à l'aide de la classe QFileDialog une utilisation très simple de ces différentes boîtes de dialogue à l'aide de méthodes statiques :
- QString getOpenFileName() : permet la récupération du chemin d'un fichier existant sélectionné par l'utilisateur ;
- QStringList getOpenFileNames() : permet la récupération du chemin de plusieurs fichiers existants sélectionnés par l'utilisateur ;
- QString getSaveFileName () : permet la récupération du chemin d'un fichier non existant dans le but d'être sauvegardé ;
- QString getExistingDirectory() : permet la récupération d'un répertoire sélectionné par l'utilisateur.
Remarque : toutes ces méthodes fonctionnent sur le même principe.
Qt fournit, depuis sa version 4.3, la classe QDirIterator, qui permet la navigation entre répertoires. Cette classe possède plusieurs surcharges du constructeur permettant de préciser le type de navigation que l'on souhaite entre les répertoires. La navigation dans les répertoires se fait surtout à l'aide de deux méthodes :
- boolQDirIterator::hasNext() : retourne true tant qu'on n'est pas à la fin de l'arborescence ;
- QStringQDirIterator::next() : fait avancer l'itérateur à la prochaine entrée et renvoie le chemin absolu de celle-ci.
Note 1 : Si on préfère récupérer une liste de type QFileInfoList au lieu d'une QStringList, il suffit d'utiliser la méthode QDirIterator::fileInfo().
Note 2 : Si on souhaite lister uniquement les fichiers d'un répertoire et non ceux de ses sous-répertoires, il est préférable d'utiliser la méthode entryInfoList() de la classe QDir.
Qt fournit la classe QDir pour manipuler les répertoires. Cette classe permet, entre autres, de récupérer le chemin du répertoire courant de l'exécution et de le modifier :
- QStringQDir::currentPath() : chemin complet du répertoire ;
- QDirQDir::current() : QDir renvoie un objet de type QDir pointant sur le répertoire courant ;
- bool QDir::setCurrent ( const QString & path ) : modifie le répertoire courant. Retourne true si la modification a réussi.
QString
CurrentDir =
QDir
::
currentPath();
QString
CurrentDir =
"C:/Users/Developpez/Downloads"
;
QDir
::
setCurrent(CurrentDir);
Remarque : Il est intéressant de préciser que le répertoire courant n'est pas forcement le même que le répertoire où se trouve l'exécutable.
Qt fournit, avec la classe QCoreApplication, des méthodes statiques permettant de récupérer facilement des informations comme le chemin du répertoire de l'exécutable.
On exécute une application depuis C:\Users\developpez\Documents\test.exe.
// Contient le chemin complet du répertoire de l'exécutable (C:\Users\developpez\Documents)
QString
MyAppDirPath =
QCoreApplication
::
applicationDirPath();
//Contient le chemin complet de l'exécutable (C:\Users\developpez\Documents\test.exe)
QString
MyAppPath =
QCoreApplication
::
applicationFilePath ();
QIODevice est une couche d'abstraction pour tous les périphériques, pour faire simple : cela permet que tous aient au moins des fonctionnalités minimales, des fonctions aux noms identiques...
Diverses classes héritent de QIODevice : la plus connue, QFile, mais aussi QProcess, QAbstractSocket (et donc, QTcpSocket et QUdpSocket), QBuffer...
QIODevice fournit la méthode readAll() pour récupérer le contenu dans un QByteArray.
QByteArray
QIODevice
::
readAll();
Depuis le QByteArray, il est possible d'obtenir une QString, grâce aux constructeurs fournis. Vous pouvez aussi passer par la méthode data() de QByteArray, qui vous permet de récupérer un char *.
Cependant, le résultat d'une telle opération peut être assez aléatoire : en effet, un QByteArray peut contenir du texte avec n'importe quel encodage. Pour cela, il vaut mieux passer par un QTextStream, qui permet de gérer l'encodage.
On ne peut jamais être sûr de la provenance d'un QByteArray, ni, donc, de la signification des caractères qu'il comporte. Par exemple, un \0 revêt une signification particulière pour QString : aux yeux de QByteArray, il s'agit d'un caractère comme les autres.
QString
::
QString
( QByteArray
);
QTextStream
::
QTextStream
(QByteArray
);
QTextStream
::
setCodec ( QTextCodec
);
Qt fournit la méthode statique QFileInfoList QDir::drives() qui permet de lister tous les lecteurs (C:\, D:\…) disponibles sur une machine Windows.
//On récupère tous les lecteurs disponibles dans une liste de type QFileInfoList
QFileInfoList
ListDrives =
QDir
::
drives();
foreach
(const
QFileInfo
&
FileInfo,ListDrives)
{
//Affichage de tous les lecteurs trouvés sur la machine
qDebug
() <<
FileInfo. filePath();
}
Cette méthode est aussi disponible sous macOS et Linux. Cependant, elle retournera uniquement la racine du système, c'est-à-dire /.
Pour supprimer un répertoire, il existe la méthode QDir::rmdir(). Seulement, celle-ci ne fonctionne que si le répertoire est vide. Pour supprimer un répertoire et son contenu (pouvant comprendre différents niveaux de sous-dossiers), on peut utiliser une méthode récursive :
bool
removeDir(const
QString
&
dirPath) //dirPath = le chemin du répertoire à supprimer, ex : "/home/user/monRepertoire")
{
QDir
folder(dirPath);
//On va lister dans ce répertoire tous les éléments différents de "." et ".."
//(désignant respectivement le répertoire en cours et le répertoire parent)
folder.setFilter(QDir
::
NoDotAndDotDot |
QDir
::
AllEntries);
foreach
(QFileInfo
fileInfo, folder.entryInfoList())
{
//Si l'élément est un répertoire, on applique la méthode courante à ce répertoire, c'est un appel récursif
if
(fileInfo.isDir())
{
if
(!
removeDir(fileInfo.filePath())) //Si une erreur survient, on retourne false
return
false
;
}
//Si l'élément est un fichier, on le supprime
else
if
(fileInfo.isFile())
{
if
(!
QFile
::
remove(fileInfo.filePath()))
{
//Si une erreur survient, on retourne false
return
false
;
}
}
}
//Le dossier est maintenant vide, on le supprime
if
(!
folder.rmdir(dirPath))
{
//Si une erreur survient, on retourne false
return
false
;
}
//Sinon, on retourne true
return
true
;
}
Il est à noter que les méthodes de suppressions de fichiers et de dossiers peuvent échouer. Les raisons sont principalement liées aux droits d'écriture ou à des fichiers ouverts dans d'autres programmes.
Voici une autre solution moyennant QDirIterator. Cet itérateur permet de lister tous les sous-dossiers d'un dossier donné. De ce fait, cette méthode ne nécessite pas d'appel récursif.
void
DeleteDir(const
QString
&
PathDir)
{
//Création de l'itérateur, on précise qu'on veut tous les sous-dossiers
QDirIterator
dirIterator(PathDir, QDirIterator
::
Subdirectories);
//On récupère les fichiers et dossiers grâce à l'itérateur
QFileInfoList
fileList;
while
(dirIterator.hasNext())
{
dirIterator.next();
fileList <<
dirIterator.fileInfo();
}
//On parcourt les éléments
QStringList
directories;
for
(int
i =
fileList.count() -
1
; i >
0
; i--
)
{
//Si l'élément est un fichier, on le supprime
if
(fileList.at(i).isFile())
QFile
::
remove(fileList.at(i).absoluteFilePath());
//On stocke le dossier contenant cet élément dans une liste (si ce n'est pas déjà fait)
if
(!
directories.contains(fileList.at(i).absolutePath()))
directories <<
fileList.at(i).absolutePath();
}
QDir
dir =
QDir
::
root();
//Finalement, on supprime tous les dossiers
foreach
( const
QString
StrDir, directories)
{
dir.rmdir(StrDir);
}
}