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 :

Afficher un GIF dans QLabel via QMovie


Sujet :

PyQt Python

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 10
    Par défaut Afficher un GIF dans QLabel via QMovie
    Bonjour,

    je devellope une application en pyQt4 et j'aimerais lors d'une opération de compression plutôt longue afficher un throbber (gif de chargement) pour montrer à l'utilisateur qu'une action est en cours. J'ai lu pas mal de topic sur le sujet et impossible d'afficher mon gif.
    Si quelqu'un a des idées, je suis preneur.

    Voici mon code :

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtGui, QtCore
    import os,tarfile
     
    ######################### Boite de Dialogue ##################################
    class compressWin(QtGui.QWidget):
     
        def __init__(self,parent,saveName,action):
            super(compressWin, self).__init__()
     
            # compression Thread
            self.thread = compressThread(self,saveName,action)
            self.thread.tick.connect(self.close)
            self.thread.start()
     
            #label
            if action == 'c':
                self.label=QtGui.QLabel('Compression en cours...')
            elif action == 'x':
                self.label=QtGui.QLabel('Extraction en cours..')
     
     
            # set up the movie screen on a label
            self.movie_screen = QtGui.QLabel()
            self.movie_screen.setStyleSheet("background-color:yellow; border: 1px solid  #ff0000 ;")
     
            # resize and center the label
            self.movie_screen.resize(QtCore.QSize(80, 80))
            self.movie_screen.setAlignment(QtCore.Qt.AlignCenter)
     
            #set layout
            main_layout = QtGui.QVBoxLayout()
            main_layout.addWidget(self.label)
            main_layout.addWidget(self.movie_screen)
     
            self.setLayout(main_layout)
            # use an animated gif file
            movie = QtGui.QMovie(parent.AbsPath+"/throbber2.gif", QtCore.QByteArray('gif'),self.movie_screen)
            movie.setCacheMode(QtGui.QMovie.CacheAll)
            movie.setSpeed(1)
            self.movie_screen.setMovie(movie)
            movie.start()
     
            #position et nom fenetre
            self.setGeometry(300,300,100,100)
            self.setWindowTitle('Compresion en cours')
            self.setWindowIcon(QtGui.QIcon(parent.AbsPath+'/img/pasta.png'))
     
    ######################### Thread de compression ################################
    class compressThread(QtCore.QThread):
        tick = QtCore.pyqtSignal() #New style signal
        #Instanciation de la classe compressThread
        #L'objet parent doit être passé en paramètre
        #Strategy est un paramètre optionnel, permet de définir un comportement
        def __init__(self, parent, fName,action):
            QtCore.QThread.__init__(self,parent)
            self.fname = fName
            self.action = action
     
        def run(self):
            if self.action == 'c':
                with tarfile.open(self.fname, "w:gz") as tar:
                    tar.add('/tmp/PASTA')
     
            elif self.action == 'x':
                with tarfile.open(self.fname) as tar:
                    tar.extractall('/')
     
            self.sleep(1)
            self.tick.emit()
    Merci par avance.

  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 m'étais intéressé à ça il y a quelques temps, et j'utilise maintenant couramment un throbber.

    Voir mon tuto:

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

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 10
    Par défaut
    Merci j'avais déjà vu votre tuto. Cependant, il ne m'a pas aidé car j'utilise pyQt4, et pas pyQt5. Toutefois j'avais essayé de le reproduire, mais sans succès.

  4. #4
    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
    Concernant le 1er code du tuto, il est facile de convertir en PyQt4 la version PyQt5: il suffit de changer les instructions d'importation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    from PyQt4.QtCore import Qt, QSize, pyqtSlot, pyqtSignal, QThread
    from PyQt4.QtGui import QMovie, QApplication, QWidget, QPushButton, QLabel, QGridLayout

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 10
    Par défaut
    Le fait est que ca ne marche pas. Ceci dit, j'ai réussi a contourner le problème en créant l'animation moi meme. Ma fenêtre lance un thread qui périodiquement envoie un signal au parent pour que celui ci mette a jour l'image. C'est pas hyper propre, mais ca marche et ca me convient xD

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtGui, QtCore
    import os,tarfile,time
     
    ######################### Boite de Dialogue ##################################
    class compressWin(QtGui.QWidget):
     
        def __init__(self,parent,saveName,action):
            super(compressWin, self).__init__()
            self.parent = parent
            self.i=1
            # # compression Thread
            self.thread = compressThread(self,saveName,action)
            self.thread.tick.connect(self.close)
            self.thread.start()
     
            #thread d'animation
            self.animThread = animateThread(self)
            self.animThread.tick.connect(self.animate)
            self.animThread.start()
     
            #label
            if action == 'c':
                self.label=QtGui.QLabel('Compression en cours...')
            elif action == 'x':
                self.label=QtGui.QLabel('Extraction en cours..')
     
     
            # set up the movie screen on a label
            self.movie_screen = QtGui.QLabel()
     
            # resize and center the label
            self.movie_screen.resize(QtCore.QSize(80, 80))
            self.movie_screen.setAlignment(QtCore.Qt.AlignCenter)
            self.picture = QtGui.QImage(self.parent.AbsPath+"/img/throbber/frame-"+str(self.i)+".gif")
            pixmap = QtGui.QPixmap.fromImage(self.picture)
            pixmap_resized = pixmap.scaled(80, 80, QtCore.Qt.KeepAspectRatio)
            self.movie_screen.setPixmap(pixmap_resized)
     
            #set layout
            main_layout = QtGui.QVBoxLayout()
            main_layout.addWidget(self.label)
            main_layout.addWidget(self.movie_screen)
     
            self.setLayout(main_layout)
     
            #position et nom fenetre
            self.setGeometry(300,300,100,100)
            self.setWindowIcon(QtGui.QIcon(parent.AbsPath+'/img/pasta.png'))
     
        def animate(self):
            self.picture = QtGui.QImage(self.parent.AbsPath+"/img/throbber/frame-"+str(self.i)+".gif")
            pixmap = QtGui.QPixmap.fromImage(self.picture)
            pixmap_resized = pixmap.scaled(80, 80, QtCore.Qt.KeepAspectRatio)
            self.movie_screen.setPixmap(pixmap_resized)
     
        def closeEvent(self,event):
            event.ignore()
            self.thread.terminate()
            self.animThread.terminate()
            event.accept()
     
    ######################### Thread de compression ################################
    class compressThread(QtCore.QThread):
        tick = QtCore.pyqtSignal()
        #Instanciation de la classe compressThread
        #L'objet parent doit être passé en paramètre
        #Strategy est un paramètre optionnel, permet de définir un comportement
        def __init__(self, parent, fName,action):
            super(compressThread, self).__init__()
            self.fname = fName
            self.action = action
     
        def run(self):
            if self.action == 'c':
                with tarfile.open(self.fname, "w:gz") as tar:
                    tar.add('/tmp/PASTA')
     
            elif self.action == 'x':
                with tarfile.open(self.fname) as tar:
                    tar.extractall('/')
     
            self.sleep(2)
            self.tick.emit()
     
    class animateThread(QtCore.QThread):
        tick = QtCore.pyqtSignal()
        #Instanciation de la classe compressThread
        #L'objet parent doit être passé en paramètre
        #Strategy est un paramètre optionnel, permet de définir un comportement
        def __init__(self, parent):
            super(animateThread, self).__init__()
            self.parent = parent
     
        def run(self):
            while True:
                self.parent.i=(self.parent.i)%18+1
                self.tick.emit()
                time.sleep(0.1)

  6. #6
    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
    Ce n'est pas possible que ça ne marche pas, puisque j'ai vérifié l'exécution lorsque j'ai fait la modif PyQt4 avant de la publier ici. Mais tu es peut-être en Python 2?

    Je viens de revérifier et revoilà le code complet en Python 3 PyQt4:

    Il faut, bien sûr un gif appelé ici "throbbergif.gif"

    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
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    # Python 3
     
    import sys, os
    import time
     
    from PyQt4.QtCore import Qt, QSize, pyqtSlot, pyqtSignal, QThread
    from PyQt4.QtGui import QMovie, QApplication, QWidget, QPushButton, QLabel, QGridLayout
     
    #############################################################################
    class Calcul(QThread):
     
        # crée un nouveau signal pour indiquer la fin du thread
        finduthread = pyqtSignal()
     
        #========================================================================
        def __init__(self, parent=None):
            super(Calcul, self).__init__(parent)
     
        #========================================================================
        def run(self):
            # tempo de 5 secondes pour l'exemple
            time.sleep(5)
            # émet le signal de fin du thread
            self.finduthread.emit()
     
    #############################################################################
    class Fenetre(QWidget):
     
        #========================================================================
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
            self.resize(400, 300)
     
            # crée le bouton qui lancera le thread
            self.bouton = QPushButton("Lancer le programme!", self)
            self.bouton.clicked.connect(self.lancementprogramme)
     
            # crée un movie avec le throbber sous forme d'image "gif" animée
            imagif = os.path.abspath("throbbergif.gif")
            self.movie = QMovie(imagif)
            self.movie.setScaledSize(QSize(60, 60))  # dimension 60x60
     
            # crée du QLabel pour intégrer le throbber
            self.label = QLabel()
            # redimenssionne 80x80
            self.label.resize(QSize(80, 80))
            # interdit le redimenssionnement à la souris
            self.label.setFixedSize(self.label.width(), self.label.height())
            # option: met un fond jaune et un cadre rouge
            self.label.setStyleSheet("background-color:yellow; border: 1px solid  #ff0000 ;")
            # le contenu du QLabel sera au milieu (hor. et vert.)
            self.label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
     
            # positionne les widgets dans la fenêtre
            posit = QGridLayout()
            posit.addWidget(self.bouton, 0, 0, 1, 3)
            posit.addWidget(self.label, 1, 1, 1, 1)
            self.setLayout(posit)
     
            self.thread = None  # signale qu'il n'y a aucun thread en cours
     
        #========================================================================
        @pyqtSlot()
        def lancementprogramme(self):
            """slot exécuté lors du clic sur le bouton: lance le thread
            """
            if self.thread != None:
                return  # = il y a déjà un thread en cours: on ne fait rien
     
            # affiche le throbber
            self.label.setMovie(self.movie)  # affecte le movie au QLabel
            self.movie.start()  # lance l'animation du throbber
     
            # lance le thread
            self.thread = Calcul()
            self.thread.finduthread.connect(self.findeprogramme)
            self.thread.start()
     
        #========================================================================
        @pyqtSlot()
        def findeprogramme(self):
            """slot exécuté lors de la clôture du thread
            """
            # arrête l'affichage du throbber
            self.movie.stop()  # arrête l'animation
            self.label.clear()  # efface le contenu du QLabel
     
            # traite la fin du thread
            self.thread.finduthread.disconnect()  # retire le lien avec la méthode
            self.thread = None  # signale qu'il n'y a plus de thread en cours
     
    #############################################################################
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())

  7. #7
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 10
    Par défaut
    Oui python 2.7.11. C'est l'environnement de toute les machines ou seront déployées mon appli.

  8. #8
    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
    A ma grande surprise, mon code marche aussi sous Python 2.7 sans modification.

Discussions similaires

  1. [MySQL] Afficher une IMAGE dans une BDD via PHP
    Par lothar59 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 07/01/2011, 15h17
  2. [Flex4] Afficher details dans accordeon via bouton dun datagrid
    Par TOTOTAR dans le forum Flex
    Réponses: 0
    Dernier message: 15/08/2010, 21h10
  3. Réponses: 4
    Dernier message: 09/05/2010, 19h01
  4. afficher les images dans un email via outlook est possible
    Par kaayna dans le forum Webmarketing
    Réponses: 4
    Dernier message: 23/02/2010, 21h17
  5. Comment afficher une image 'gif' dans une interface
    Par LMU2S dans le forum Interfaces Graphiques
    Réponses: 1
    Dernier message: 17/03/2008, 10h31

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