Treemap - Visualiseur d'Espace Disque
Une application Windows en C++17 / Qt6 qui scanne un disque et affiche l'espace utilisé sous forme de treemap : chaque dossier et fichier est représenté par un rectangle dont l'aire est proportionnelle à sa taille, façon WinDirStat.

"Langage & Standard":
C++17
"Framework GUI":
Qt 6 (Widgets, QGraphicsView)
"Algorithme":
Squarified Treemap (Bruls, Huizing, van Wijk)
"Scan disque":
std::filesystem + QtConcurrent
Présentation du Projet
Le principe est simple : sélectionner un disque, lancer un scan en arrière-plan (l'interface ne freeze pas), puis explorer visuellement l'espace utilisé sous forme de rectangles colorés par type de fichier. Un panneau arborescence synchronisé permet de naviguer directement dans un dossier précis, sans avoir à zoomer niveau par niveau dans le treemap.
Treemap Coloré par Type
Chaque rectangle est coloré selon son type de fichier (exécutables, vidéos, images, code, archives...), pour repérer d'un coup d'œil ce qui occupe l'espace.
Arborescence Synchronisée
Panneau arborescence à gauche avec la taille de chaque dossier, synchronisé en temps réel avec le treemap affiché à droite.
Navigation par Clic
Zoom dans un dossier au clic, bouton Retour pour remonter, ou clic direct dans l'arborescence pour sauter à n'importe quel niveau.
Info-bulles & Explorateur
Survol pour afficher le chemin complet, la taille et le % du dossier parent ; clic droit pour afficher l'élément dans l'explorateur Windows.


Focus Algorithmique : Squarified Treemap
Le cœur du projet est une implémentation de l'algorithme squarified treemap (Bruls, Huizing, van Wijk) : à chaque niveau, les enfants sont regroupés en rangées de façon à garder des rectangles aussi proches du carré que possible, plutôt que des bandes fines illisibles. Taille minimum garantie pour qu'un petit fichier à côté d'un dossier énorme ne devienne jamais invisible.
Récursif vs itératif - le bug réel derrière le choix
Récursif - crash (rejeté)
Une frame par fichier traité. Sur un dossier à plusieurs centaines de milliers d'entrées, la pile déborde et le programme plante - sans message exploitable.
Itératif - stable (retenu)
Une boucle while sur une pile explicite : la mémoire utilisée reste plate, quel que soit le nombre de fichiers.
Architecture en Quatre Briques
Le projet est découpé en quatre briques indépendantes, chacune responsable d'une étape du pipeline scan → layout → affichage.
FileNode
La structure de données de base : un nœud représente un fichier ou un dossier. Le chemin complet n'est jamais stocké dans chaque nœud (seulement le nom) - pour un scan de plusieurs millions de fichiers, ça doublerait inutilement la mémoire utilisée. Il se reconstruit à la demande en remontant le pointeur parent.
Scanner
Parcourt le disque récursivement avec std::filesystem. Exclut les dossiers système inaccessibles ($Recycle.Bin, WinSxS...), détecte les jonctions/reparse points, et isole les erreurs par entrée pour ne jamais interrompre le reste du scan.
TreeMapLayout
Le cœur algorithmique : transforme l'arbre de FileNode en rectangles via l'algorithme squarified treemap, de façon itérative pour supporter les dossiers à plusieurs milliers d'enfants.
MainWindow
L'interface Qt Widgets : barre du haut (scan, retour, progression), QSplitter horizontal entre QTreeWidget et QGraphicsView/QGraphicsScene, profondeur de rendu limitée à 3 niveaux pour rester lisible.
Défis Techniques & Solutions
Stack Overflow sur les Gros Scans
Le scan complet du disque système (C:\, 648 Go) a débusqué un crash par stack overflow, résolu en passant à une boucle itérative.
Boucles Infinies sur les Jonctions
Détection via FILE_ATTRIBUTE_REPARSE_POINT, avec une limite de profondeur (256) en filet de sécurité.
Interface Réactive Pendant le Scan
Thread séparé via QtConcurrent::run, callback renvoyé via QMetaObject::invokeMethod.
Compilation & Limites
$ compilation (CMake + Qt6)
cmake -B build -S .
cmake --build buildTesté avec Qt 6.11.1 / MinGW 64-bit sur Windows.
- Windows uniquement pour l'instant (les détections de jonctions/reparse points utilisent l'API Win32).
- Pas d'annulation possible une fois un scan lancé.
Ce que j'ai appris
Algorithmique Itérative & Robustesse
Implémentation du squarified treemap sous forme de boucle while plutôt que récursive : un dossier peut contenir des milliers d'enfants, et une version récursive classique fait planter le programme par stack overflow sur ce genre de cas réel.
Concurrence avec Qt (QtConcurrent)
Exécution du scan disque dans un thread séparé via QtConcurrent::run pour ne jamais geler l'interface, avec un callback de progression renvoyé proprement sur le thread principal via QMetaObject::invokeMethod.
Système de Fichiers & API Win32
Parcours récursif avec std::filesystem, détection des jonctions et reparse points Windows pour éviter les boucles infinies, et isolation des erreurs par entrée pour qu'un seul fichier problématique n'interrompe jamais tout le scan.
Qt Widgets Avancé
Synchronisation bidirectionnelle entre un QTreeWidget et une QGraphicsScene, calcul du layout dans un repère logique fixe (1600×900) étiré via fitInView pour un rendu stable quel que soit le redimensionnement de la fenêtre.