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 :

Gui ne s'affiche pas [QtGui]


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2011
    Messages : 27
    Par défaut Gui ne s'affiche pas
    Salut à tous, je me mets au python et pour cela j'ai décidé de faire un babyphone sous raspberry + écran tactile.
    Je voudrais que ma fille puisse appeler les numéro de sa mère ainsi que le mien et qu'elle puisse répondre aux appels.
    J'utilise pour ce faire PJSIP et Pyqt5 en m'inspirant des examples de PJSIP j'ai fait le code suivant.
    Le fonctionnement souhaité est le suivant programme doit enregistrer un compte SIP se mettre à l'écoute et mettre à jour l'IHM lors d'un appel afin que ma fille puisse répondre en cliquant sur un bouton.
    De plus elle doit à parti de l'IHM pouvoir interagir avec le compte SIP afin de passer des appels à 2 numéros pré-configurés.
    L'IHM seule fonctionne et le compte sip aussi mais je n'arrive pas à lier les deux, j'ai entendu parler de threading mais j'ai du mal à appliquer ce concept si une bonne âme pouvais m'aider.
    Merci d'avance.
    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
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
     
        import os
        import sys
        import pjsua as pj
        import threading
        import signal
        import datetime
        from time import sleep
        from PyQt5 import QtCore, QtGui, QtWidgets
     
        LOG_LEVEL=3
     
     
        current_call = None
        lib = None
        acc = None
     
        # Logging callback
        def log_cb(level, str, len):
            print str,
     
        class Ui_MainWindow(object):
            def setupUi(self, MainWindow):
                MainWindow.setObjectName("MainWindow")
                MainWindow.setEnabled(True)
                MainWindow.resize(640, 480)
     ....
                MainWindow.setCentralWidget(self.centralwidget)
                self.menubar = QtWidgets.QMenuBar(MainWindow)
                self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 20))
                self.menubar.setObjectName("menubar")
                MainWindow.setMenuBar(self.menubar)
     
                self.retranslateUi(MainWindow)
                QtCore.QMetaObject.connectSlotsByName(MainWindow)
     
            def retranslateUi(self, MainWindow):
                _translate = QtCore.QCoreApplication.translate
                self.answBtn.setText(_translate("MainWindow", "Answ"))
                self.hangUpBtn.setText(_translate("MainWindow", "Hang"))
                self.dadBtn.setText(_translate("MainWindow", "Dad"))
                self.mumBtn.setText(_translate("MainWindow", "Mum"))
     
                self.answBtn.clicked.connect(self.Answer)
                self.hangUpBtn.clicked.connect(self.Hang)
                self.dadBtn.clicked.connect(self.DialDad)
                self.mumBtn.clicked.connect(self.DialMum)
     
            def Answer(self):
                if not current_call:
                    print "There is no call"
                else:
                    current_call.answer(200)
                    self.signLbl.setText(str('talking to ' + uri))
     
            def Hang(self):
                if not current_call:
                    print "There is no call"
                else:
                    current_call.hangup()
                    self.signLbl.setText("")
     
            def DialDad(self):
                self.make_call('uri:dad number')
                self.signLbl.setText("Dialing Dad ! ! !")
     
            def DialMum(self):
                self.make_call('uri:mum number')
                self.signLbl.setText("Dialing Mum ! ! !")
     
        def signal_handler(signal, frame):
            if acc is not None:
                acc.delete()
                acc = None
            if lib is not None:
                lib.destroy()
                lib = None
            sys.exit(0)
     
        # Callback to receive events from account
        class MyAccountCallback(pj.AccountCallback):
            sem = None
     
            def __init__(self, account=None):
                pj.AccountCallback.__init__(self, account)
     
            # Notification on incoming call
            def on_incoming_call(self, call):
                global current_call 
                if current_call:
                    call.answer(486, "Busy")
                    return
     
                print "Incoming call from ", call.info().remote_uri
     
                current_call = call
     
                call_cb = MyCallCallback(current_call)
                current_call.set_callback(call_cb)
                current_call.answer(180)
     
            def wait(self):
                self.sem = threading.Semaphore(0)
                self.sem.acquire()
     
            def on_reg_state(self):
                print "Registration complete, status=", self.account.info().reg_status, "(" + self.account.info().reg_reason + ")"
                if self.sem:
                    if self.account.info().reg_status >= 200:
                        self.sem.release()
     
        # Callback to receive events from Call
        class MyCallCallback(pj.CallCallback):
     
            def __init__(self, call=None):
                pj.CallCallback.__init__(self, call)
     
            # Notification when call state has changed
            def on_state(self):
                global current_call
                print "Call with", self.call.info().remote_uri,
                print "is", self.call.info().state_text,
                print "last code =", self.call.info().last_code,
                print "(" + self.call.info().last_reason + ")"
                if self.call.info().state == pj.CallState.DISCONNECTED:
                    current_call = None
                    print 'Current call is', current_call
     
            # Notification when call's media state has changed.
            def on_media_state(self):
                global lib
                if self.call.info().media_state == pj.MediaState.ACTIVE:
                    # Connect the call to sound device
                    call_slot = self.call.info().conf_slot
                    lib.conf_connect(call_slot, 0)
                    lib.conf_connect(0, call_slot)
                    print "Media is now active"
                else:
                    print "Media is inactive"
     
        # Function to make call
        def make_call(uri):
            try:
                print "Making call to", uri
                return acc.make_call(uri, MyCallCallback())
            except pj.Error, e:
                print "Exception: " + str(e)
                return None
     
        # Create library instance
        lib = pj.Lib()
     
        try:
            # Init library with default config and some customized
            # logging config.
            lib.init(log_cfg = pj.LogConfig(level=LOG_LEVEL, callback=log_cb))
     
            # Create UDP transport which listens to any available port
            transport = lib.create_transport(pj.TransportType.UDP)
            print "\nListening on", transport.info().host,
            print "port", transport.info().port, "\n"
     
            # Start the library
            lib.start()
     
            # Create account
            acc_cfg = pj.AccountConfig()
            print pj.AccountConfig()
            acc_cfg.id = 'sip:ID'
            acc_cfg.reg_uri = 'sip:Registrar'
            print acc_cfg.reg_uri
            acc_cfg.auth_cred = [ pj.AuthCred('*', 'ID', 'PW') ]
            print acc_cfg.auth_cred
            acc_cfg.reg_timeout = 1800
            acc_cb = MyAccountCallback()
            acc = lib.create_account(acc_cfg, cb=acc_cb)
            acc_cb.wait()
     
            # If argument is specified then make call to the URI
            if len(sys.argv) > 1:
                lck = lib.auto_lock()
                current_call = make_call(sys.argv[1])
                print 'Current call is', current_call
                del lck
     
            my_sip_uri = "sip:" + transport.info().host + \
                         ":" + str(transport.info().port)
            print my_sip_uri
     
            signal.signal(signal.SIGINT, signal_handler)
            signal.pause()
     
            acc.delete()
            acc = None
            lib.destroy()
            lib = None
     
        except pj.Error, e:
            print "Exception: " + str(e)    
            if acc is not None:
                acc.delete()
                acc = None
            if lib is not None:
                lib.destroy()
                lib = None
     
     
        if __name__ == "__main__":
            import sys
            app = QtWidgets.QApplication(sys.argv)
            MainWindow = QtWidgets.QMainWindow()
            ui = Ui_MainWindow()
            ui.setupUi(MainWindow)
            MainWindow.show()
            sys.exit(app.exec_())

  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,

    Je n'ai pas spécialement regardé les 200 lignes de ton code, mais le problème que tu poses est assez général: si dans un programme graphique on lance une tâche longue, le graphique est figé pendant son exécution. La raison en est simple: pour ne pas se figer, le programme graphique doit avoir sa "boucle de traitement des évènements" toujours en état de fonctionnement.

    La méthode classique pour échapper à ça est d'exécuter cette tâche longue dans un thread, c'est à dire de façon asynchrone.

    Avec PyQt5, comme avec la plupart des autres bibliothèques graphiques, il y a une contrainte à respecter: ce qui s'exécute dans un thread ne doit pas toucher directement au graphique! Couramment, la communication entre le thread et le programme principal (partie graphique) se fait par échange de signaux, ces signaux pouvant d'ailleurs porter des données python. Pour permettre les échanges par signaux, il vaut mieux utiliser directement QThread de PyQt au lieu de threading.

    A titre d'exemple, voir mon tuto pour intégrer un "throbber" (une roue qui tourne):

    http://python.jpvweb.com/python/mesr...pyqt5_throbber

    Voir aussi à la fin de l'excellent cours de Swinnen, le chapitre qui parle de "multithreading":

    https://python.developpez.com/cours/apprendre-python3/

  3. #3
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2011
    Messages : 27
    Par défaut Résolu
    Un GRAND merci à ceux qui ont répondu (@Tyrtamos surtout) j'ai résolu le problème en séparant le traitement (lancement d'un thread avec instanciation de la librairie SIP) de l'affichage.
    Maintenant je charge l'IHM en parallèle de l'initialisation du SIP.
    Ceux qui sont intéressé peuvent m'envoyer un mp pour le code car il serait un peu long de tout affiché.

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

Discussions similaires

  1. [JTable] les noms des colonnes de s'affichent pas
    Par macben dans le forum Composants
    Réponses: 6
    Dernier message: 25/04/2008, 11h03
  2. GUI Java par netbeans - ne s'affiche pas
    Par G_angel dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 31/01/2007, 11h38
  3. Le résultat de Print ne s'affiche pas...
    Par Red Bull dans le forum Langage
    Réponses: 9
    Dernier message: 15/06/2006, 18h56
  4. Les classes ne s'affichent pas
    Par karl3i dans le forum MFC
    Réponses: 8
    Dernier message: 26/01/2004, 14h52
  5. [MFC] Ces fenêtres qui ne s'affichent pas..
    Par Davide dans le forum MFC
    Réponses: 3
    Dernier message: 19/11/2003, 11h30

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