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 :

QKeyPressEvent pour deux widgets


Sujet :

PyQt Python

  1. #1
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut QKeyPressEvent pour deux widgets
    Bonjour,

    je débute encore dans la gestion des évènements en PyQt, mon problème est sans doute simple à résoudre mais je ne comprends pas comment faire.
    J'ai dans ma fenêtre deux widgets, un QListWidget et un QTableWidget.
    Pour chacun j'ai besoin de savoir quand l'utilisateur appuie sur la touche "suppr", afin que cela supprime les éléments sélectionnés dans mon widget.

    Comment puis-je savoir le widget concerné lors de l'appel de keyPressEvent?
    J'ai besoin d'appeler une méthode différente pour ces deux widgets lors d'un appui sur "suppr".

    Merci d'avance pour votre aide!

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il suffit de demander si le widget concerné a le focus. C'est logique, puisque par définition c'est le widget qui a le focus qui reçoit les touches du clavier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        def keyPressEvent(self, event):
            if self.widget1.hasFocus():
                if event.key() in [liste des touches recherchées pour le widget1]:
                    ...
            elif  self.widget2.hasFocus(): 
                if event.key() in [liste des touches recherchées pour le widget2]:
                    ...
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Tout simplement!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def keyPressEvent(self, event):
        if self.myListBox.hasFocus():
            if event.key() == QtCore.Qt.Key_Delete:
                print "supression pour la listbox"
        elif  self.myTabWidget.hasFocus(): 
            if event.key() == QtCore.Qt.Key_Delete:
                print "supression pour le tabWidget"
    Merci de ta réponse rapide et efficace

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,
    Encore plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class ListWidget(QListWidget):
        def keyPressEvent(self, e):
            if event.key() == QtCore.Qt.Key_Delete:
                print "supression pour la listbox"   
     
    class TableWidget(QTableWidget):
        def keyPressEvent(self, e):
            if event.key() == QtCore.Qt.Key_Delete:
                print "supression pour le tabWidget"
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour wiztricks,

    Le sous-classement a tout de même un inconvénient: on ne peut plus utiliser ces widgets avec QtDesigner, à moins d'en créer les conditions (plugins). Et là, ce n'est plus simple du tout.

    Il y a une solution intermédiaire: un "détournement" de méthode du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    self.myListBox.keyPressEvent = self.keyPressEvent_lb
    self.myTabWidget.keyPressEvent = self.keyPressEvent_tb
    Dans ce cas, les 2 méthodes self.keyPressEvent_lb et self.keyPressEvent_tb reçoivent les touches clavier de chacun des 2 widgets seulement en cas de focus. Mais il ne faut pas oublier de "redonner la main" au keyPressEvent d'origine.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Le sous-classement a tout de même un inconvénient: on ne peut plus utiliser ces widgets avec QtDesigner, à moins d'en créer les conditions (plugins). Et là, ce n'est plus simple du tout.
    Pour les orthodoxes du C++, c'est sur.
    Un code quick&dirty...
    Je fabrique un truc avec QtDesigner:
    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
    45
    46
    47
    # -*- coding: utf-8 -*-
     
    # Form implementation generated from reading ui file 'ui_sample.ui'
    #
    # Created: Tue Jan 28 12:44:59 2014
    #      by: PyQt4 UI code generator 4.10.3
    #
    # WARNING! All changes made in this file will be lost!
     
    from PyQt4 import QtCore, QtGui
     
    try:
        _fromUtf8 = QtCore.QString.fromUtf8
    except AttributeError:
        def _fromUtf8(s):
            return s
     
    try:
        _encoding = QtGui.QApplication.UnicodeUTF8
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig, _encoding)
    except AttributeError:
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig)
     
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName(_fromUtf8("Form"))
            Form.resize(498, 445)
            self.verticalLayoutWidget = QtGui.QWidget(Form)
            self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, -1, 501, 441))
            self.verticalLayoutWidget.setObjectName(_fromUtf8("verticalLayoutWidget"))
            self.verticalLayout = QtGui.QVBoxLayout(self.verticalLayoutWidget)
            self.verticalLayout.setMargin(0)
            self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
            self.tableView = QtGui.QTableView(self.verticalLayoutWidget)
            self.tableView.setObjectName(_fromUtf8("tableView"))
            self.verticalLayout.addWidget(self.tableView)
            self.listView = QtGui.QListView(self.verticalLayoutWidget)
            self.listView.setObjectName(_fromUtf8("listView"))
            self.verticalLayout.addWidget(self.listView)
     
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
     
        def retranslateUi(self, Form):
            Form.setWindowTitle(_translate("Form", "Form", None))
    Puis je code avec une pincée de Pythonique:

    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
    import sys
    from PyQt4.QtGui import QApplication, QDialog, QListWidget, QTableWidget
    from ui_sample import Ui_Form
     
    class ListWidget(QListWidget):
        def keyPressEvent(self, e):
            cls = type(self)
            print (cls.__name__)
            return super().keyPressEvent(e)
     
    class TableWidget(QTableWidget):
        def keyPressEvent(self, e):
            cls = type(self)
            print (cls.__name__)
            return super().keyPressEvent(e)
     
    app = QApplication(sys.argv)
    window = QDialog()
    ui = Ui_Form()
    ui.setupUi(window)
    ui.tableView.__class__ = TableWidget
    ui.listView.__class__ = ListWidget
     
    window.show()
    sys.exit(app.exec_())
    Et voila.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    En effet j'avais vu cette façon de faire avec le sous-classement, et comme Tyrtamos je ne voyais pas comment l'utiliser comme mes widgets sont créés avec QtDesigner. Donc merci pour l'exemple!
    Mais j'avoue que je trouve cette solution plus compliquée.

    tyrtamos ta deuxième solution est pas mal aussi et je me rends compte que je l'utilisais déjà pour des dropEvent (c'est même toi qui m'avait montré ça pour les dropEvent dans un ancien post je crois)! Je n'ai même pas pensé à reprendre ça pour les keyPressEvent

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par mokochan Voir le message
    En effet j'avais vu cette façon de faire avec le sous-classement, et comme Tyrtamos je ne voyais pas comment l'utiliser comme mes widgets sont créés avec QtDesigner. Donc merci pour l'exemple!
    La solution de Tyrtamos est "semblable".
    Avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.myListBox.keyPressEvent = self.keyPressEvent_lb
    on ajoute dynamiquement l'attribut keyPressEvent a self.myListBox instance de QListWidget.
    Avec ui.listView.__class__ = ListWidget, on remplace l'espace de noms herite par l'instance par un autre dans lequel keyPressEvent est défini.

    Mais j'avoue que je trouve cette solution plus compliquée.
    C'est du "pythonique"... Un mise en œuvre simple qui donne le tournis aux débutants.

    La solution de Tyrtamos est sympa lorsqu'il n'y a qu'un callback a spécialiser. Lorsque leur nombre augmente, ça devient vite le bazar que seules les s/classes permettent de résoudre.
    En C++, pas facile d'aller patcher la vtable d'une instance: le pluggin est plus sur. En Python, c'est une autre histoire...

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

  9. #9
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Citation Envoyé par wiztricks
    La solution de Tyrtamos est sympa lorsqu'il n'y a qu'un callback a spécialiser. Lorsque leur nombre augmente, ça devient vite le bazar que seules les s/classes permettent de résoudre.
    Bien d'accord. Dans le cas présent je vais rester sur la solution de Tyrtamos puisque que c'est une sous-fenêtre toute simple de mon IHM avec seulement 2 widgets à considérer.
    Mais si je suis amenée à devoir gérer les keyPressEvent sur une IHM plus compliquée j'utiliserai les sous classes.
    Merci!

  10. #10
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 563
    Points : 460
    Points
    460
    Par défaut
    wiztricks => Merci beaucoup !!!
    C'est exactement ce que je cherchais depuis quelques heures, j'ai fait pas mal de tests compliqués... (2 ui que j'essaie de rassembler, j'y arrivais mais ça ne donnait pas exactement ce que je voulais au niveau graphique).

    Là, c'est un chouille plus long que la proposition de Tyrtamos mais ça reste très lisible et pratique (j'utilise pour le drag and drop)!

    Merci à vous deux.
    Sous Kubuntu 20.04

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 24/07/2006, 16h11
  2. 0% CPU selon ps pour deux setiathome qui tournent!!!
    Par SaintAmand dans le forum Applications et environnements graphiques
    Réponses: 5
    Dernier message: 21/05/2006, 21h40
  3. Count pour deux tables
    Par Safaritn dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 08/11/2005, 16h22
  4. switch case pour deux variable en meme temps
    Par petitours dans le forum C
    Réponses: 3
    Dernier message: 06/11/2005, 19h20
  5. [Sybase] Dump pour deux platefrome # ASE12.5
    Par vsavoir dans le forum Sybase
    Réponses: 9
    Dernier message: 14/07/2005, 18h31

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