Bonjour,

Actuellement j'ai un QTreeView qui n'affiche que les icones des dossiers, et ce sont toujours les memes icones quelque soit l'Etat du noeud du QTreeView associe a ce dossier. Or je voudrais pouvoir afficher deux sortes d'icones différentes, une pour les noeud "expandés" du QTreeView et une autre pour les noeuds "collapses". J'ai donc créé une classe d'icon provider qui dérive de QFileIconProvider et j'ai réimplementé sa méthode icon(const QFileInfo &info) de sorte qu'elle renvoie soit une image de dossier ouvert, soit une image de dossier fermé en fonction de l'etat expended ou collapsed du noeud correspondant. Voici le code de mon icon provider :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
 
class MyIconProvider : public QFileIconProvider
{
private:
	QHash<QString, QString> fFileIcon;
 
public:
 
    void setIcon(QString path, QString iconPath)
	{
		fFileIcon.insert(path, iconPath);
	}
 
protected:
    virtual QIcon icon(const QFileInfo &info) const
	{		
		QHash<QString, QString>::const_iterator itFile = fFileIcon.find(info.path());
		if(itFile == fFileIcon.end())
		       return QIcon("folderClosed.png");
		return QIcon(fFileIcon.value(info.path()));
	}	
};


Et voici son utilisation :


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
class maClasse
{
private:
	MyFileIconProvider* fileIconProvider;
	QFileSystemModel* model;
 
public:
 
	void buildTreeView(QString rootPath)
	{
		fileIconProvider = new MyFileIconProvider;
 
		model = new QFileSystemModel(this);
		model->setFilter(QDir::Dirs|QDir::Drives|QDir::NoDotAndDotDot|QDir::AllDirs);
		model->setIconProvider(fileIconProvider);
 
		QTreeView* treeView = new QTreeView(this);
		treeView->setModel(model);
		treeView->setRootIndex(model->setRootPath(rootPath));
 
		connect(treeView, SIGNAL(expanded(const QModelIndex &)), this, SLOT(onTreeViewExpand(const QModelIndex &)) );
		connect(treeView, SIGNAL(collapsed(const QModelIndex &)), this, SLOT(onTreeViewCollapsed(const QModelIndex &)) );
	}
 
 
	void onTreeViewExpand(const QModelIndex& index)
	{
		QString path = model->filePath(index);
 
		// workaround que j'ai trouve sur le net pour forcer le refresh du treeView
		model->setRootPath("");
		fsModel->setRootPath(path);
 
		fileIconProvider->setIcon(path, "folderOpen.png");
	}
 
	void onTreeViewCollapsed(const QModelIndex& index)
	{
		QString path = model->filePath(index);
		model->setRootPath("");
		fsModel->setRootPath(path);
		fileIconProvider->setIcon(path, "folderClosed.png");
	}

A l'execution, le programme execute bien MyFileProvider::icon(), il renvoie bien la bonne image, mais premierement il ne m'affiche pas forcement l'icone qui a ete renvoyee par cette methode, en fait j'ai l'impression qu'il utilise la bonne image mais pour une raison mysterieuse il le fait pour les fils du noeud courant, et non pas le noeud lui meme, par exemple si j'ai l'arborescence suivante :

C:/folder1/d1
C:/folder1/d2
C:/folder1/d3
C:/folder1/d4

... un appel a MyFileProvider::icon("C:/folder1/") renverra bien "folderOpen.png", mais au final c'est toujours l'icone de depart, c'est a dire "folderClosed.png", qui sera utilise. D'ou mon sentiment qu'on ne peut definir l'icone a utiliser qu'une seule fois pour un neud donne et qu'a partir de la c'est toujours la meme qui sera utilisee pour ce noeud. J'ai regarde avec le debugger et effectivement, quand on collapse un noeud, la fonction qui appelle icon() verifie pour voir si le neud etait deja defini avant, et si c'est le cas elle ne le met pas a jour. J'aimerais donc savoir si il est possible de forcer le rafraichissement du QFileSystem. J'ai essaye de rajouter un workaround que j'ai trouve sur le net (model->setRootPath(""); fsModel->setRootPath(path) pour forcer la mise a jour du QFileSystem mais la seule difference que je constate c'est que MyIconProvider::icon() est appelee a chaque expand ou collapse, mais ca ne change rien au resultat, c'est toujours la premiere icone a avoir ete retournee par l'iconprovider qui est utilisee jusqu'a ce que je detruise mes objets.

Si vous voyez une solution, merci a vous !