IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

PyQt4 et les QStandardItemModel


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Inscrit en
    Août 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 5
    Par défaut PyQt4 et les QStandardItemModel
    Bonjour à tous,

    Je viens vers vous car j'ai une question qui reste sans réponse.
    Tout d'abord je vous situe le contexte:

    Je programme un petit soft pour apprendre à "maîtriser" le python (j'utilise actuellement la version 2.7) et le superbe module PyQt4.

    Maintenant que le contexte est situé, voici mon problème:

    Mon interface graphique est constituée d'une main frame dans laquelle se trouve un Qwidget, lui même contenant d'autres widgets.
    Celui qui me pose problème est le QTreeView, pour gèrer l'affichage de mon arbre j'utilise le QStandartItemModel. Jusque là tout fonctionne comme je le souhaite!
    Mais je me suis mis en tête de pouvoir sauvegarde l'ensemble des labels, options désirées par l'utilisateur (moi) et le QStandardModel dans un fichier cfg! Pour faire cela, j'utilise la fonction Pickle.
    Chacune des variables est enregistrée dans un dictionnaire.

    Parfait les variables sont enregistrées, les labels aussi mais alors le QStandardItemModel est vide comme une coquille lui..voici ce que me donne le le fichier de config sur la partie concernant le modèle:


    Alors j'avais remarqué que l'on ne pouvait pas faire
    toto = QStandardItemModel()
    dupont = QStandardItemModel()

    toto = dupont

    Mais qu'il fallait insérer élément par élément le contenu du modèle vers un autre: alors c'est ce que j'ai fait, j'ai testé en faisant toto.clear() et puis MaFonctionCopie(toto, dupont). Mais ca ne fonctionne pas…

    J'ai essayé de sauvegarde le modèle seul… mis ca ne change rien! Maintenant je n'ai plus d'idées…J'ai regardé les exemples avec PyQt4.. Dans itemview.. Alors eux ils le font à partir d'un QRessource on dirait, mais n'ayant pas compris plus que ca l'exemple je préfère m'arrêter d'en parler

    Si l'un d'entre vous à une solution à me proposer, je suis preneur..

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut, poste nous un bout de code significatif, que l'on puisse comprendre ce que tu cherche à obtenir.

    Moi, j'ai un peu de mal, qu'y-a-t-il dans ton treeView ? l'arborescence de ton pc ?

  3. #3
    Futur Membre du Club
    Inscrit en
    Août 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 5
    Par défaut
    salut VinsS,
    je n'ai pas le code sous la main sur ce pc, je le posterai au plus tôt si jamais mes explications ne sont pas suffisantes:

    en faite je cherche à faire une liste des fichiers que je veux: je souhaite faire une sorte de petit IDE pour mes projets.
    il s'agit d'un arbre dans lequel j'affiche des .c et leur .h en fonctions de leur dépendance. Pas de soucis pour les faire afficher. J'inclus les éléments soit à la main soit de manière automatique.
    Ensuite je voulais pouvoir sauvegarder les options de configurations ainsi que l'arbre pour afficher là où j'en étais.
    Je sauvegarde les variables, les labels sans soucis! Mais la fonction cPickle ne permet pas de stocker des QStandardItemModel..

    Donc on m'a conseillé de le faire à la main..
    à la main j'arrive à sauvegarder le QStandardItemModel dans un autre modèle, sauvegarder les éléments de l'arbre dans deux dictionnaires: un pour les .c et un . les .h
    Chaque dictionnaire liste en faite les dépendances: exemple =>
    • dic["main.c"] = ['timer.h', 'interruptions.h']
    • dic["timer.c"] = ['timer.h', 'variables.h']
    • dic2['timer.h'] = ['interruptions.h', 'temps.h']


    c'est un exemple totalement inventé mais je pense que l'on comprend mieux.
    Je peux stocker ces dictionnaires à l'aide de la fonction cPickle dans un fichier: "config.tree' (encore une fois un exemple)
    et ensuite je les récupère.. j'ai encore quelques soucis car ma fonction qui est censé tout remettre sous forme d'arbre déconne au bout de deux dépendances.. (je fais des fonctions récursives de partout, c'est la mode dans mon code en ce moment).

    Est-ce plus compréhensible cette fois?

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Ptiloic Voir le message
    salut VinsS,
    je n'ai pas le code sous la main sur ce pc, je le posterai au plus tôt si jamais mes explications ne sont pas suffisantes:

    en faite je cherche à faire une liste des fichiers que je veux: je souhaite faire une sorte de petit IDE pour mes projets.
    il s'agit d'un arbre dans lequel j'affiche des .c et leur .h en fonctions de leur dépendance. Pas de soucis pour les faire afficher. J'inclus les éléments soit à la main soit de manière automatique.
    Ensuite je voulais pouvoir sauvegarder les options de configurations ainsi que l'arbre pour afficher là où j'en étais.
    Je sauvegarde les variables, les labels sans soucis! Mais la fonction cPickle ne permet pas de stocker des QStandardItemModel..

    Donc on m'a conseillé de le faire à la main..
    à la main j'arrive à sauvegarder le QStandardItemModel dans un autre modèle, sauvegarder les éléments de l'arbre dans deux dictionnaires: un pour les .c et un . les .h
    Chaque dictionnaire liste en faite les dépendances: exemple =>
    • dic["main.c"] = ['timer.h', 'interruptions.h']
    • dic["timer.c"] = ['timer.h', 'variables.h']
    • dic2['timer.h'] = ['interruptions.h', 'temps.h']


    c'est un exemple totalement inventé mais je pense que l'on comprend mieux.
    Je peux stocker ces dictionnaires à l'aide de la fonction cPickle dans un fichier: "config.tree' (encore une fois un exemple)
    et ensuite je les récupère.. j'ai encore quelques soucis car ma fonction qui est censé tout remettre sous forme d'arbre déconne au bout de deux dépendances.. (je fais des fonctions récursives de partout, c'est la mode dans mon code en ce moment).

    Est-ce plus compréhensible cette fois?
    Beaucoup plus compréhensible.

    Le problème, c'est que chacun à sa façon de programmer propre. Par exemple, si moi je devais faire ça, je mettrais
    - dans un module "modèle" tous les outils permettant de sauvegarder/restaurer les dépendances sur disque
    - dans un module "vue" ce qui permet d'afficher l'arbre (le QTreeWidget)
    - dans un module "contrôleur" l'arbre de mes dépendances à ma sauce (un peu comme tes dict)
    Si je dois sauvegarder l'arbre, je ne sauvegarde que mes dict. Des fonctions de bases permettront de stocker/charger ces dict sur disque. D'autres fonctions X ou Y auront pour charge d'afficher mes dict (sur un QTreeWidget éventuellement ou alors sur autre chose). L'avantage c'est que ce genre de programmation est hyper flexible
    1) si je veux, je rajoute une entrée clavier et l'intègre dans mes dict. Il sera affiché ensuite comme les autres par la fonction qui convertit les dict en QTreeWidget
    2) si je veux, je remplace la sauvegarde sur disque par une bdd de mon choix
    3) si un jour je veux changer d'IHM et remplacer Qt par wxWidget, je ne modifie que la partie "vue".
    etc etc. Cette méthode de découpage est ce qu'on appelle couramment le MVC (modèle/vue/contrôleur). Bref je ne base pas mon appli sur une seule technique/outil/lib...

    PS: fais gaffe à la mode. Une fonction récursive ça peut sembler la solution mais quand on sait tout ce qui se passe derrière... Ce n'est pas interdit bien entendu... mais si on peut éviter c'est un gain de temps à l'exécution.
    Exemple: les suites de Fibonacci
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def fib_r(n):
       if n < 2: return 1
       return fib_r(n - 2) + fib_r(n - 1)
     
    def fib_i(n):
       res=[1, 1, 0]
       if n < 2: return res[n]
     
       i=2
       while i <= n:
           res[2]=res[0] + res[1]
           (res[0], res[1])=(res[1], res[2])
           i+=1
       return res[2]

    Voilà. La fonction récursive fait 2 lignes et l'itérative en fait 8. Mais compare donc les temps de réponse entre fib_r(38) et fib_i(38)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Futur Membre du Club
    Inscrit en
    Août 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 5
    Par défaut
    Je suis tout à fait d'accord cet objectif Sve@r
    J'avoue perdre un peu de temps en mélangeant ces 3 modules.. car je devrai obligatoirement tout reprendre.
    Mais bon j'ai quand même bien séparer tout ce qui concerne l'affichage et les données pour l'IHM (vive l'héritage multiple). D'où ma phrase: "j'apprend".. ca ne présentait pas d'utilités de tout séparer vu que je ne comprenait pas ce qu'il se passait.
    je pense que je vais refaire dès que j'aurais réussis à restaurer l'arbre!
    Histoire de mieux gérer l'affichage et les calculs.. ca me permettra de voir les threads en python au passage.

    Tu pourrais me montrer un petit exemple avec une fiction itérative s'il te plait? l'exemple du la suite de fibo ne me parle pas spécialement

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Ptiloic Voir le message
    Tu pourrais me montrer un petit exemple avec une fiction itérative s'il te plait? l'exemple du la suite de fibo ne me parle pas spécialement
    Mouais, si tu veux. Petite démo d'une création d'un arbre
    Code Python : 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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
     
    # Objet pour gérer un noeud
    class cNode:
    	# Chaine d'affichage arborescence (static)
    	__arbo="|__"
     
    	# Constructeur
    	def __init__(self, libelle):
    		# On mémorise le libellé du noeud qu'on est en train de créer
    		self.__libelle=libelle
     
    		# Création de la branche fille
    		self.__depend=[]
     
    		# Le noeud créé est vierge donc il n'a pas de parent
    		self.__parent=None
    	# __init__()
     
    	# Ajout d'un noeud
    	def __append(self, node):
    		# On mémorise qu'on est le parent du noeud ajouté (pour l'instant le parent n'est pas utilisé mais c'est au cas où)
    		node.__parent=self
     
    		# On rajoute le nouveau noeud comme étant notre enfant
    		self.__depend.append(node)
    	# append()
     
    	# Fonction de recherche d'un noeud ayant un libellé particulier (récursive mais on peut pas faire autrement)
    	def __find(self, libelle, prof=0):
    		# Si le libellé demandé est le notre
    		if libelle == self.__libelle:
    			# Alors on est là
    			return self
     
    		# Balayage de la branche fille
    		for node in self.__depend:
    			# On récupère l'item correspondant au libellé cherché
    			item=node.__find(libelle, prof + 1)
     
    			# Si l'item a été trouvé
    			if item != None:
    				# On le renvoie à l'appelant
    				return item
    		# for
     
    		# La branche a été balayée - L'item n'a pas été trouvé
    		# Si on n'est pas au premier niveau
    		if prof != 0:
    			# Pas trouvé, le parent aura peut-être plus de chance dans une autre branche
    			return None
    		else:
    			# Pas trouvé et plus de parent => Erreur de clef
    			raise KeyError, libelle
    		# if
    	# __find()
     
    	# Opérateur [] pour affectation => permet d'écrire noeud[...]=noeud_fils
    	def __setitem__(self, libelle, fils):
    		# On recherche le noeud contenant le libellé
    		node=self.__find(libelle)
     
    		# Maintenant on va rajouter le noeud contenant le libellé dans la branche fille
    		node.__append(fils)
    		# On aurait pu écrire aussi self.__find(libelle).__append(fils)
    	# __setitem__()
     
    	# Opérateur [] pour récupération => permet de récupérer noeud[]
    	def __getitem__(self, libelle):
    		# On renvoie le noeud contenant le libellé
    		return self.__find(libelle)
    	# __getitem__()
     
    	# Affichage d'un noeud
    	def affich(self, prof=0):
    		# Création de la chaine d'affichage
    		string=""
     
    		# On affiche l'arbre
    		string+="%s" % self.__arbo * prof
     
    		# On affiche le libellé
    		string+="%s (%s)\n" % (self.__libelle, self.__parent.__libelle if self.__parent != None else "None")
     
    		# Traitement des fils
    		for item in self.__depend:
    			string+=item.affich(prof + 1)
     
    		# On renvoie la chaine
    		return string
    	# affich()
    # class cNode()
     
    # Création de l'arbre
    arbre=cNode("main.c")
     
    # Ajout d'une branche (marche grâce à "__setitem__")
    arbre["main.c"]=cNode("stdio.h")
    arbre["main.c"]=cNode("stdlib.h")
    arbre["stdlib.h"]=cNode("sys/types.h")
    arbre["stdlib.h"]=cNode("sys/socket.h")
    arbre["stdio.h"]=cNode("sys/base_stdio.h")
     
    # Affichage d'une branche (marche grâce à "__getitem__")
    print arbre["main.c"].affich()

    Tu remarqueras que le plus gros du travail est écrit dans la classe. Une fois qu'elle est bien écrite et bien robuste, l'utiliser devient trivial. Toutefois ce bref exemple n'est pas absolument parfait. On peut envisager aussi de définir l'objet "cArbre" ; même si c'est un objet ne contenant rien de plus qu'un noeud racine mais ce qui permettrait d'y inclure plus tard des outils en plus de manipulation/recherche/stats (évolutivité). Par exemple la fonction "__find" aurait plus sa place dans l'objet arbre que dans l'objet "noeud". Mais pour l'instant on peut considérer qu'un noeud est un mini arbre...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 29
    Dernier message: 25/03/2015, 07h29
  2. [QtGui] pyqt4, mainwindow,menubar: basculer les menus
    Par noramokh dans le forum PyQt
    Réponses: 9
    Dernier message: 13/07/2014, 14h09
  3. Réponses: 2
    Dernier message: 18/04/2012, 09h56
  4. Réponses: 20
    Dernier message: 12/12/2010, 21h25
  5. Obligatoire : lisez les règles du forum : MAJ 06/08/2010
    Par Anomaly dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 0
    Dernier message: 03/07/2008, 13h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo