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 :

Check box dans une QListWidget et un filtre


Sujet :

PyQt Python

  1. #1
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Février 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Février 2019
    Messages : 9
    Points : 4
    Points
    4
    Par défaut Check box dans une QListWidget et un filtre
    Bonjour,

    Je suis nouveau sur la programmation en PYQT5, ainsi j'aurais aimé une aide,

    je chercher à faire une QListWidget à l’intérieur il y'a que des checkbox, ainsi qu'un filtre qui me permet de faire une recherche parmi les items dans la QListWidget.

    voici le code que j'ai pu faire :

    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
     
     
    import sys
    from PyQt5.QtCore import QDate, QSize, Qt
    from PyQt5.QtGui import *
    from PyQt5 import QtWidgets,QtCore
     
    class Test(QtWidgets.QDialog):
        def __init__(self, parent=None):
            super(Test, self).__init__(parent)
            self.layout = QtWidgets.QVBoxLayout()
            self.listWidget = QtWidgets.QListWidget()
            self.listWidget.itemEntered.connect(lambda item: item.setCheckState(Qt.Checked if item.checkState()==Qt.Unchecked else Qt.Unchecked))
            self.listWidget.setGeometry(QtCore.QRect(10, 10, 211, 291))
            for i in range(10):
                item = QtWidgets.QListWidgetItem("Item %i" % i)
                item.setCheckState(Qt.Unchecked)
                self.listWidget.addItem(item)
            self.listWidget.itemClicked.connect(self.printItemText)
     
            self.layout.addWidget(self.listWidget)
            self.setLayout(self.layout)
     
        def printItemText(self):
            items = self.listWidget.selectedItems()
            print (self.listWidget.itemClicked)
            for i in range(len(items)):
                print (str(self.listWidget.selectedItems()[i].text()))
     
     
     
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        form = Test()
        form.show()
        app.exec_()
    les problèmes auxquels je suis confronté sont:

    -je n'arrive pas à savoir quelle checkbox est sélectionnée, à terme je cherche à remplir une liste avec les items sélectionnées ("il faut prendre en compte ceux qui ont changé d'état")

    -un filtre qui me permet de chercher rapidement un item, IMPOSSIBLE de trouver quoi que ce soit sur internet :/



    je vous remercie d'avance pour vos réponses

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

    Voilà un petit programme de test pour source d'inspiration sur le sujet:

    A noter que la méthode "modifcoche", ne fait qu'afficher en console à chaque modif de la coche d'une case, et ne sert qu'à la mise au point. L'utilisation normale est de rentrer la liste des items au lancement du dialogue, et de sortir la liste modifiée à la fermeture du dialogue.

    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
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
     
    ##############################################################################
    class Test(QtWidgets.QDialog):
     
        #=========================================================================
        def __init__(self, listitems=[], parent=None):
            super().__init__(parent)
     
            self.listWidget = QtWidgets.QListWidget()
     
            for check, item in listitems:
                qitem = QtWidgets.QListWidgetItem()
                qitem.setText(item)
                qitem.setCheckState(QtCore.Qt.Checked if check else QtCore.Qt.Unchecked)
                self.listWidget.addItem(qitem)
     
            # optionnel
            self.listWidget.itemClicked.connect(self.modifcoche)
     
            # crée les boutons pour terminer le dialogue
            boutons = QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel
            self.boutonbox = QtWidgets.QDialogButtonBox(boutons)
            self.boutonbox.accepted.connect(self.accept) # => bouton "Ok"
            self.boutonbox.rejected.connect(self.reject) # => bouton "Annuler"
     
            # positionner les widgets dans la fenêtre de dialogue
            layout = QtWidgets.QGridLayout()
            layout.addWidget(self.listWidget, 0, 0)
            layout.addWidget(self.boutonbox, 1, 0)        
            self.setLayout(layout)
     
        #=========================================================================
        def modifcoche(self, qitem):
            """appelé à chaque modification d'un checkbox avec pour paramètre le 
               QListWidgetItem concerné
            """
            ligne = qitem.listWidget().row(qitem)
            item = qitem.text()
            coche = True if qitem.checkState()==QtCore.Qt.Checked else False        
            print("ligne:", ligne, "item:", item, "=>", coche)
     
        #=========================================================================
        def resultat(self):
            """retourne la liste résultat [[check, item], ...]
            """
            self.result = []
            for i in range(0, self.listWidget.count()):
                qitem = self.listWidget.item(i)
                coche = True if qitem.checkState()==QtCore.Qt.Checked else False
                item = qitem.text()
                self.result.append([coche, item])
            return self.result
     
    ##############################################################################
    if __name__ == "__main__":
     
        app = QtWidgets.QApplication(sys.argv)
     
        # données d'entrée
        listitems = [[True, "item0"], [False, "item1"], [False, "item2"], [True, "item3"], [True, "item4"], ]
     
        # appel dialogue
        form = Test(listitems)
     
        # exécution du dialogue et résultats
        if form.exec_():
            resultat = form.resultat()
            print()
            for check, item in resultat:
                print(check, item)
        else:
            print()
            print("Annulation")

  3. #3
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Février 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Février 2019
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    je vous remercie, cela va beaucoup m'aider, c'est exactement ce que je vaux faire à terme.

    en ce qui concerne les filtres, si tu as des idées n’hésite pas

    MERCI ENCORE

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 478
    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 478
    Points : 9 278
    Points
    9 278
    Billets dans le blog
    6
    Par défaut
    Il faut m’en dire un peu plus sur le filtre que tu veux, et ce que tu veux en faire. Il y a beaucoup de possibilités.

  5. #5
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Février 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Février 2019
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    En fait je chercher a faire une bar de recherche qui me permet de en tapant un début de mot, de sélectionner dans une liste les mots qui correspondent ,

    J'ai trouvé une vidéo sur youtube qui illustre mes propos mais ce n'est pas en python.


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

    Voilà quelques solutions pour la recherche des mots d'une liste satisfaisant une condition.

    D'abord, il y a une fonction à créer pour ne pas tenir compte de la casse (majuscule/minuscules) ni des accents (ici avec unicode uniquement):

    - pour la casse: on fait les comparaisons en mettant en majuscules le mot et la cible avec la méthode ".upper()".

    - pour les accents, on utilise:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    from unicodedata import normalize, combining
     
    def supaccents(chaine):
        """Supprime les accents de la chaine de caractères (unicode uniquement)
           utilise normalize et combining du module unicodedata
        """
        chnorm = normalize('NFKD', chaine)
        return "".join([car for car in chnorm if not combining(car)])
    Pour l'exemple, on va chercher dans une liste de prénoms comme (j'ai cherché dans https://nominis.cef.fr/contenus/pren...betique/A.html):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    liste = ["Adèle", "Béatrice", "Candice", "Delphine", "Eléanor", "Fabien", "Gérard", "Hélène"]
    Et voilà quelques solutions de recherche:

    1- Recherche des mots de la liste commençant par la cible

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    cible = "elea"
     
    cible = supaccents(cible.upper())
    for mot in liste:
        if supaccents(mot.upper()).startswith(cible):
            print(mot)
    # résultat: Eléanor
    2- Recherche des mots de la liste contenant la cible

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    cible = "elea"
     
    cible = supaccents(cible.upper())
    for mot in liste:
        if cible in supaccents(mot.upper()):
            print(mot)
    # résultat: Eléanor
    3- Recherche des mots de la liste satisfaisant un motif 'wildcard'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    from fnmatch import fnmatchcase
     
    cible = "*ean*"
     
    cible = supaccents(cible.upper())
    for mot in liste:
        if fnmatchcase(supaccents(mot.upper()), cible):
            print(mot)
    # résultat: Eléanor
    4-Recherche des mots de la liste satisfaisant un motif 'expression régulière'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import re
     
    cible = r"^.*ea.*or$"
     
    cible = supaccents(cible)
    regex = re.compile(cible, re.IGNORECASE)
    for mot in liste:
        if regex.match(supaccents(mot))!=None:
            print(mot)
    # résultat: Eléanor
    5- Recherche des mots de la liste ressemblant à la cible (avec un ratio mini de ressemblance)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from difflib import SequenceMatcher
     
    cible = "leanar"
    ratio = 0.75
     
    cible = supaccents(cible.upper())
    for mot in liste:
        if SequenceMatcher(None, supaccents(mot.upper()), cible).ratio() >= ratio:
            print(mot)
    # résultat: Eléanor
    Il n'y a plus qu'à choisir la méthode qui convient le mieux à ton problème...

  7. #7
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Février 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Février 2019
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Un très grand merci à vous,

    J'ai réussi à trouvé ce que je cherchais, j'ai même pu trouver une façon simple de faire un filtre avec textChanged.connect et setHidden .


    Merci encore

  8. #8
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Février 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Février 2019
    Messages : 9
    Points : 4
    Points
    4
    Par défaut Petite Problématique
    Bonjour,

    je fais face à une autre problématique, je m'explique:

    -j'ai une Class A dans la quelle j'ai une fenêtre qui va être remplie par l’utilisateur avec un bouton qui permet de sauvegarder les informations

    -j'ai une Classe B dans la quelle je veux faire une boucle for (ou une autre facon de faire) qui va récupérer les information de la Classe A

    j'ai tout essayé mais rien à faire , je n'arrive pas à faire en sorte que dans la boucle for il attend que le bouton de la classe A doit actionné pour passer à la suivante :/, j'ai même essayé du threading, cependant j'ai la fenêtre de la Class A qui bug au moment du wait()


    Le threading en question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result_available = threading.Event()

    Voila la Class A

    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
    class Proprietes_Remplissage(QMainWindow):
        fermeture_fenetre=QtCore.pyqtSignal(object)    #le signal du bouton 
        def __init__(self):
            super(Proprietes_Remplissage, self).__init__()
            uic.loadUi("%s/Proprietes_Remplissage.ui"%direction, self)
     
            self.Sortie=None
        def lancement_du_remplissage(self,prop,Base=None):
     
            self.name=prop
            self.label.setText(self.name)
            if self.name=="Sy":
                self.tableWidget_remp.setColumnCount(len(["Temperature"]+Base.index.tolist()))
                self.pushButton.clicked.connect(partial(self.Remplissage,["Temperature"]+Base.index.tolist()))
                self.tableWidget_remp.setHorizontalHeaderLabels(["Temperature"]+Base.index.tolist())
            else:
                self.tableWidget_remp.setColumnCount(len(["Temperature"]+Base["Nuance"].unique().tolist()))
                self.pushButton.clicked.connect(partial(self.Remplissage,["Temperature"]+Base["Nuance"].unique().tolist()))
                self.tableWidget_remp.setHorizontalHeaderLabels(["Temperature"]+Base["Nuance"].unique().tolist())
            self.tableWidget_remp.setRowCount(50)  
     
            self.show()   # j'affiche la fenêtre 
     
     
        def Remplissage(self,Base_col):
     
            temp_dic={}
            for i in Base_col:
                temp_dic[i]=[]
            for i in range(50):
                for icol,col in enumerate(Base_col):
                    try: 
                        temp_dic[col].append(self.tableWidget_remp.item(i,icol).text())
                        if self.tableWidget_remp.item(i,0).text()=="" and i==0:
                            self.showDialog("la temperature de la 1er ligne n'est pas remplie !!!")
                            return
                    except:
                        break
            self.Sortie=pd.DataFrame(temp_dic)
            self.Sortie.set_index("Temperature",inplace=True)
            self.fermeture_fenetre.emit(self.Sortie) #j'envoie l'object
            self.close()      #je ferme la fenêtre

    La Class B:
    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
    class Controller() :
     
    #Fonctions supprimées pour plus de clarté 
     
        def phase_remplissage(self,tmp):      #Fonction qui nous intéresse
     
            for i in self.prop_rempli:  #self.prop_rempli est une liste, je ne connais pas sa longueur par avance entre 2 et 5
                self.app=Proprietes_Remplissage()
                thread=threading.Thread(self.app.lancement_du_remplissage(i,self.Base_Final))
                thread.start()
                result_available.wait()  #Arrivé ici un fenetre s'ouvre et bug, je ne peux que tuer l'application
     
        def remplissage_sorties(self,Sortie): #fonction qui me permet de sauvgarder les information de la classe A
            result_available.set()             #c'est censé faire en forte que la boucle for avance d'un pas! comme le bouton de la Class A a ete appuyé 
            self.Sorties.append(Sortie)
            self.app.close()
            print(self.Sorties)

    je sais que c'est difficile de imaginer la fichier en entier mais j'ai supprimé des choses inutiles pour une meilleur lisibilité!,

    je vous remercie par avance

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

    Je ne suis pas sûr d'avoir bien compris les opérations, mais je peux suggérer les points suivants:

    - les graphiques fonctionnent par évènements: il y a une boucle (le "app.exec_()") qui attend un signal d'évènement (souris, clavier, réseau, etc...) et le traite au fur et à mesure. Aussi, si une fenêtre veut signaler à une autre qu'une donnée est disponible, il lui suffit d'envoyer un signal, et la fenêtre qui doit le recevoir, le reçoit et fait ce qu'elle doit faire. Il existe des signaux déjà prévus (voir la doc), mais on peut en créer de nouveaux. On peut même faire porter les données disponibles par ce signal spécifique, ce qui simplifie grandement le procédé.

    - Pour les mêmes raisons, il ne faut pas prévoir de ligne d'attente comme .wait ou .join, car le graphique est alors gelé. On peut éventuellement faire une boucle d'attente en attendant une condition, mais il faut "redonner la main" au traitement des évènements du graphique à chaque tour de boucle avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QtCore.QCoreApplication.processEvents()
    - les threads sont utiles quand une opération, un calcul par exemple, est longue et risque de geler le graphique trop longtemps. Mais les threads ne doivent pas toucher le graphique (sinon => bug)! En PyQt5, il est intéressant d'utiliser QThread de PyQt5 au lieu de threading, parce que l'émission d'un signal est alors facile, tant pendant le déroulement du thread qu'à sa fin. Pour faire la même chose avec threading, on peut faire une classe qui hérite en même temps de threading et de QObject (héritage multiple).

  10. #10
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Février 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Février 2019
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Bonjour,

    Déjà un grand merci pour vos réponse,

    Pour expliquer mieux ce que je veux faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for iter in range (5):
    
        #je lance une fenêtre avec un bouton et une table
        #je remplis la table avec des valeurs
        #je clique sur le bouton pour m'envoyer les données de la table et ferme en meme temps fenêtre 
        #une fois le bouton cliqué la boucle for continue (iter=iter+1), donc une nouvelle fenêtre s'ouvre avec une table et un bouton
    Apres des longues recherches sur internet je commence à comprendre le QThread, cependant j'ai rien compris sur QCoreApplication.processEvents().

    pourriez vous me donner des exemples parceque sur internet je ne trouve pas grandes choses, ou je ne sais pas bien chercher !

  11. #11
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 478
    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 478
    Points : 9 278
    Points
    9 278
    Billets dans le blog
    6
    Par défaut
    Bonjour (et bonne année!)

    Pour voir comment on peut utiliser les signaux pour communiquer des données, voilà un petit code de test:

    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
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
     
    import sys
    from PyQt5 import QtCore, QtWidgets
     
    #############################################################################
    class Fenetre2(QtWidgets.QWidget):
     
        # crée un nouveau signal de fermeture qui portera la donnée de retour 
        fermeturefen2 = QtCore.pyqtSignal(str)
     
        #========================================================================
        def __init__(self, parent=None):
            super().__init__(parent)
     
            self.setWindowTitle("Fenêtre 2")
            self.resize(400, 300)
     
            # crée une ligne d'édition
            self.edit = QtWidgets.QLineEdit()
     
            # positionne le QLineEdit dans la fenêtre
            layout = QtWidgets.QGridLayout()
            layout.addWidget(self.edit, 0, 0)
            self.setLayout(layout)
     
        #========================================================================
        def closeEvent(self, event):
            """à la fermeture de cette fenêtre 2, celle-ci envoie un signal à la 
               fenêtre 1 appelante avec la donnée de retour
            """
            # émet le signal avec le contenu du QLineEdit
            self.fermeturefen2.emit(self.edit.text()) 
            # et accepte la fermeture de cette fenêtre
            event.accept()
     
    #############################################################################
    class Fenetre1(QtWidgets.QWidget):
     
        #========================================================================
        def __init__(self, parent=None):
            super().__init__(parent)
     
            self.setWindowTitle("Fenêtre 1")
            self.resize(300, 200)
     
            # crée un bouton
            self.bouton = QtWidgets.QPushButton("Lancer une 2ème fenêtre!", self)
            self.bouton.clicked.connect(self.appelfen2)
     
            # positionne le bouton dans la fenêtre
            layout = QtWidgets.QGridLayout()
            layout.addWidget(self.bouton, 0, 0)
            self.setLayout(layout)
     
            # initialise la variable qui portera la fenetre 2
            self.fenetre2 = None
     
        #========================================================================
        def appelfen2(self):
            """méthode appelée par le bouton, Lance une deuxième fenêtre
            """
            if self.fenetre2 is not None:
                # une fenêtre 2 est déjà ouverte: on ne fait rien!
                return
            else:            
                # lance la fenêtre 2
                self.fenetre2 = Fenetre2()
                # prépare la fin de la fenêtrre 2 pour recevoir ses données 
                self.fenetre2.fermeturefen2.connect(self.fen2close)
                # affiche cette 2ème fenêtre
                self.fenetre2.show()
     
        #========================================================================
        def fen2close(self, texte):
            """méthode appelée par la fermeture de la fenêtre 2
            """
            # coupure du lien avec le signal
            self.fenetre2.fermeturefen2.disconnect()
            # on garde l'info d'une fenêtre 2 non affichée
            self.fenetre2 = None
            # on affiche la donnée de retour de la fenêtre 2
            print("retour fenêtre 2:", texte)
     
        #========================================================================
        def closeEvent(self, event):
            """méthode appelée lors de la fermeture de la fenêtre 1
            """
            if self.fenetre2 is not None:
                # => une fenêtre 2 est encore ouverte
                # coupure du lien avec le signal
                self.fenetre2.fermeturefen2.disconnect()
                # fermeture de la fenêtre 2
                self.fenetre2.close()
                print("Fenêtre 2 fermée mais donnée perdue")
            print("Fenêtre 1 fermée")
            # accepte la fermeture de la fenêtre 1
            event.accept()    
     
    #############################################################################
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        fenetre1 = Fenetre1()
        fenetre1.show()
        sys.exit(app.exec_()) #<===  boucle de traitement des évènements
    Pour ce qui concerne le ".processEvents()":
    Imaginons que nous ayons un thread qui fait un calcul long, et qui, quand il a fini, place le résultat dans une variable globale "resultat" initialisé avant par "None".
    Pour que le graphique sache quand un résultat est disponible, la bonne solution est pour le thread d'envoyer un signal, mais si ce n'est pas possible, on pourrait faire ceci dans le code du graphique qui a lancé le thread:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while resultat is none:
        pass
    Mais il y a un os: pendant l'exécution de la boucle, le graphique est figé (comme si on avait utilisé ".join"())! Alors, on fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while resultat is none:
        QtCore.QCoreApplication.processEvents()
    Ce qui fait qu'à chaque tour de boucle, on donne la possibilité au graphique de traiter les évènements en attente (clavier, souris, etc...) et ce graphique attend donc sans être figé.
    Ce n'est pas une très bonne solution (celle avec les signaux est bien meilleure), mais elle marche!

    ok?

  12. #12
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Février 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Février 2019
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Bonjour, et bonne année

    Merci pour votre explication, j'ai mieux compris les signaux, cependant je ne pense pas que cela va etre applicable à mon cas :/

    Comme j'ai essayais d'expliquer (j'ai du mal à l'expliquer) c'est de pouvoir faire un QThread qui permet de lancer une fenêtre, j'ai essayé de m'exercer mais je pense que je me prends hyper mal :

    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
    import sys
    import time
     
    from PyQt5.QtCore import (QCoreApplication, QObject, QRunnable, QThread,
                              QThreadPool, pyqtSignal)
    from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QTextEdit,QAction, QTableWidget,QTableWidgetItem,QVBoxLayout,QMessageBox,QMenu
    from PyQt5 import uic,QtCore,QtWidgets,QtGui
    import sys
    import os
     
    direction=os.path.dirname(os.path.abspath( __file__ ))
     
    class Proprietes_Remplissage(QMainWindow,QObject):
        fermeture_fenetre=QtCore.pyqtSignal(object)
        def __init__(self):
            super(Proprietes_Remplissage, self).__init__()
            super().__init__()
     
     
        def lancement_du_remplissage(self,prop="",Base=None):
            uic.loadUi("%s/Proprietes_Remplissage.ui"%direction, self)
     
            self.Sortie=None        
            self.name=prop
            self.label.setText(self.name)
     
            #QCoreApplication.processEvents()
            self.pushButton.clicked.connect(self.close_app)
            self.show()
       def close_app(self):
            print("je ferme l'application")
                self.fermeture_fenetre.emit()
     
     
     
     
     
     
     
    def using_q_thread(txt=""):
        app = QApplication(sys.argv)
        obj = Proprietes_Remplissage()  
        thread = QThread()  
        obj.moveToThread(thread)
        obj.fermeture_fenetre.connect(thread.quit) 
        thread.started.connect(obj.lancement_du_remplissage) 
        app.exec_()
     
     
    if __name__ == "__main__":
        for i in ["A","B","C"]:
            using_q_thread(i)
            print(i)

    cependant je tombe sur une erreur :
    QObject::moveToThread: Widgets cannot be moved to a new thread
    je sais que je me prends mal, mais bon je fais de mon mieux.

    Pourriez vous m'orienter vers une méthode pour m’avancer dans la résolution de mon problème .


    Merci Beaucoup

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

    Citation Envoyé par R2D2 le vrai Voir le message
    cependant je ne pense pas que cela va etre applicable à mon cas :/
    La communication par signaux fait tellement partie des bases de fonctionnement des graphiques que ça m'étonnerait. Mon code test n'a fait que traiter un des cas possibles (à la fermeture d'une fenêtre), mais on peut envoyer des signaux à n'importe quel moment, y compris pendant l'exécution d'un thread (avec QThread), dès lors que ça a un sens dans le déroulement des opérations.

    Citation Envoyé par R2D2 le vrai Voir le message
    c'est de pouvoir faire un QThread qui permet de lancer une fenêtre
    Mais j'ai dit plus haut que le thread (y compris QThread) ne devait pas toucher au graphique! On dit que le graphique n'est pas "thread-safe" (voir: https://fr.wikipedia.org/wiki/Thread_safety). L'utilisation "normale" d'un thread ici est de faire des calculs longs "non-graphiques" et de renvoyer les résultats au graphique avec des signaux.

    Il me semble cependant avoir vu des cas où c'était possible, mais cela ajoute des complexités inutiles. Si on veut lancer une fenêtre qui possède sa propre boucle de traitement des évènements, afin de saisir des données, autant lancer une fenêtre QDialog!

  14. #14
    Candidat au Club
    Femme Profil pro
    Analyste d'exploitation
    Inscrit en
    Février 2019
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Février 2019
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Bonjour,

    J'ai bien relu ce vous avez écrit, et vous aviez raison, je me suis bien sorti avec les signaux

    Je vous remercie énormément

Discussions similaires

  1. [XL-2003] Check Box dans une cellule
    Par juju1988 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 13/09/2010, 11h59
  2. Réponses: 15
    Dernier message: 01/07/2008, 15h12
  3. [JTable] Check Box dans une cellule
    Par kkajout dans le forum Composants
    Réponses: 4
    Dernier message: 19/05/2008, 10h55
  4. Check box dans une JTable
    Par Mischka dans le forum Composants
    Réponses: 1
    Dernier message: 24/07/2007, 13h58
  5. inclure un check box dans une table
    Par krikete13 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 03/06/2007, 13h46

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