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 :

Liaison entre deux QTableView. [QtGui]


Sujet :

PyQt Python

  1. #1
    Membre régulier
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Points : 92
    Points
    92
    Par défaut Liaison entre deux QTableView.
    Bonjour,

    C'est toujours moi avec mes problèmes de programmation qui n'en finissent pas. Aujourd'hui je voulais vous posez un nouveau cas qui se résume ainsi:

    J'ai deux QTableView la première contient l'ensemble des employés et l'autre contient les formations effectuées. Pour le moment les deux tables m'affichent l'une l'ensemble de l'effectif et autre l'ensemble de l'effectif qui a subi une ou plusieurs formation.
    Je voudrais filtrer la deuxième TableView (Formation) en fonction de la matricule de l'employé sélectionnée dans la première TableView.
    Ainsi, Je me suis inspiré de l'exemple précédent (Lien entre deux QComboBox) pour filtrer la table mais sans résultat.
    Je demande votre aide.

    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
     
     
    #Model des employés
     
            self.modellisteemloyes = QSqlRelationalTableModel(self)
            self.modellisteemloyes.setTable('Agents')
            self.modellisteemloyes.setEditStrategy(QSqlRelationalTableModel.OnManualSubmit)
            self.modellisteemloyes.select()
            self.modellisteemloyes.setSort(0, Qt.AscendingOrder)
            self.ui.tableViewEmployes.setSortingEnabled(True)
            self.ui.tableViewEmployes.setModel(self.modellisteemloyes)
            self.ui.tableViewEmployes.resizeColumnsToContents()
            self.ui.tableViewEmployes.selectionModel().currentRowChanged.connect(self.setFiltreFormat)
     
    #Model employés ayant subi une ou plusieurs formations
     
            self.modellisteformation = QSqlRelationalTableModel(self)
            self.modellisteformation.setTable('Formations')
            self.modellisteformation.setEditStrategy(QSqlRelationalTableModel.OnManualSubmit)
            self.modellisteformation.select()
            self.modellisteformation.setSort(0, Qt.AscendingOrder)
            self.ui.tableViewformasuivi.setSortingEnabled(True)
            self.ui.tableViewformasuivi.setModel(self.modellisteformation)
            self.ui.tableViewformasuivi.resizeColumnsToContents()
     
        def setFiltreFormat(self, row):
            Matricule=self.modellisteemloyes.selectionModel(self.modellisteemloyes.index(row,0, QModelIndex()))
            self.modellisteformation.setFilter("Matricule = {}".format(Matricule))

  2. #2
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mai 2003
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2003
    Messages : 290
    Points : 388
    Points
    388
    Par défaut
    Bonjour,
    Sur le même principe que les combobox :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            self.ui.tableViewEmployes.clicked.connect(setFiltreFormat) 
        def setFiltreFormat(self, ind): #C'est un QModelIndex qui est renvoyé
            Matricule=self.modellisteemloyes.data(self.modellisteemloyes.index(ind.row(),0, QModelIndex()))
            self.modellisteformation.setFilter("Matricule = {}".format(Matricule))

  3. #3
    Membre régulier
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Points : 92
    Points
    92
    Par défaut
    Merci pierjean pour votre réponse et excusez mon retard de vous répondre.
    J'ai utilisé votre scripte mais il me donne un tableau vide avec uniquement son entête.
    J'ai ajouté "print(Matricule)", pour voire si la fonction marche, alors la matricule s'affiche correctement.
    Cordialement.

  4. #4
    Membre régulier
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Points : 92
    Points
    92
    Par défaut
    Bonjour,
    J'ai modifier la fonction setFiltreFormat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     def setFiltreFormat(self, ind): #C'est un QModelIndex qui est renvoyé
            Matricule=self.modellisteemloyes.data(self.modellisteemloyes.index(ind.row(),0, QModelIndex()))
            print(Matricule) #Pour afficher la matricule 
            self.modellisteformation.setFilter("Matricule = {}".format(Matricule))
            self.ui.tableViewformasuivi.setModel(self.modellisteformation) # J'ai ajouté cette ligne  
    La tableau est toujours vide, est ce que j'ai oublié quelque chose.
    Merci

  5. #5
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mai 2003
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2003
    Messages : 290
    Points : 388
    Points
    388
    Par défaut
    Bonjour,
    Un petit exemple qui fonctionne :
    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
    import sys, sqlite3
    from PyQt5.QtWidgets import (QMainWindow, QApplication, QWidget, 
                                 QHBoxLayout,QTableView)
    from PyQt5.QtSql import (QSqlDatabase, QSqlQuery, QSqlTableModel,
                                    QSqlRelation,QSqlRelationalTableModel)
    from PyQt5.QtCore import QModelIndex
     
    class MyWindow(QMainWindow):
            def __init__(self):
                    super(MyWindow, self).__init__()
                    db=self.connectdb()
                    widget=QWidget(self)
                    self.setCentralWidget(widget)
                    layout=QHBoxLayout()
     
                    self.tableViewEmployes=QTableView(self)
                    self.tableViewformasuivi=QTableView(self)
                    layout.addWidget(self.tableViewEmployes)
                    layout.addWidget(self.tableViewformasuivi)
                    widget.setLayout(layout)
     
                    self.modellisteemloyes=QSqlTableModel()
                    self.modellisteemloyes.setTable("Agents")
                    self.modellisteemloyes.select()
                    self.tableViewEmployes.setModel(self.modellisteemloyes)
     
                    self.modellisteformation=QSqlRelationalTableModel()
                    self.modellisteformation.setTable("Formations")
                    self.modellisteformation.setRelation(1,QSqlRelation('Listeformations', 'FormId', 'intitule'))
                    self.modellisteformation.select()
                    self.tableViewformasuivi.setModel(self.modellisteformation)
                    self.tableViewEmployes.clicked.connect(self.setFilter)
     
     
            def setFilter(self, ind):
                    matricule=self.modellisteemloyes.data(self.modellisteemloyes.index(ind.row(), 0, QModelIndex()))
                    self.modellisteformation.setFilter("Matricule = {}".format(matricule))
     
            def connectdb(self):
                    db = QSqlDatabase.addDatabase("QSQLITE")
                    db.setDatabaseName(":memory:")
                    if not db.open():
                            return False
     
                    Agents = [(1, "Agent 1"),
                                    (2, "agent 2"),
                                    (3,"Agent 3")]
     
                    Listeformations=[(1,  "Formation 1"), 
                                            (2,  "Formation 2"), 
                                            (3,  "Formation 3"), 
                                            (4,  "Formation 4")]
    #liste des formations suivies (Matricule, formation)
                    Formations=[
                                            (1,1),
                                            (1,2),
                                            (2,2)]
     
                    query=QSqlQuery()
                    query.exec_("create table Agents(Matricule int, Nom varchar(20))")
                    query.exec_("create table Formations(Matricule int, FormId)")
                    query.exec_("create table Listeformations(FormId, Intitule varchar(20))")
                    for value in Agents:
                            query.exec_("insert into Agents (Matricule, Nom) values {}".format(value))
                    for value in Formations:
                            query.exec_("insert into Formations(Matricule, FormId) values {}".format(value))
                    for value in Listeformations:
                            query.exec_("insert into Listeformations(FormId, Intitule) values {}".format(value))
                    return True
     
    if __name__ == "__main__":
            application = QApplication(sys.argv)
            win = MyWindow()
            win.show()
     
            con = sqlite3.connect(":memory:")
            con.close()
     
            sys.exit(application.exec_())
    J'ai ajouté un exemple avec QSqlRelationalTableModel car tu l'utilise dans ton code, mais sans QSqlRelation.

    Après, je ne sais pas à quoi ressemblent tes tables.

  6. #6
    Membre régulier
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Points : 92
    Points
    92
    Par défaut
    Bonjour pierjean,
    Merci pour votre réponse, j'ai essayé d'adapter votre code pour l'utiliser dans mon programme mais en vain, je ne sais pas ce qui manque. J'ai aussi modifier votre code pour utiliser uniquement deux tables Agents et Formations ça a marché.
    ci-après mon code peut être j'ai loupé quelque chose ???

    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
     
     
       #Création du model agents
     
            self.modellisteemloyes = QSqlRelationalTableModel(self)
            self.modellisteemloyes.setTable('Agents')
            self.modellisteemloyes.setEditStrategy(QSqlRelationalTableModel.OnManualSubmit)
            self.modellisteemloyes.select()
            self.modellisteemloyes.setSort(0, Qt.AscendingOrder)
            self.ui.tableViewEmployes.setSortingEnabled(True)
            self.ui.tableViewEmployes.resizeColumnsToContents()
            self.ui.tableViewEmployes.setModel(self.modellisteemloyes)
     
            self.modellisteemloyes.setRelation(1,QSqlRelation('Formations', 'Matricule', ' ')) 
     
        #Affichage des formations
     
            self.modellisteformation = QSqlRelationalTableModel(self)
            self.modellisteformation.setTable('Formations')
            self.modellisteformation.select()
            self.modellisteformation.setEditStrategy(QSqlRelationalTableModel.OnManualSubmit)
            self.modellisteformation.setSort(0, Qt.AscendingOrder)
            self.ui.tableViewformasuivi.setModel(self.modellisteformation)
            self.ui.tableViewformasuivi.setSortingEnabled(True)
            self.ui.tableViewformasuivi.resizeColumnsToContents()
     
            self.ui.tableViewEmployes.clicked.connect(self.setFiltreFormat)
     
        def setFiltreFormat(self, ind):
            matricule=self.modellisteemloyes.data(self.modellisteemloyes.index(ind.row(),0, QModelIndex()))
            self.modellisteformation.setFilter("Matricule = {}".format(matricule))
    Aussi, lorsque je clique sur l’entête pour trier les enregistrements, le tableau devient vide.
    J'ai oublié de vous donner la structure des deux tables

    -- Table : Agents

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        Matricule CHAR (6)     NOT NULL   PRIMARY KEY,
        Nom       VARCHAR (50) NOT NULL,
        Prenoms   VARCHAR (50) NOT NULL,
        Fonction  VARCHAR (50) NOT NULL,
        Structure VARCHAR (50) NOT NULL

    -- Table : Formations

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        Matricule CHAR (6)     PRIMARY KEY   NOT NULL
                               REFERENCES Agents (Matricule),
        Domaine   VARCHAR (20) NOT NULL,
        Activite  VARCHAR (50) NOT NULL,
        Type      CHAR (3)     NOT NULL,
        Theme     VARCHAR (50) NOT NULL,
        Ecole     CHAR (3)     NOT NULL,
        Datedebut DATE         NOT NULL,
        Datefin   DATE         NOT NULL,

    Salutations

  7. #7
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mai 2003
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2003
    Messages : 290
    Points : 388
    Points
    388
    Par défaut
    Bonjour,
    C'est cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.modellisteemloyes.setRelation(1,QSqlRelation('Formations', 'Matricule', ' '))
    Tu essaies de lier la colonne "Nom" avec "Matricule" de la table Formations et d'afficher le champs " " dans cette colonne.
    D'ailleurs je ne vois pas l'utilité d'un QSqlRelationalTableModel.

  8. #8
    Membre régulier
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Points : 92
    Points
    92
    Par défaut
    Bonjour pierjean,

    Merci pour votre réponse seulement j'ai trouvé un autre problème "bête" c'est le type de champ de matricule qui était en "CHAR" je l'ai modifié en "int" et ça a marché.
    En outre, je voudrais vous dire que je suis un novice dans le langage PyQt et j'essaye d’utiliser des morceaux de codes où la majorité des cas je ne connaissais pas la signification des paramètres utilisés.
    Vous me dites : "D'ailleurs je ne vois pas l'utilité d'un QSqlRelationalTableModel" c'est la réalité je ne sais pas la différence entre QSqlRelationalTableModel et QSqlTableModel.
    C'est pour cette raison, je vous suggère, vous les membres experts de ce forum, dans la mesure du possible, de nous expliquer de temps en temps des principes de programmation en PyQt.
    Merci encore.

  9. #9
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mai 2003
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2003
    Messages : 290
    Points : 388
    Points
    388
    Par défaut
    Bonjour,
    Je ne me considère pas comme un membre expert
    QSqlRelationalTableModel permet d'utiliser les jointures.
    Dans l'exemple complet que je t'ai donné, ligne 29 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.modellisteformation.setRelation(1,QSqlRelation('Listeformations', 'FormId', 'intitule')
    La 2ème colonne de self.modellisteformation est mis en relation avec le champs 'Intitulé' de Listeformations.
    Dans ton TableView, au lieu de voir le N° de la formation, tu vois son intitulé.
    Je ne sais pas si je suis clair

  10. #10
    Membre régulier
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Points : 92
    Points
    92
    Par défaut
    Bonjour pierjean,
    Merci pour votre réponse, c'est très clair.
    Je voulais faire une jointure entre la table "Agents" et la table "Formation" où la 1ere colonne "matricule" est la même clé et d'afficher le reste des informations (theme, école, type, datedebut et datefin) dans "tableViewformasuivi ".
    J'ai modifié la ligne en question de votre code en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    self.modellisteemloyes.setRelation(0,QSqlRelation('Formations', 'Matricule', ''))
    Le résultat est juste et affiché dans "tableViewformasuivi ".

    Et, si je met cette ligne pour spécifier les colonnes à afficher :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    self.modellisteemloyes.setRelation(0,QSqlRelation('Formations', 'Matricule', 'Theme, Ecole, Type, Datedebut, Datefin'))
    le résultat est affiché dans "tableViewformasuivi " mais, quand je clique sur l’entête du "tableViewAgents"
    la "tableViewAgents" affiche les éléments : Theme, Ecole, Type, Datedebut, Datefin ainsi que, les colonnes de "tableViewAgents" concernant uniquement les agents qui ont poursuivie une formation. Bizarre

    Ma question, est ce que je met
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.ui.tableViewEmployes.setSortingEnabled(False)
    ou bien j'ai oublié quelques chose.

    Au question SVP : Pourquoi quand j'ai modifier le type de champ "Matricule" de CHAR vers INTEGER le code a marcher ???

  11. #11
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mai 2003
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2003
    Messages : 290
    Points : 388
    Points
    388
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    self.modellisteemloyes.setRelation(0, #La colonne où tu veux voir le champs de l'autre table
        QSqlRelation('Formations', #la table reliée
         'Matricule', #le champs de cette table
         '' #Le champs que tu veux voir affiché. Ici : '', qui n'existe pas.
    ))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    self.modellisteemloyes.setRelation(0, #Le champs 'Matricule' sur lequel tu vas faire ton filtre
        QSqlRelation('Formations', 'Matricule',
         'Theme, Ecole, Type, Datedebut, Datefin' #Ce que tu affiches à la place de 'Matricule'
        ))
    Pour te donner une idée, voici à quoi ressemble la requête associée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT relTblAl_0.Theme, Ecole, Type, Datedebut, Datefin,Agents."Nom" FROM Agents,Formations relTblAl_0 WHERE (Agents."Matricule"=relTblAl_0.Matricule)

  12. #12
    Membre régulier
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Septembre 2015
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : Algérie

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 148
    Points : 92
    Points
    92
    Par défaut
    Merci beaucoup.

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

Discussions similaires

  1. Probleme de liaison entre deux tables d'une base de donnees
    Par blondelle dans le forum C++Builder
    Réponses: 32
    Dernier message: 12/04/2007, 18h09
  2. Liaison entre deux tables
    Par knoll dans le forum Langage SQL
    Réponses: 1
    Dernier message: 02/02/2007, 17h23
  3. liaison entre deux bases de données access
    Par questions dans le forum Access
    Réponses: 1
    Dernier message: 09/06/2006, 13h26
  4. [VBA-A] liaison entre deux tables
    Par lumbroso dans le forum VBA Access
    Réponses: 16
    Dernier message: 01/06/2006, 10h22
  5. condition liaison entre deux formulaires
    Par Davik dans le forum Access
    Réponses: 10
    Dernier message: 25/04/2006, 15h52

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