Partage
  • Partager sur Facebook
  • Partager sur Twitter

Télécharger fichier avec QT

problèmes de signaux/slots

    14 novembre 2011 à 11:44:23

    Hello !
    Alors voilà je suis en train de coder un petit programme pour télécharger des fichiers mais j'ai un soucis : Je n'arrive pas à connecter mes signaux et mes slots.
    Dans le code ci-dessous je devrais avoir "haha", "bonjour", ainsi que le contenu du fichier qui s'affichent dans la console quand on clique sur télécharger. En réalité, je n'ai que "haha".
    Est-ce qu'une âme charitable peut m'aider ?

    Voilà le code simplifié de mon programme :
    #!/usr/bin/env python
    # - encoding: utf8 - 
    from PyQt4 import QtGui, QtCore, QtNetwork
    import sys, os
    
    class QVK(QtGui.QMainWindow):
        def __init__(self):
            super(QVK, self).__init__()
            self.result = False
            self.settings = QtCore.QSettings(QtCore.QString("QVK"), QtCore.QString("QVK"))
    
        def initUI(self):
            ## First launch widget
            if not self.settings.value("firstLaunch").toBool():
                self.settings.setValue("firstLaunch", False)
                
            ## Init widget
            zoneCentrale = QtGui.QWidget()
            layout = QtGui.QVBoxLayout(zoneCentrale)
            self.setCentralWidget(zoneCentrale)
            
            ## Create download button
            self.downloadButton = QtGui.QPushButton(u'Télécharger')
            layout.addWidget(self.downloadButton)
            
            ## Connect buttons to functions
            self.connect(self.downloadButton, QtCore.SIGNAL('clicked()'), self.downloadClicked)
        
        def downloadClicked(self):
            Downloader("/tmp/ls-lR.gz","http://mirror.switch.ch/ftp/ubuntu/ls-lR.gz")
            
    class Downloader(QtGui.QWidget):
        def __init__(self, filePath, url):
            QtGui.QWidget.__init__(self)
            self.filePath = filePath
            self.url = url
            self.progressDialog = QtGui.QProgressDialog(self)
            self.progressDialog.setLabelText("Downloading %s..." % (os.path.basename(filePath)))
            self.progressDialog.show()
            self.download()
        
        def download(self):
            print "haha"
            self.manager = QtNetwork.QNetworkAccessManager()
            self.reply = self.manager.get(QtNetwork.QNetworkRequest(QtCore.QUrl(self.url)))
            self.connect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.downloadProgress)
            self.connect(self.manager, QtCore.SIGNAL("finished(QNetworkReply *)"), self.replyFinished)
    
        def downloadProgress(self, bytesReceived, bytesTotal):
            print "bonjour"
            self.progressDialog.setMaximum(bytesTotal)
            self.progressDialog.setValue(bytesReceived)
        
        def replyFinished(self, reply):
            reponse = reply.readAll()
            print reponse
            
    app = QtGui.QApplication(sys.argv)
    qvk = QVK()
    qvk.initUI()
    qvk.show()
    sys.exit(app.exec_())
    
    • Partager sur Facebook
    • Partager sur Twitter
      14 novembre 2011 à 13:06:56

      Bonjour, je n'ai pas trop le temps de pencher sur ton code, j'éditerai mon post par la suite.


      class Downloader(QtGui.QWidget):
          def __init__(self, filePath, url):
              QtGui.QWidget.__init__(self)
              self.filePath = filePath
              self.url = url
              self.progressDialog = QtGui.QProgressDialog(self)
              self.progressDialog.setLabelText("Downloading %s..." % (os.path.basename(filePath)))
              self.progressDialog.show()
              self.download()
          
          def download(self):
              print "haha"
              self.manager = QtNetwork.QNetworkAccessManager()
              self.reply = self.manager.get(QtNetwork.QNetworkRequest(QtCore.QUrl(self.url)))
              self.connect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.downloadProgress)
              self.connect(self.manager, QtCore.SIGNAL("finished(QNetworkReply *)"), self.replyFinished)
      
          def downloadProgress(self, bytesReceived, bytesTotal):
              print "bonjour"
              self.progressDialog.setMaximum(bytesTotal)
              self.progressDialog.setValue(bytesReceived)
      



      A priori, tu n'émets pas un signal, mais tu veux exécuter une fonction seulement si la barre de progression progresse :)
      self.connect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.downloadProgress)
      


      or ta fonction downloadProgress(qint64, qint64) ne sera jamais appelée vu qu'elle est à zéro.
      • Partager sur Facebook
      • Partager sur Twitter
        14 novembre 2011 à 13:37:56

        Hello merci pour ta réponse :)

        Citation : realmagma


        A priori, tu n'émets pas un signal, mais tu veux exécuter une fonction seulement si la barre de progression progresse :)

        self.connect(self.reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"), self.downloadProgress)
        



        or ta fonction downloadProgress(qint64, qint64) ne sera jamais appelée vu qu'elle est à zéro.



        Oui c'est bien ça je veux que ma fonction self.downloadProgress soit appelée lorsque le signal émi par self.reply (de la classe QtNetwork.QNetworkReply) change. Ce signal est sensé changer constemment puisqu'il contient la progression actuelle du téléchargement. Du coup je ne comprends pas pourquoi sa valeur reste à 0.

        C'est pareil pour mon deuxième signal. Il est sensé être émi par self.manager (de la classe QtNetwork.QNetworkAccessManager) lorsque le téléchargement est terminé. Si il n'est pas émi c'est que le téléchargement ne se termine pas, ce qui ne devrait pas arriver.
        • Partager sur Facebook
        • Partager sur Twitter
          14 novembre 2011 à 14:44:20

          Dans ce cas là je te conseille d'émettre tes propres signaux, en utilisant "emit".
          Pour ce faire, je t'oriente vers ce tutoriel (dans la partie suivante: Créer son propre signal) Voici un autre lien intéressant.


          Exemple d'utilisation tiré de: Pierre Puiseux-UPPA, Tutoriel PyQt-4-Signaux et Slots:

          #Dans le slot changerLargeur, Il suffit de tester si la largeur est maximum (600), et d'émettre alors un signal.
          def changerLargeur(self,largeur):
              if largeur==600:
                  self.emit(SIGNAL("largeurMax(int)"), largeur)
              self.setFixedSize(largeur,self.height())
          



          Le signal largeurMax(int) emit prend un entier en argument : largeur. Les signaux se présentent en pratique sous forme de
          méthodes (comme les slots). Un signal peut passer un ou plusieurs paramètres.

          Définition d'un slot


          Dans la classe MaFenetre, une simple méthode définit l'action à entreprendre lorsqu'est émis le signal largeurMax(int)
          def action(self,l):
              exit()
          


          Connection a un slot


          Reste maintenant à connecter l'émission du signal largeurMax(int) au slot self.action nouvellement définit, c'est aussi simple que
          d'habitude :
          self.connect(self,SIGNAL("largeurMax(int)"),self.action)
          



          Les signaux et les slots, c'est vraiment ce qui fait la force de Qt et PyQt... mais ses détracteurs disent que c'est une erreur d'avoir voulu
          "modifier" le langage C++. En effet, la compilation est plus lourde car il y a des étapes de pré-compilation à effectuer impérativement si on
          veut que le code soit compilable. C'est un point de vue qui se défend.
          L'avantage de ce système, et ça personne ne le discute, c'est qu'il est robuste. On dispose d'une extraordinaire souplesse pour faire
          communiquer des objets entre eux :
          • Un signal peut appeler le slot d'un autre objet pour l'informer d'un évènement.
          • Un signal peut appeler plusieurs slots d'objets différents si nécessaire pour faire plusieurs traitements.
          • Un signal peut être connecté à un autre signal directement, qui lui-même peut être raccordé à un autre signal (réaction en chaîne) ou
          appeler un slot.
          • La connexion entre un signal et un slot permet d'échanger un ou plusieurs paramètres.
          • L'échange de paramètres entre le signal et le slot est sécurisé : Qt vérifie que la signature du signal correspond bien à celle du slot.
          • Partager sur Facebook
          • Partager sur Twitter
            14 novembre 2011 à 15:51:28

            Oui j'ai déjà utilisé emit et je comprends son fonctionnement (enfin je crois) mais dans ce cas précis, je ne vois vraiment pas où je pourrais le placer puisque je n'ai aucune information concernant l'état du téléchargement en cours. C'est sensé être le rôle des classes QNetworkAccessManager et QNetworkReply de gérer l'état du téléchargement.

            Ce qui est étrange c'est que ce code fonctionne alors que j'utilise exactement le même mécanisme. C'est l'ancienne version du programme, avant que je décide de créer une classe Downloader.

            #!/usr/bin/env python
            # - encoding: utf8 - 
            from PyQt4 import QtGui,QtCore,QtNetwork
            import sys, os
            
            import urllib2
            import hashlib
            from lxml import etree
            import xml.dom.minidom
            import urllib
            from optparse import OptionParser
            import time
            
            class QVK(QtGui.QMainWindow):
                def __init__(self):
                    super(QVK, self).__init__()
                    self.result = False
                    self.settings = QtCore.QSettings(QtCore.QString("QVK"),QtCore.QString("QVK"))
                    self.initUI()
                    
            
                def initUI(self):
                    ## First launch widget
                    if not self.settings.value("firstLaunch").toBool():
                        self.settings.setValue("firstLaunch",False)
                        
                    ## Init widget
                    self.showMaximized()
                    zoneCentrale = QtGui.QWidget()
                    layout = QtGui.QVBoxLayout(zoneCentrale)
                    self.setCentralWidget(zoneCentrale)
            
                    ## Create download button
                    self.downloadButton = QtGui.QPushButton(u'Télécharger')
                    layout.addWidget(self.downloadButton)
                    
                    ## Connect buttons to functions
                    self.connect(self.downloadButton, QtCore.SIGNAL('clicked()'),self.downloadClicked)
                def downloadClicked(self):
                   listOfRows = []
                   i=0
                   self.progressDialog = QtGui.QProgressDialog()
                   self.progressDialog.show()
                   self.download(['','','','http://mirror.switch.ch/ftp/ubuntu/ls-lR.gz'])
                   time.sleep(2)
                   self.progressDialog.close()
                   
                def download(self, song):
                    downloadDirectory =  self.settings.value("downloadDirectory").toString()
                    manager = QtNetwork.QNetworkAccessManager(self)
                    self.connect(manager, QtCore.SIGNAL("finished(QNetworkReply*)"), self.replyFinished)
                    reply = manager.get(QtNetwork.QNetworkRequest(QtCore.QUrl(song[3])))
                    self.connect(reply, QtCore.SIGNAL("downloadProgress(qint64, qint64)"),self.downloadProgress)
                    
                def downloadProgress(self, bytesReceived, bytesTotal):
                    print int(float(bytesReceived)/float(bytesTotal)*100)
                    self.progressDialog.setMaximum(bytesTotal)
                    self.progressDialog.setValue(bytesReceived)
                    
                def replyFinished(self,reply):
                    print reply.readAll()
            
            app = QtGui.QApplication(sys.argv)
            qvk = QVK()
            qvk.show()
            
            sys.exit(app.exec_())
            
            • Partager sur Facebook
            • Partager sur Twitter

            Télécharger fichier avec QT

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown