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 :

Signal quand on quitte un QTableWidget


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Géomaticien
    Inscrit en
    Octobre 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2012
    Messages : 12
    Par défaut Signal quand on quitte un QTableWidget
    Bonjour à tous,

    Je débute avec PyQt, je suis en train de faire une interface en PyQT sous forme de formulaire pour remplir une Base de données.

    Je bloque sur un point :

    A un endroit j'ai un Qtablewidget avec 2 boutons : un pour ajouter un élément, un autre pour supprimer l'élément sélectionné. Du coup à la base mon bouton "supprimer" est désactivé par défault et s'active quand je sélectionne une ligne de la table (j'utilise le Signal itemSelectionChanged).

    Maintenant j'aimerais désactiver le bouton quand je "sors" du Qtablewidget vers un autre Widget du formulaire mais je n'y arrive pas :

    - je n'ai pas trouvé de signal à faire émettre par QTableWidget

    - j'ai pensé à émettre un signal quand je clique sur un autre widget (QLineEdit par exemple) mais je ne trouve pas non plus : j'ai cru comprendre qu'il faut réimplémenter un mouseClicEvent, mais en bon débutant que je suis, je n'y suis pas encore parvenu et surtout, je me demande si c'est la meilleure méthode sachant que je devrais recréer le même signal pour chaque widget de mon formulaire ce qui me semble alourdir le code pour peu.

    Qu'en pensez-vous?

    Merci d'avance,

    Maxime

  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,

    On peut utiliser les méthodes focusOutEvent et focusInEvent qui sont automatiquement appelées lorsque le QTableWidget respectivement perd et récupère le focus. Il faut surcharger ces méthodes pour faire ce qu'on veut faire.

    Ce sont bien ici les méthodes de QTableWidget dont on a besoin, ce qui logiquement nécessite de sous-classer QTableWidget. C'est facile à faire, sauf si on veut absolument utiliser QDesigner pour dessiner la fenêtre.

    Dans ce dernier cas, il y a une astuce: il s'agit de rediriger les méthodes focusOutEvent et focusInEvent de la table sur celle de la fenêtre. Il faut alors pouvoir tester au début de ces méthodes si la table est concernée ou pas par l'évènement.

    Voilà un petit code exemple:

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        # =======================================================================
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
            self.resize(800,600)
     
            self.tableWidget = QtGui.QTableWidget(self)
            self.nbrow, self.nbcol = 7, 7
            self.tableWidget.setRowCount(self.nbrow)
            self.tableWidget.setColumnCount(self.nbcol)
     
            self.tableWidget.focusInEvent = self.focusInEvent
            self.tableWidget.focusOutEvent = self.focusOutEvent
     
            self.bouton1 = QtGui.QPushButton(self)
            self.bouton2 = QtGui.QPushButton(self)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.tableWidget, 0, 0)
            posit.addWidget(self.bouton1, 1, 0)
            posit.addWidget(self.bouton2, 2, 0)
            self.setLayout(posit)
     
            self.tableWidget.setFocus()
            self.tablefocus = True
            self.tableWidget.setCurrentCell(0, 0)
     
        # =======================================================================
        def focusInEvent(self, event):
     
            if self.tableWidget.hasFocus():
                print u"la table prend le focus!"
                self.tablefocus = True
                event.accept()
            else:
                QtGui.QWidget.focusInEvent(self, event)
     
        # =======================================================================
        def focusOutEvent(self, event):
     
            if self.tablefocus:
                print u"la table perd le focus!"
                self.tablefocus = False
                event.accept()
            else:
                QtGui.QWidget.focusOutEvent(self, event)
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Il faut lancer ça dans une console ou dans un outil de développement à cause du print.

    Il y a une table et 2 boutons. Quand la table prend le focus ou le perd, les messages s'affichent. Par contre, quand on clique alternativement sur l'un et l'autre des boutons, il n'y a aucun message parce que la table n'est pas concernée.

  3. #3
    Membre habitué
    Homme Profil pro
    Géomaticien
    Inscrit en
    Octobre 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2012
    Messages : 12
    Par défaut
    Merci beaucoup pour la réponse, je teste ça et ferai un retour. Je ne l'ai pas précisé mais effectivement je veux utiliser QDesigner.

    Bonne après-midi,

    Maxime

  4. #4
    Membre habitué
    Homme Profil pro
    Géomaticien
    Inscrit en
    Octobre 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2012
    Messages : 12
    Par défaut
    Super ça marche! Par contre je suis confronté à un autre soucis du coup : si je clique sur le boutton "supprimer" la table perd le focus, du coup je ne peux plus cliquer sur supprimer

  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
    Si j'ai bien compris (ce qui n'est pas sûr), il suffit de redonner le focus à la table, dans la méthode de traitement du clic du bouton "supprimer".

  6. #6
    Membre habitué
    Homme Profil pro
    Géomaticien
    Inscrit en
    Octobre 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2012
    Messages : 12
    Par défaut
    Merci beaucoup de prendre le temps de me répondre en tout cas!

    En fait je veux que l'utilisateur ait la possibilité de cliquer sur "supprimer" (pour supprimer une entrée de la table) uniquement quand il a préalablement sélectionné une ligne.

    Là j'ai 2 petits soucis :

    - la table prend le focus au démarrage par défaut même quand j'enlève les lignes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            self.Table.setFocus()
            self.tablefocus=True
            self.Table.setCurrentCell(0,0)
    - Quand je sélectionne une ligne de ma table, le bouton "supprimer" est bien actif mais quand j'essaye de cliquer dessus, il ne l'est plus puisque la table perd le focus et que je lui ai demandé d'être inactif quand il perd le focus.

    Voici mon code sur lequel je fais mes tests :


    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
    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
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    # -*- coding: cp1252 -*-
     
    from PyQt4.QtCore import SIGNAL, SLOT, Qt, QEvent
    from PyQt4.QtGui import QApplication, QWidget, QLineEdit, QPushButton, QHBoxLayout, QTableWidget,QTableWidgetItem, QLabel, QAbstractItemView
    import sys
     
    class Form(QWidget):
        def __init__(self, parent=None):
            super(Form, self).__init__(parent)
            self.Layout=QHBoxLayout(self)     
            self.Table=QTableWidget(self)
            self.Table.focusInEvent=self.focusInEvent
            self.Table.focusOutEvent=self.focusOutEvent
    #        self.Table.setFocus()
    #        self.tablefocus=True
    #        self.Table.setCurrentCell(0,0)
            self.remplirTable()
            self.Boutton=QPushButton("Ajouter une notification")
            self.Boutton.connect(self.Boutton, SIGNAL("clicked()"), self.slotAction)
            self.Boutton2=QPushButton("Supprimer une notification")
            self.Boutton2.setEnabled(False)
            self.Boutton2.connect(self.Boutton2, SIGNAL("clicked()"), self.slotAction2)
            self.LineEdit=QLineEdit()
            self.LineEdit2=QLineEdit()
            self.Layout.addWidget(self.Table)
            self.Layout.addWidget(self.Boutton)
            self.Layout.addWidget(self.Boutton2)
            self.Layout.addWidget(self.LineEdit)
            self.Layout.addWidget(self.LineEdit2)
     
        def remplirTable(self):
            self.Table.clear()
            self.Table.setRowCount(len(Liste))
            self.Table.setColumnCount(3)
            self.Table.setAlternatingRowColors(True)
            self.Table.setHorizontalHeaderLabels(["Num", "Date", "Destinataire"])
            self.Table.verticalHeader().hide()
            self.Table.setEditTriggers(QAbstractItemView.NoEditTriggers)
            self.Table.setSelectionMode(QAbstractItemView.SingleSelection)
            self.Table.setSelectionBehavior(QAbstractItemView.SelectRows)
            for r,row in enumerate(Liste):
                for c,column in enumerate(row):
                    self.Item=QTableWidgetItem(column)
                    self.Table.setItem(r,c,self.Item)
            self.Table.resizeColumnsToContents()
     
        def slotAction(self):
            self.notif=Notif()
            self.notif.show()
     
        def slotAction2(self):
            self.Table.setCurrentCell(self.Table.currentRow(),0)
            Suppr=self.Table.currentItem().text()
            for i,n in enumerate(Liste):
                if Liste[i][0]==Suppr:
                    Liste.pop(i)
            self.remplirTable()
     
     
        def focusInEvent(self,event):
            if self.Table.hasFocus():
                print u"la table prend le focus"
                self.tablefocus=True
                self.Boutton2.setEnabled(True)
                event.accept()
    #        else:
    #            QWidget.focusInEvent(self,event)
     
        def focusOutEvent(self,event):
            if self.tablefocus:
                print u"la table perd le focus"
                self.tablefocus=False
                self.Boutton2.setEnabled(False)
                event.accept()
    #        else:
    #            QWidget.focusOutEvent(self,event)
     
    class Notif(QWidget):
        def __init__(self, parent=None):
            super(Notif, self).__init__(parent)
            self.NotifLayout=QHBoxLayout(self)
            self.labelNotif1=QLabel(self)
            self.labelNotif1.setText("Date :")
            self.lineEdit_Notif1=QLineEdit(self)
            self.labelNotif2=QLabel(self)
            self.labelNotif2.setText("Destinataire :")
            self.lineEdit_Notif2=QLineEdit(self)
            self.BouttonNotif=QPushButton("Ok")
            self.BouttonNotif.connect(self.BouttonNotif, SIGNAL("clicked()"),self.slotAction)
            self.NotifLayout.addWidget(self.labelNotif1)
            self.NotifLayout.addWidget(self.lineEdit_Notif1)
            self.NotifLayout.addWidget(self.labelNotif2)
            self.NotifLayout.addWidget(self.lineEdit_Notif2)      
            self.NotifLayout.addWidget(self.BouttonNotif)
     
        def slotAction(self):
            self.Date=self.lineEdit_Notif1.text()
            self.Destinataire=self.lineEdit_Notif2.text()
            self.ListeID=[]
            try:
                for n in Liste:
                    self.ListeID.append(int(n[0]))
                self.maxListeID=max(self.ListeID)+1
            except:
                self.maxListeID=1
            Liste.append([unicode(self.maxListeID),self.Date,self.Destinataire])
            form.remplirTable()
            form.notif.close()
     
     
    if __name__== "__main__" :
        App=QApplication(sys.argv)
        Liste=[["1","2013-01-07","M. Prout"],["2","2012-12-05","Mme Prout"],["3","2012-10-12","Mr Caca"]]
        form=Form()
        form.show()
        App.exec_()

Discussions similaires

  1. [c#]Destructeur, problème quand je quitte de programme
    Par skysee dans le forum Windows Forms
    Réponses: 28
    Dernier message: 01/06/2008, 23h10
  2. Comprendre demande d'enregistrement quand on quitte
    Par Lucas Panny dans le forum Visual C++
    Réponses: 4
    Dernier message: 06/12/2007, 09h55
  3. Réponses: 4
    Dernier message: 24/01/2007, 15h59
  4. Réponses: 2
    Dernier message: 08/08/2006, 22h17
  5. Réponses: 1
    Dernier message: 16/05/2004, 17h56

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