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 :

PyQt5: Qu'une fenêtre attende la réception d'un paramètre depuis un widget pour exécuter son code


Sujet :

PyQt Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Septembre 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2015
    Messages : 4
    Points : 2
    Points
    2
    Par défaut PyQt5: Qu'une fenêtre attende la réception d'un paramètre depuis un widget pour exécuter son code
    Bonjour,
    Mon programme ouvre une fenêtre principale, et dans la foulée une boite de dialogue qui attend la validation d'un paramètre (str). Une fois ce paramètre obtenu, la boite de dialogue se ferme. J'aimerais ensuite que le code de la fenêtre principale utilise ce paramètre. Avec le code que j'ai écrit, utilisant signal et slot, le code de la fenêtre principale continue à se dérouler bien avant que je reçoive le paramètre, que je ne peux donc pas utiliser. Pour le démontrer, j'ai placé 3 print que j'aimerais voir s'afficher dans l'ordre 1, 2 (validation), 3 (utilisation), mais hélas ils s'affichent 1, 3, 2.
    Je souhaiterais donc que le code de la fenêtre principale se mette en pause jusqu'à réception du paramètre. Merci de 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
    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
     
    from PyQt5.QtWidgets import QMainWindow, QWidget # ,QApplication
    from  PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
    import win_tbite as ihm
    import widg_config
    import serial.tools.list_ports
     
    class myInterface(QMainWindow, ihm.Ui_MainWin):
        '''
        Dessine l'interface graphique principale
        '''
     
        def __init__(self):
            super(myInterface, self).__init__()
            self.setupUi(self)
            self.show()         # ouvre la fenêtre principale
            self.newConnect()
            print('3 port: {}'.format(self.portName)) 
     
        def newConnect(self):
            self.myWidgConf = myFormConfig()
            self.portName = ''
            self.myWidgConf.widgSign.connect(self.recupParam)
            self.myWidgConf.show()
            print('1 port: {}'.format(self.portName)) 
     
        @pyqtSlot('QString')
        def recupParam(self, param):
            '''
            Parameters
            ----------
            param : TYPE str
            DESCRIPTION. le nom du port
            Returns  None.
            -------
            '''
            self.portName = param
            print('2 port: {}'.format(self.portName))
     
        def sendCmd():
            pass
     
        def disConnect():
            pass
     
    class myFormConfig(QWidget, widg_config.Ui_FormConfig):
        '''
        Dessine le formulaire de configuration du port
        '''
        widgSign = pyqtSignal(str)
     
        def __init__(self):
            super(myFormConfig, self).__init__()
            self.setupUi(self)
            self.detectPort()
     
        def detectPort(self):
            ports = serial.tools.list_ports.comports()
            listPorts = []
            listDec = []
            for port, dec, hwid in sorted(ports):
                listPorts.append(port)
                listDec.append(dec)
            for i in range (len(listDec)):
                self.cbPortSelect.addItem(listDec[i])
            self.cbPortSelect.setEditable(False)
            if listPorts != []:
                self.myPort = listPorts[self.cbPortSelect.currentIndex()]
            else:
                self.myPort = ''
     
        def configOk(self):
            '''
            Appelé lors du clic sur le poussoir OK
                    Envoie en signal le nom du port (string)
            '''
            # renvoie le nom du port
            self.widgSign.emit(self.myPort)
            # ferme le widget
            self.close()

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

    C'est toujours difficile de comprendre la conception d'un code écrit par quelqu'un d'autre.

    En tout cas, rien n'empêche d'ouvrir la fenêtre de configuration AVANT la fenêtre principale, et ainsi de lui transmettre le ou les paramètres de configuration dans ses arguments de lancement.

    Pour prendre un autre exemple, on peut saisir une info au clavier avec un QMessageBox, juste après l'activation de la bibliothèque PyQt5 (app=QtWidgets.QApplication(sys.argv)), à condition de mettre "None" en tant que parent. On peut ainsi ouvrir la fenêtre principale en lui passant la donnée comme argument.

    Il y a probablement d'autres solutions, mais il faudrait en connaître plus sur le problème à résoudre.
    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
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Septembre 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2015
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bonjour,
    Citation Envoyé par tyrtamos Voir le message
    C'est toujours difficile de comprendre la conception d'un code écrit par quelqu'un d'autre.
    Bien sûr. Mais comme un code absent est souvent (toujours?) réclamé par les personnes qui répondent, j'ai préféré mettre le mien.

    Citation Envoyé par tyrtamos Voir le message
    En tout cas, rien n'empêche d'ouvrir la fenêtre de configuration AVANT la fenêtre principale, et ainsi de lui transmettre le ou les paramètres de configuration dans ses arguments de lancement.
    Pour prendre un autre exemple, on peut saisir une info au clavier avec un QMessageBox, juste après l'activation de la bibliothèque PyQt5 (app=QtWidgets.QApplication(sys.argv)), à condition de mettre "None" en tant que parent. On peut ainsi ouvrir la fenêtre principale en lui passant la donnée comme argument.
    Oui, mais mon souhait n'est pas de résoudre un problème en le contournant, mais d'apprendre.

    Citation Envoyé par tyrtamos Voir le message
    Il y a probablement d'autres solutions, mais il faudrait en connaître plus sur le problème à résoudre.
    Alors, de ce que je peux voir depuis ces quelques heures où je me penche sur le problème, c'est qu'une de ses solutions serait l'utilisation du threading. N'ayant jamais été jusque là en Python (ni jamais été très loin, d'ailleurs ) je vais essayer à tâtons. Peut-être avez-vous des tuyaux à m'offrir dans ce domaine?
    Merci.

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Au lieu d'un simple widget utilise un QDialog pour ta seconde fenêtre et rend la modale, ainsi ta fenêtre principale attendra le retour du dialogue.

  5. #5
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Septembre 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2015
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bonjour, merci de cette réponse.
    J'ai donc remplacé le widget par une boite de dialogue. Je remarque que 2 choses peuvent être rendues modales:
    - la boite de dialogue (appelée dialConfig), par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dialConfig.setWindowModality(QtCore.Qt.ApplicationModal)
    J'aurais aussi pu la rendre WindowModal.
    - le QDialog, par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dialConfig.setModal(True)
    J'ai rendu modales les 2 propriétés.
    Le code principal n'a pas sensiblement changé par rapport à mon premier post (hormis les noms de fenêtre et l'import de QDialog).
    Je constate que le print n°3 (celui où je suis censé utilisé le paramètre retourné) arrive malheureusement toujours avant le retour effectif du paramètre (print n°2). Donc mon problème reste toujours que le code de ma GUI s'exécute toujours complètement sans attendre la fermeture du dialogue (qui s'effectue correctement après retour du paramètre).
    Pourtant la modalité est effectivement censée bloquer l'exécution de la fenêtre parent. Peut-être que justement, je n'ai pas rendue la fenêtre principale parente de la fenêtre appelée, non? Et si c'est ça que faudrait-il faire?

  6. #6
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Septembre 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2015
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    La solution est énervante tellement elle est simple .
    Mon erreur consistait à poursuivre le cours du programme dans __init__. Celle-ci doit se terminer après l'appel de la méthode qui va ouvrir la boite de dialogue (newConnect). Le programme reprendra à partir de la récupération du paramètre (recupParam). Le print n°3 n'a donc pas lieu d'être, il faut simplement poursuivre à partir du print n°2!
    C'est stupide, je reconnais, ça m'aura permis de changer mon widget en dialogue et de regarder un peu la modalité.
    Merci.

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

Discussions similaires

  1. [XL-2013] Existe-t-il une solution pour indenter son code ?
    Par DenisHen dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 09/04/2021, 12h43
  2. Embarquer une fenêtre dans une fenêtre PyQt5
    Par zsoufianz dans le forum GUI
    Réponses: 2
    Dernier message: 20/02/2017, 15h34
  3. Ajouter une fenêtre externe dans une interface PyQt5
    Par zsoufianz dans le forum Général Python
    Réponses: 2
    Dernier message: 01/02/2017, 00h11
  4. Réponses: 0
    Dernier message: 30/03/2016, 16h21

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