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

Python Discussion :

Problème affichage d'une mise à jour d'un QTableWidget


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    DAF
    Inscrit en
    Août 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : DAF
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2020
    Messages : 12
    Par défaut Problème affichage d'une mise à jour d'un QTableWidget
    Bonjour à tous

    je me suis mis à tester le développement d'interface graphique à l'aide de PyQt5.
    Je rencontre un problème que je n'arrive pas à résoudre malgré mes recherches sur internet.

    J'ai une fenêtre (classe GestUsers) qui contient un QTableWidget (classe Users) qui me sert à afficher la liste des utilisateurs et leur niveau d'autorisation.
    J'ai ajouté un bouton qui ouvre un QDialog (classe UserCreation) qui sert à créer un nouvel utilisateur.
    Le QTableWidget est alimenté par un pandas dataframe que je stocke dans un fichier.

    Jusque là tout va bien et tout fonctionne.

    Le problème que je rencontre à lieu quand je valide la création d'un utilisateur, une ligne s'ajoute bien à mon QTableWidget et le pandas dataframe se met bien à jour, par contre le contenu des cellules qui ont été ajoutées ne s'affiche pas. Elles restent vides.
    Pour finir de m'achever, quand je quitte ma fenêtre GestUsers et que je la re-ouvre, là le contenu s'affiche correctement.

    J'ai beau m'arracher les derniers cheveux qu'il me reste, impossible de trouver pourquoi l'affichage ne se fait pas correctement tant que je ne quitte pas la fenêtre, d'où mon appel à l'aide.

    Merci par avance.

    Voici le code des différentes classes impliquées.
    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
    class GestUsers(Qt.QWidget):
        """Classe de la fenêtre de gestion des utilisateurs"""
        def __init__(self, parent):
            Qt.QWidget.__init__(self)
     
            self.db = func.open_users_list()
     
            self.parent = parent
            self.frame_users = Users(self.db)
            self.ajouter = Qt.QPushButton("Ajouter")
            self.ajouter.setFixedSize(180, 40)
            self.supprimer = Qt.QPushButton("Supprimer")
            self.supprimer.setFixedSize(180, 40)
            self.quit = Qt.QPushButton("Quitter")
            self.quit.setFixedSize(180, 40)
     
            main_layout = Qt.QVBoxLayout()
            but_layout = Qt.QHBoxLayout()
            main_layout.addWidget(self.frame_users)
            but_layout.addWidget(self.ajouter)
            but_layout.addSpacing(25)
            but_layout.addWidget(self.supprimer)
            but_layout.addSpacing(25)
            but_layout.addWidget(self.quit)
            main_layout.addLayout(but_layout)
            self.setLayout(main_layout)
     
            self.ajouter.clicked.connect(self.create_user_dial)
            self.quit.clicked.connect(self.parent.cancel_param)
     
        def create_user_dial(self):
            self.creation = UserCreation(self)
            self.creation.setWindowModality(QtCore.Qt.ApplicationModal)
            self.creation.show()
    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
    class UserCreation(Qt.QDialog):
        """Fenêtre modale de création d'utilisateur"""
     
        def __init__(self, parent=None):
            Qt.QDialog.__init__(self)
     
            self.parent = parent
            self.db = func.open_users_list()
            self.setWindowTitle("Ajout d'utilisateur")
            self.resize(400, 200)
            self.name_lab = Qt.QLabel("Nom")
            self.name = Qt.QLineEdit()
            self.mdp_lab = Qt.QLabel("Mot de passe")
            self.mdp = Qt.QLineEdit()
            self.mdp.setEchoMode(Qt.QLineEdit.Password)
            self.niveau_lab = Qt.QLabel("Niveau d'autorisation")
            self.niveau = Qt.QComboBox()
            self.niveau.addItems(["Administrateur", "Utilisateur"])
            self.valid = Qt.QPushButton("Valider")
            self.cancel = Qt.QPushButton("Annuler")
     
            main_layout = Qt.QVBoxLayout()
            layout_name = Qt.QHBoxLayout()
            layout_mdp = Qt.QHBoxLayout()
            layout_niveau = Qt.QHBoxLayout()
            layout_buttons = Qt.QHBoxLayout()
     
            layout_name.addWidget(self.name_lab)
            layout_name.addSpacing(52)
            layout_name.addWidget(self.name)
            layout_name.addSpacing(20)
            layout_mdp.addWidget(self.mdp_lab)
            layout_mdp.addSpacing(10)
            layout_mdp.addWidget(self.mdp)
            layout_mdp.addSpacing(20)
            layout_niveau.addWidget(self.niveau_lab)
            layout_niveau.addSpacing(10)
            layout_niveau.addWidget(self.niveau, QtCore.Qt.AlignLeft)
            layout_niveau.addSpacing(150)
            layout_buttons.addWidget(self.valid)
            layout_buttons.addSpacing(25)
            layout_buttons.addWidget(self.cancel)
     
            main_layout.addLayout(layout_name)
            main_layout.addSpacing(10)
            main_layout.addLayout(layout_mdp)
            main_layout.addSpacing(10)
            main_layout.addLayout(layout_niveau)
            main_layout.addSpacing(20)
            main_layout.addLayout(layout_buttons)
     
            self.setLayout(main_layout)
     
            self.valid.clicked.connect(self.on_valid)
            self.cancel.clicked.connect(self.on_cancel)
     
        def on_cancel(self):
            """Fermeture de la fenêtre de création d'utilisateur"""
            self.close()
     
        def on_valid(self):
            user = self.name.text()
            _pass = encryption(self.mdp.text())
            droits = self.niveau.currentText()
            df_new_user = pd.DataFrame({"Nom": [user], "Mot de passe": [_pass], "Droits": [droits]})
     
            if self.db.empty:
                self.add_db(df_new_user)
                self.parent.frame_users.add_row(df_new_user)
            else:
                for idx, val in self.db.iterrows():
                    if val["Nom"] == user:
                        func.mes("Utilisateur déjà existant!", "ERREUR", "critique")
                        return
     
            self.parent.frame_users.add_row(df_new_user)
            self.db = self.db.append(df_new_user)
            func.write_users_list(self.db)
            self.close()
    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
    class Users(Qt.QTableWidget):
        """Classe QTablewidget  de la liste des utilisateurs"""
     
        def __init__(self, data=None):
            Qt.QTableWidget.__init__(self)
     
            self.setEditTriggers(Qt.QTableWidget.NoEditTriggers)
            if data is None:
                self.df = pd.DataFrame()
            else:
                self.df = data
     
            # Dimensionnement du tableau
            self.n_rows, self.n_columns = self.df.shape
            self.setColumnCount(self.n_columns)
            self.setRowCount(self.n_rows)
     
            # data insertion
            for i in range(self.rowCount()):
                for j in range(self.columnCount()):
                    self.setItem(i, j, Qt.QTableWidgetItem(str(self.df.iloc[i, j])))
     
            self.cellChanged[int, int].connect(self.update_df)
     
            # Modification des en-têtes de colonnes pour les faire correspondre aux noms de colonnes du Dataframe
            self.col_names = list(self.df.columns)
            self.str_col_names = ",".join(self.col_names)
     
            words = self.str_col_names.split(",")
            n_words = len(words)
            if n_words > self.columnCount():
                self.setColumnCount(n_words)
            self.setHorizontalHeaderLabels(words)
     
            # Ajustement de la largeur de colonne au contenu des cellules
            self.resizeColumnsToContents()
            self.setColumnHidden(1, True)
     
        def update_df(self, row, column):
            text = self.item(row, column).text()
            self.df.iloc[row, column] = text
     
        def add_row(self, df):
            self.insertRow(self.rowCount())
            row = self.rowCount()
            self.setItem(row, 0, Qt.QTableWidgetItem(str(df.iloc[0, 0])))
            self.setItem(row, 1, Qt.QTableWidgetItem(str(df.iloc[0, 1])))
            self.setItem(row, 2, Qt.QTableWidgetItem(str(df.iloc[0, 2])))
            self.resizeColumnsToContents()

  2. #2
    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
    Bonjour
    Citation Envoyé par jim7963 Voir le message
    Le problème que je rencontre à lieu quand je valide la création d'un utilisateur, une ligne s'ajoute bien à mon QTableWidget et le pandas dataframe se met bien à jour, par contre le contenu des cellules qui ont été ajoutées ne s'affiche pas. Elles restent vides.
    Pour finir de m'achever, quand je quitte ma fenêtre GestUsers et que je la re-ouvre, là le contenu s'affiche correctement.

    J'ai beau m'arracher les derniers cheveux qu'il me reste, impossible de trouver pourquoi l'affichage ne se fait pas correctement tant que je ne quitte pas la fenêtre, d'où mon appel à l'aide.
    J'ai eu un problème analogue sur un projet où une widget affichait le contenu d'une table Postgres et où je voulais pouvoir modifier la bdd via une autre fenêtre et voir les modifs apparaitres immédiatement.
    Quand la sous-fenêtre s'ouvre, elle permet d'ajouter les données mais il n'y a aucun ordre pour dire "recharge la modif" dans la fenêtre principale.

    Pour régler le souci, ce que j'ai fait
    • définir une méthode "load()" dans la fenêtre principale. Cette méthode a pour fonction de charger les datas et les afficher
    • surcharger le slot "showEvent()" qui est automatiquement invoqué chaque fois qu'une widget est affichée. Et dans ce cas, appeler le load() pour charger les datas
    • la fenêtre qui modifie les datas envoie un signal "updated" quand elle se ferme (slot "closeEvent()") et que les datas ont été réellement modifiées en bdd (le signal emporte alors avec lui l'identifiant de l'info qui a été modifiée)
    • connecter dans la fenêtre principale le signal "updated" de ladite fenêtre avec le slot "showEvent" de la fenêtre principale qui peut alors réafficher l'info modifiée


    PS: ton post aurait eu plus de succès dans le sous-forum PyQt dédié à ce sujet et donc fréquenté par une population meilleure que moi dans ce domaine.
    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]

  3. #3
    Membre averti
    Homme Profil pro
    DAF
    Inscrit en
    Août 2020
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : DAF
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2020
    Messages : 12
    Par défaut
    Merci beaucoup pour ta réponse.

    Je m'en vais de ce pas tester tout ça.

Discussions similaires

  1. Réponses: 1
    Dernier message: 31/03/2009, 18h57
  2. problème suite a une mise a jour mysql
    Par fcois93 dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 11/07/2007, 15h46
  3. [FreeBSD] Problème lors d'une mise à jour
    Par gentox dans le forum BSD
    Réponses: 2
    Dernier message: 15/11/2006, 18h44
  4. [GD] Problème avec imagecreatetruecolor() : requiert une mise à jour
    Par arnaud_verlaine dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 10/08/2006, 16h45
  5. Problème d'une mise à jour
    Par Hamdi dans le forum Access
    Réponses: 2
    Dernier message: 17/09/2005, 13h57

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