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 :

selectionChanged TreeView [Débutant(e)]


Sujet :

PyQt Python

  1. #1
    Membre éclairé Avatar de Jazz_
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 290
    Par défaut selectionChanged TreeView
    Bonjour,

    je suis un peu perdue, j'aissaie de m'abonner a l'evenement selectionchanged du mon QTreeView :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ## Dans une classe :
     
    def setSignals(self):
    		QObject.connect(self.ui.treeView,SIGNAL("selectionChanged()"), self.tree_clicked)
     
    def tree_clicked(self): #, newSelection, oldSelection):
    		print "changed"
    		if self.ui.treeView.SelectedIndex >= 0:
    			node = self.ui.treeView.SelectedNode()
    			print node
    et cela ne fonctionne pas, ca ne rentre jamais dans tree_clicked.
    Comment faire?

    Merci d'avance,
    Cordialement,

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je n'ai pas trouvé "selectionChanged()" en tant que signal de QTreeView: voir la doc: http://doc-snapshot.qt-project.org/4.8/qtreeview.html.

  3. #3
    Membre éclairé Avatar de Jazz_
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 290
    Par défaut
    Merci de ta réponse,

    Je l'ai trouvé dans la doc de pyqt4 :

    http://www.riverbankcomputing.co.uk/...lectionChanged

    apperement c'est une fonction hérité de QAbstractItemView.

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Citation Envoyé par Jazz_ Voir le message
    Merci de ta réponse,

    Je l'ai trouvé dans la doc de pyqt4 :

    http://www.riverbankcomputing.co.uk/...lectionChanged

    apparement c'est une fonction hérité de QAbstractItemView.
    A mon sens, on ne connecte que des "signaux" à des "slots" et les "slots" ne sont que des méthodes particulières.

    Un signal n'existe pas en tant que méthode, c'est juste une chaîne de caractères qui donne le "prototype" des fonctions qui pourront lui être connecté.

    Mais vous pouvez éventuellement surcharger selectionChanged pour lui faire faire .emit("selectionChanged()")

    Cordialement,
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    C'est bien ce que je disais: "selectionChanged()" n'existe pas en tant que signal. Le fait qu'il existe en tant que méthode ne sert à rien puisqu'un tel signal ne sera jamais émis.

    Les signaux qui sont émis par QTreeView sont précisés par la doc:

    Signals
    void collapsed ( const QModelIndex & index )
    void expanded ( const QModelIndex & index )

    6 signals inherited from QAbstractItemView
    1 signal inherited from QWidget
    1 signal inherited from QObject
    Comme le dit wiztricks, si ça ne suffit pas, on peut toujours créer de nouveaux signaux avec de nouveaux noms, mais il faut dans ce cas les émettre soi-même avec "emit" lorsque le contexte approprié est atteint.

    Commence par définir quel est l'évènement du QTreeView qui devrait émettre un signal, et cherche parmi les signaux existants s'il y en a un qui est prévu d'origine.

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut

    Citation Envoyé par tyrtamos Voir le message
    Commence par définir quel est l'évènement du QTreeView qui devrait émettre un signal, et cherche parmi les signaux existants s'il y en a un qui est prévu d'origine.
    Je n'ai pas le temps de tester mais la doc dit:

    void QAbstractItemView::selectionChanged
    [virtual protected slot]

    This slot is called when the selection is changed. The previous selection (which may be empty), is specified by deselected, and the new selection by selected.

    La fonction n'est pas appelée via un signal particulier mais de façon discrétionnaire par le gestionnaire de sélection.
    Ma compréhension du "virtual, protected" est qu'à part "surcharger"/redéfinir la fonction dans une s/classe de QTreeView impossible que çà se passe.
    Et bien sûr, le "body" de la fonction pourra se contenter d'émettre tous les signaux avec les paramètres souhaités.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre éclairé Avatar de Jazz_
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 290
    Par défaut
    Je ne suis pas sur de tout avoir compris.

    Ce que j'ai cru comprendre c'est que si je veux effectuer une action particulierere lorsque l'utilisateur change de selection, je doit creer une classe qui herite de QTreeView et surcharger la methode selection changed ?

    C'est cela?

  8. #8
    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,

    La méthode peut elle-même être reimplementée très simplement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            self.treeView = QtGui.QTreeWidget(parent)
            self.treeView.selectionChanged = self.selection_changed
            ...
     
     
        def selection_changed(self, new, old):
             print "selection_changed:", new, old
    Je viens de le tester.

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par Jazz_ Voir le message
    Ce que j'ai cru comprendre c'est que si je veux effectuer une action particulierere lorsque l'utilisateur change de selection, je doit creer une classe qui herite de QTreeView et surcharger la methode selection changed ?
    Absolument. La plomberie est du style:

    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
    class QTreeView(QtGui.QTreeView):
        def selectionChanged(self, *args, **kwds):
            print ('selection changed')
            self.emit(SIGNAL('selectionChanged()'))
            super(QTreeView, self).selectionChanged(*args, **kwds)
     
     
    # puis ailleurs
    model = ...
    tv = QTreeView()
    tv.setModel(model)
    # le slot a appeler    
    def on_selection_changed():
            print ('on_selection_changed')
    # on le connecte
    tv.connect(tv, SIGNAL('selectionChanged()'), on_selection_changed)
    Cordialement,
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    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
    Oops, c'est vrai que j'ai testé avec un QTreeWidget et pas un QTreeView.

    De toutes façons je vois que ce sont des QItemSelection qui sont retournés, ce qui n'aide pas vraiment, il faut utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            print self.treeView.currentItem()
    pour récupérer l'item sélectionné.

  11. #11
    Membre éclairé Avatar de Jazz_
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 290
    Par défaut
    Merci beaucoup, effectivement, ceci fonctionne:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def setSignals(self):
    		QObject.connect(self.ui.delete_button,SIGNAL("clicked()"), self.ui.lineEdit.clear)
    		QObject.connect(self.ui.new_button,SIGNAL("clicked()"), self.ui.lineEdit.clear)
    		QObject.connect(self.ui.save_button,SIGNAL("clicked()"), self.makeOut)
    		self.ui.treeView.selectionChanged = self.selection_changed
     
    	def selection_changed(self, new, old):
             print "selection_changed:", new, old
    par contre ca cree un bug d'afficheage (surement parceque la fonction virtuelle de QTreeview du coup n'est pas appelée) :

    quand je clique sur les objets, la partie a gauche du nom reste en surbrillance meme apres avoir changé de selection j'espere que ce screen vous aideras a comprendre :


    N'y a t'il pas un moyen d'apeller dans ma methode virtuelle surchargée, la methode abituelle ?

  12. #12
    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
    Et si tu ajoute ceci dans la définition de ton TreeView
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.treeView.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
    J'ai aussi le précédent item qui ne se désélectionne pas totalement, mais c'est le seul et si je déplace la souris par dessus l'affichage redevient correct.

  13. #13
    Membre éclairé Avatar de Jazz_
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 290
    Par défaut
    Meme avec cette ligne, chez moi ca ne change pas, moi ce sont effectivement les precedents items qui ne se delectionnent pas totalement (pas que la derniere), et effectivement ca redevient normal quand on passe la sourie dessus.

    EDIT :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print self.treeView.currentItem()
    Je ne trouve pas cette methode dans QTreeView, du coup comment je peux recuperer mon item selectionné ?

    je dispose de mon Model.

    Merci d'avance.

  14. #14
    Membre éclairé Avatar de Jazz_
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 290
    Par défaut
    J'ai trouvé !

    Au lieu de surcharger selectionchanged, j'ai surchargé currentchanged:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    elf.ui.treeView.currentChanged = self.selection_changed
     
    	def selection_changed(self, new, old):
    		print "selection_changed:", new, old
    		print self.Model.itemFromIndex(new)
    ensuite, j'ai utilisé la methode itemFromIndex de mon model.

  15. #15
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut mauvaise plomberie.
    Salut,

    Python étant interprété, il appliquera le comportement demandé à ce qu'il récupère comme "valeur" de l'attribut "currentChanged".

    Ceci dit:
    elf.ui.treeView.currentChanged = self.selection_changed
    self.selection_changed n'est pas "fonction" de la classe mais "bound method" à l'instance d'une autre classe: un autre objet que l'instance "elf.ui.treeView".

    Pour cette démo, c'est pas très grave: on fait pas grand chose.
    Plus tard, qui est "self" posera problème puisque c'est quand même ce qui définit le contexte de l'instance...

    De fait, sous-classer, définir sa méthode,... est une façon simple et propre de le faire. "Patcher" dynamiquement l'instance pour lui ajouter la méthode d'une autre instance signifie dissocier le "self" de la "fonction" et recoller la fonction à l'autre self... est une technique utile mais seulement lorsqu'on ne peut faire autrement.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  16. #16
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Moi aussi, je préfèrerais nettement la solution de la nouvelle classe héritant de QTreeView et dont la méthode concernée serait surchargée. Mais compte tenu d'instructions comme "self.ui.treeView", je suppose qu'on utilise QtDesigner. Et j'entrevois alors l'obstacle principal à une telle solution: peut-on continuer à utiliser QtDesigner avec la classe redéfinie d'un widget?

    Oui! On peut définir des widgets modifiés ainsi que des ensembles de plusieurs widgets et les utiliser avec QtDesigner. Et comme j'en avais besoin, j'ai même fait un tuto: http://python.jpvweb.com/mesrecettes...uveaux_widgets.

    Si tu souhaites aller dans cette direction: dis-le => je peux donner un coup de pousse.

  17. #17
    Membre éclairé Avatar de Jazz_
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2010
    Messages : 290
    Par défaut
    Merci beaucoup.

    Je vais continuer comme ca, les traitements que j'ai a faire sont minimes.

    Si d'aventure je me rend compte que j'ai vraiment besoin d'une nouvelle classe qui herite de QTreeview, je garde ton tutoriel sous le coude.

  18. #18
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Citation Envoyé par tyrtamos Voir le message
    Et j'entrevois alors l'obstacle principal à une telle solution: peut-on continuer à utiliser QtDesigner avec la classe redéfinie d'un widget?
    Très bonne question que j'avais complètement zappé
    Le tuto que vous avez fait adresse le problème plus largement et c'est bien.

    Ceci dit dans ce cas (particulier) où on souhaite "spécialiser" (ajouter une méthode à la classe QtGui.QTreeView) une façon de faire pourrait être:

    On crée la s/classe "normalement":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class QTreeView(QtGui.QTreeView):
        def currentChanged(self, ...):
             ...
    Puis on "patche" l'instance (elf.ui.treeView) via un changement "dynamique" de la classe de l'instance:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    elf.ui.treeView.__class__ = QTreeView
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. TreeView et menu contextuel...
    Par agh dans le forum Composants VCL
    Réponses: 6
    Dernier message: 06/04/2009, 12h23
  2. TreeView -> ajouter un child à un noeud donné
    Par fake dans le forum Composants VCL
    Réponses: 6
    Dernier message: 26/03/2003, 17h14
  3. Réponses: 5
    Dernier message: 09/01/2003, 11h55
  4. où y a t il un tutorial pour le Treeview ??
    Par silvermoon dans le forum C++Builder
    Réponses: 4
    Dernier message: 09/12/2002, 13h30
  5. [Pointer]Treeview.Data
    Par rbag dans le forum Composants VCL
    Réponses: 7
    Dernier message: 31/08/2002, 01h44

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