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 :

[Phonon] Python.exe ne se ferme plus


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 de base de données
    Inscrit en
    Mars 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2012
    Messages : 17
    Par défaut [Phonon] Python.exe ne se ferme plus
    Bonjour,

    J'utilise un objet Phonon.VideoPlayer dans une fenêtre.
    Lorsque je ferme la dernière fenêtre, l'application lance bien le signal aboutToQuit, il retourne un code à 0 pour le exec_(), l'exécution se poursuit bien après le exec_() mais python.exe ne rend pas la main.
    Y-a-t-il un outil permettant de savoir ce qui bloque ?

    Script de lancement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import sys
    from core import mApp
     
    if __name__ == "__main__":
        try:
            app = mApp.Application(sys.argv)
            retcode = app.exec_()
            print("FIN {0}".format(retcode))
        except:
            pass
    Classe QApplication (core/mApp.py) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Application(QtGui.QApplication):
        def __init__(self, argv):
            super(Application, self).__init__(argv)
            self.aboutToQuit.connect(self._terminate)
    ...
        def _terminate(self):
            print("TERMINATE")
    Résultat :
    Merci par avance pour vos lumières.

  2. #2
    Expert confirmé

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Essayes avec closeAllWindows()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            self.aboutToQuit.connect(self.closeAllWindows)
    En regardant la doc, il y a diverses façons de clore, selon le nombre de fenêtre, ... Faut tester.

    T'as essayé sys.exit() à la fin du script de lancement, normalement ce n'est pas nécessaire, mais si c'est juste Python qui ne rend pas la main, p'têtre que ça aidera.

  3. #3
    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 ne comprend pas la ligne "from core import mApp" qui génère une erreur chez moi, mais il me semble qu'il y a redondance entre "app = mApp.Application(sys.argv)" et la classe qui dérive de QtGui.QApplication

    Voilà un petit exemple minimum qui montre comment je structure habituellement mes applications (Python 2.7, PyQt4):

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import sys
    from PyQt4 import QtCore, QtGui
    from PyQt4.phonon import Phonon
     
    class Fenetre(QtGui.QWidget):
        def __init__(self, url, parent = None):
            super(Fenetre, self).__init__(parent)
            self.resize(800,600)
     
            self.player = Phonon.VideoPlayer(Phonon.VideoCategory, self)
            media = Phonon.MediaSource(url)
            self.player.play(media)
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.player, 0, 0)
            self.setLayout(posit)
     
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre("mavideo.avi")
        fen.show()
        sys.exit(app.exec_())

  4. #4
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Mars 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2012
    Messages : 17
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Essayes avec closeAllWindows()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            self.aboutToQuit.connect(self.closeAllWindows)
    Le problème ne vient pas de là, l'application PyQt se termine bien comme en témoigne le "FIN 0" dans la trace.

    Citation Envoyé par VinsS Voir le message
    T'as essayé sys.exit() à la fin du script de lancement, normalement ce n'est pas nécessaire, mais si c'est juste Python qui ne rend pas la main, p'têtre que ça aidera.
    Oui oui, j'ai essayé au départ je faisais un sys.exit(app.exec_()).

    Citation Envoyé par tyrtamos Voir le message
    Je ne comprend pas la ligne "from core import mApp" qui génère une erreur chez moi
    Normal, il s'agit d'un module à moi. J'ai modifié mon post pour clarifier.
    J'ai créé une classe Application qui dérive de QApplication.
    Citation Envoyé par tyrtamos Voir le message
    mais il me semble qu'il y a redondance entre "app = mApp.Application(sys.argv)" et la classe qui dérive de QtGui.QApplication
    Non, mApp.Application est la classe qui dérive de QApplication.

    Ce qui est bizarre, c'est que le côté PyQt se termine, mais python n'arrive pas à s'arrêter ...

  5. #5
    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 trouve étrange d'utiliser une classe qui dérive de QApplication. Je n'ai encore pas vu cela dans les exemples.

    La logique qu'on voit est (cf mon exemple):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    app = QtGui.QApplication(sys.argv)
    fen = Fenetre()
    fen.show()
    sys.exit(app.exec_())
    Et la boucle de traitement est donnée par "app.exec_()".

  6. #6
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Mars 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2012
    Messages : 17
    Par défaut
    Bon finalement j'ai laissé tombé Phonon qui de toute façon ne répondait pas à mon besoin puisque étant limité aux codecs installés.
    Je suis passé sur mPlayer en backend et ça marche plutôt bien.
    Je suis parti sujet trouvé sur un autre site et l'ai adapté à Python 3 et PyQt4.
    Pour ceux que ça pourrait intéresser :
    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
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    import os
    import time
     
    from PyQt4 import QtCore, QtGui
     
    #----------------------------------------------------------------------------
    # CLASSE      : VideoPlayer
    # HERITAGE    : QFrame
    # DESCRIPTION : Classe permettant de piloter mPlayer.
    #----------------------------------------------------------------------------
    class VideoPlayer(QtGui.QFrame):
        #------------------------------------------------------------------------
        # CONSTRUCTEUR
        # PARAMETRES : wParent     : Objet parent (QFrame).
        #              mPlayerPath : Chemin du binaire mPlayer.
        #------------------------------------------------------------------------
        def __init__(self, wParent, mPlayerPath):
            super(VideoPlayer, self).__init__()
            self.setAttribute(QtCore.Qt.WA_PaintOnScreen)
            self.__isPlaying = False
            self.__isPaused = False
            self.__mPlayerPath = mPlayerPath
            self.__mPlayerProcess = QtCore.QProcess(self)
            self.__poller = QtCore.QTimer(self)
            self.__videoWidth = 0
            self.__videoHeight = 0
            self.__slider = None
            self.__isResizing = False
            grid = QtGui.QGridLayout(self)
            self.__target = QtGui.QWidget()
            grid.setColumnStretch(0, 1)
            grid.setColumnStretch(2, 1)
            grid.setRowStretch(0, 1)
            grid.setRowStretch(2, 1)
            grid.addWidget(self.__target, 1, 1)
            self.connect(self.__mPlayerProcess, QtCore.SIGNAL('readyReadStandardOutput()'), self._catchOutput)
            self.connect(self.__mPlayerProcess, QtCore.SIGNAL('finished(int, QProcess::ExitStatus)'), self._mPlayerEnded)
            self.connect(self.__poller, QtCore.SIGNAL('timeout()'), self._pollCurrentTime)
        #------------------------------------------------------------------------
        # METHODE     : load
        # PORTEE      : PUBLIQUE
        # DESCRIPTION : Arrête la lecture en cours et charge une nouvelle vidéo.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def load(self, videoPath):
            self.stop()
            self.__videoPath = videoPath
        #------------------------------------------------------------------------
        # METHODE     : pause
        # PORTEE      : PUBLIQUE
        # DESCRIPTION : Met en pause.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def pause(self):
            if self.__isPlaying == True:
                self.__isPaused = not self.__isPaused
                self.__mPlayerProcess.write('pause\n')
        #------------------------------------------------------------------------
        # METHODE     : play
        # PORTEE      : PUBLIQUE
        # DESCRIPTION : Lance la lecture.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def play(self, rotate='none'):
            if not self.__isPlaying:
                if not self._startMPlayer(rotate):
                    return
                self.__isPlaying = True
                self.__isPaused = False
        #------------------------------------------------------------------------
        # METHODE     : seek
        # PORTEE      : PUBLIQUE
        # DESCRIPTION : Repositionne la lecture dans la vidéo.
        # PARAMETRES  : pos : position en secondes.
        #------------------------------------------------------------------------
        def seek(self, pos):
            self.__mPlayerProcess.write('seek {0} 2\n'.format(pos))
        #------------------------------------------------------------------------
        # METHODE     : setPosSlider
        # PORTEE      : PUBLIQUE
        # DESCRIPTION : Indique le slider à utiliser pour la position.
        # PARAMETRES  : slider : objet QSlider.
        #------------------------------------------------------------------------
        def setPosSlider(self, slider):
            self.__slider = slider
            self.connect(self.__slider, QtCore.SIGNAL('sliderMoved(int)'), self.seek)
        #------------------------------------------------------------------------
        # METHODE     : stop
        # PORTEE      : PUBLIQUE
        # DESCRIPTION : Arrête la lecture.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def stop(self):
            if not self._stopMPlayer():
                return
            self.__poller.stop()
            self.__isPlaying = False
            self.__isPaused = False
        #------------------------------------------------------------------------
        # METHODE     : _adjustSize
        # PORTEE      : PRIVEE
        # DESCRIPTION : Ajuste la taille du widget en fonction de la taille de la
        #               vidéo.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def _adjustSize(self):
            if self.__videoWidth == 0 or self.__videoHeight == 0:
                self.__target.setFixedSize(1, 1)
                return
            if self.__isResizing == True:
                return
            self.__isResizing = True
            margins = self.contentsMargins()
            frameWidth = self.width() - margins.left() - margins.right()
            frameHeight = self.height() - margins.top() - margins.bottom()
            if self.__videoWidth > (frameWidth - 20):
                targetWidth = frameWidth - 20
                targetHeight = int(targetWidth * self.__videoHeight / self.__videoWidth)
            else:
                targetWidth = self.__videoWidth
                targetHeight = self.__videoHeight
            if targetHeight > (frameHeight - 20):
                targetHeight = frameHeight - 20
                targetWidth = int(targetHeight * self.__videoWidth / self.__videoHeight)
            self.__target.setFixedSize(targetWidth, targetHeight)
            self.__isResizing = False
        #------------------------------------------------------------------------
        # METHODE     : _catchOutput
        # PORTEE      : PRIVEE
        # DESCRIPTION : Analyse les données retournées par le processus mPlayer.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def _catchOutput(self):
            while self.__mPlayerProcess.canReadLine():
                buff = QtCore.QByteArray(self.__mPlayerProcess.readLine())
                # Résolution
                if buff.startsWith("ANS_VIDEO_RESOLUTION"):
                    buff.remove(0, 21)
                    buff.replace(QtCore.QByteArray("'"), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray(" "), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray("\n"), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray("\r"), QtCore.QByteArray(""))
                    sepIndex = buff.indexOf('x')
                    if self.__rotate == False:
                        self.__videoWidth = buff.left(sepIndex).toInt()[0]
                        self.__videoHeight = buff.mid(sepIndex+1).toInt()[0]
                    else:
                        self.__videoWidth = buff.mid(sepIndex+1).toInt()[0]
                        self.__videoHeight = buff.left(sepIndex).toInt()[0]
                    self._adjustSize()
                # Durée de la vidéo
                elif buff.startsWith("ANS_LENGTH"):
                    buff.remove(0, 11)
                    buff.replace(QtCore.QByteArray("'"), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray(" "), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray("\n"), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray("\r"), QtCore.QByteArray(""))
                    maxTime = buff.toFloat()[0]
                    if self.__slider is not None:
                        self.__slider.setMaximum(maxTime + 1)
                # Position
                elif buff.startsWith("ANS_TIME_POSITION"):
                    buff.remove(0, 18)
                    buff.replace(QtCore.QByteArray("'"), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray(" "), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray("\n"), QtCore.QByteArray(""))
                    buff.replace(QtCore.QByteArray("\r"), QtCore.QByteArray(""))
                    currTime = buff.toFloat()[0]
                    if self.__slider is not None:
                        self.__slider.setValue(currTime + 1)
        #------------------------------------------------------------------------
        # METHODE     : _mPlayerEnded
        # PORTEE      : PRIVEE
        # DESCRIPTION : Fin de la lecture.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def _mPlayerEnded(self, exitCode, exitStatus):
            self.__isPlaying = False
            self.__isPaused = False
            self.__poller.stop()
            self.__videoWidth = 0
            self.__videoHeight = 0
            self._adjustSize()
            if self.__slider is not None:
                self.__slider.setValue(0)
                self.__slider.setMaximum(0)
        #------------------------------------------------------------------------
        # METHODE     : _pollCurrentTime
        # PORTEE      : PRIVEE
        # DESCRIPTION : Recherche la position courante.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def _pollCurrentTime(self):
            self._adjustSize()
            if self.__isPaused == False:
                self.__mPlayerProcess.write('get_time_pos\n')
        #------------------------------------------------------------------------
        # METHODE     : _startMPlayer
        # PORTEE      : PRIVEE
        # DESCRIPTION : Lance le processus mPlayer.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def _startMPlayer(self, rotate='none'):
            if self.__isPlaying == True:
                return True
            self.__width = 0
            self.__height = 0
            self._adjustSize()
            args = ['-slave', '-quiet', '-wid', str(int(self.__target.winId()))]
            if os.name in ['posix', 'mac']:
                args.extend(['-vo', 'x11'])
            # Sous windows
            elif os.name=='nt':
                args.extend(['-vo', 'gl'])
            if rotate != 'none':
                args.extend(['-vf', 'rotate={}'.format(rotate)])
                self.__rotate = True
            else:
                self.__rotate = False
            args.append(self.__videoPath)
            self.__mPlayerProcess.setProcessChannelMode(QtCore.QProcess.MergedChannels)
            self.__mPlayerProcess.start(self.__mPlayerPath, args)
            if not self.__mPlayerProcess.waitForStarted(3000):
                return False
            self.__mPlayerProcess.write('get_video_resolution\n')
            self.__mPlayerProcess.write('get_time_length\n')
            self.__poller.start(250)
            self.__isPlaying = True
            return True
        #------------------------------------------------------------------------
        # METHODE     : _stopMPlayer
        # PORTEE      : PRIVEE
        # DESCRIPTION : Arrête le processus mPlayer.
        # PARAMETRES  : (NEANT)
        #------------------------------------------------------------------------
        def _stopMPlayer(self):
            self.__videoWidth = 0
            self.__videoHeight = 0
            self._adjustSize()
            if self.__slider is not None:
                self.__slider.setValue(0)
                self.__slider.setMaximum(0)
            if self.__mPlayerProcess.state() == QtCore.QProcess.NotRunning:
                return True
            if self.__isPlaying == False:
                return True
            self.__mPlayerProcess.write('quit\n')
            if not self.__mPlayerProcess.waitForFinished(3000):
                return False
            return True

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

Discussions similaires

  1. Une fenêtre qui ne se ferme plus !
    Par colorid dans le forum Langage
    Réponses: 2
    Dernier message: 07/04/2011, 19h18
  2. Python.exe a rencontré un problème
    Par Chris33 dans le forum Général Python
    Réponses: 5
    Dernier message: 08/05/2010, 13h06
  3. Réponses: 1
    Dernier message: 02/12/2008, 23h55
  4. Réponses: 4
    Dernier message: 08/09/2006, 11h20
  5. (VB6) - Message Outlook (2003) ne se ferme plus
    Par jlvalentin dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 01/12/2005, 10h55

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