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 QDialog suivi d'une longue opération


Sujet :

PyQt Python

  1. #1
    Membre à l'essai
    Avatar de mazert
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 22
    Points
    22
    Billets dans le blog
    1
    Par défaut Afficher un QDialog suivi d'une longue opération
    Bonjour tous le monde, je suis face à un problème tout bête.

    J'ai une classe MainWindow et une autre Qdialog. Dans une méthode de la fenêtre principale, je déclenche l'ouverture de la fenêtre de dialogue, puis effectue une opération get_proxies de plusieurs minutes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    pu = Loading(parent=self)
    pu.show()
    proxies = ProxiesManager.get_proxies()
    Sauf que l'affichage ne se fait qu'après l’exécution de get_proxies(). Alors après un long travail de recherche, j'ai pu remarquer qu'il faut surcharger la méthode showevent de QDialog, pour y mettre un signal comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Loading(QtGui.QDialog):
     
        dialogShown = QtCore.Signal()
     
        ...
        def showEvent(self, event):
            super(Loading, self).showEvent(event)
            self.dialogShown.emit()
        ...
    et ensuite coté MainWindow, ajouter un connecteur qui exécute la suite des instructions une fois déclenché. Sauf que dans la pratique ça ne fonctionne pas (la fenêtre s'ouvre, mais les actions ne s'effectuent pas ).

    J'aurais espéré une solution simple et élégante au début, peut-être que je m'y prend mal pour ce que je souhaite faire.
    Merci d'avance pour vos solutions.

  2. #2
    Expert éminent

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

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

    Essaye déjà ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    pu = Loading(parent=self)
    pu.show()
    QtCore.QCoreApplication.processEvents()
    proxies = ProxiesManager.get_proxies()
    Mais je te conseille de mettre get_proxies() dans un thread sinon l'appli va se figer.

  3. #3
    Membre à l'essai
    Avatar de mazert
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 22
    Points
    22
    Billets dans le blog
    1
    Par défaut
    Salut,

    Effectivement avec processEvents j'arrive à afficher la fenêtre avant l'opération get_proxies. Le seul problème est que cette fenêtre est vide jusqu'à ce que get_proxies soit terminé :



    Voici comment je construit mon interface pour QDialog (extrait) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    vbox1 = QtGui.QVBoxLayout()
    img_label = QtGui.QLabel("lol")
    img = QtGui.QMovie("media/running_tiger.gif")
    img_label.setMovie(img)
    img_label.setAlignment(QtCore.Qt.AlignCenter)
    img.start()
    message = QtGui.QLabel(
    "Tiger Proxy is downloading proxies across different servers"
    ", please wait a moment ..."
    )
    vbox1.addWidget(img_label)
    vbox1.addWidget(message)
    self.setLayout(vbox1)
    Pour cette version de l'appli je ne souhaite pas encore utiliser de processus (car j'aurais besoin de pouvoir arrêter l'opération get_proxies à la volée, ce que ne permet pas un thread). Ceci dit, si c'est le meilleur moyen de résoudre mon problème alors je commencerais à m'en servir.

  4. #4
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 302
    Points : 6 782
    Points
    6 782
    Par défaut
    Tu peux très bien afficher les proxy au fur et à mesure avec un pyqtSignal et la recherche des proxys peut se faire dans un thread, il n'y a aucun problème pour le stopper en cours de recherche.

    Je ne peut te dire comment faire sans voir comment est codée ta recherche de proxys.

  5. #5
    Membre à l'essai
    Avatar de mazert
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 12
    Points : 22
    Points
    22
    Billets dans le blog
    1
    Par défaut
    D'accord, alors coté architecture on a trois types de composants :
    • Gestionnaire de proxies (unique accès pour la vue à la partie modèle)
    • Fournisseur (extracteur de proxies lié à un service en ligne)
    • Proxy (une entité proxy)


    Quand dans la vue j'appelle get_proxies, le gestionnaire va rechercher à travers l'ensemble des fournisseurs des proxies avec une methode get_proxies
    . Cette méthode va parcourir l'ensemble des pages du serveur en question pour ajouter dans une liste les proxies qu'elle aura trouvé, puis la renvoi.

    Nom : A4xlN44.png
Affichages : 172
Taille : 26,5 Ko

    Coté code, voici ce que contient le get_proxies des fournisseurs, ce n'est pas indiqué sur l'uml mais tous les fournisseurs héritent d'une classe abstraite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def get_proxies(self):
            """ Renvoi l'ensemble des proxies disponibles """
     
            p = self.first_p
            res = []
            while True:
                page = self._get_page(p)
                if self._is_proxy_page(page):
                    proxies = self._extract_proxies(page)
                    res += proxies
                    time.sleep(5)
                    p += 1
                else:
                    return res
    et voici pour la classe de gestionnaire des proxies :
    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
    class ProxiesManager:
        """ Gestionnaire de proxies. Il s'agit de l'unique point d'entrée pour
        accéder aux modèles
        """
     
        _providers = []
     
        @classmethod
        def init_providers(c):
            for name, cls in inspect.getmembers(providers):
                if inspect.isclass(cls) and cls.__module__ == "models.providers":
                    c._providers.append(cls())
     
        @classmethod
        def get_proxies(c):
            """ Renvoi une liste de proxies depuis l'ensemble des fournisseurs """
     
            res = []
            for provider in c._providers:
                res += provider.get_proxies()
            return res

    J’ignorais que l'on pouvait faire passer des données à travers un signal, je pensais me servir des files (queues) pour cela.
    On peut dans ce cas garder l'idée d'ajouter au fur et à mesure les proxies dans le tableau, et dans la boite QDialog ajouter un bouton annuler pour arrêter l'opération. Je souhaite la garder pour y ajouter d'autres informations à l'avenir.

Discussions similaires

  1. Afficher le "temps restant" sur une longue action
    Par illuzmax dans le forum Langage
    Réponses: 2
    Dernier message: 04/07/2005, 10h23
  2. afficher tous les champs d'une table
    Par julio84 dans le forum ASP
    Réponses: 8
    Dernier message: 19/01/2005, 10h31
  3. [CR 10] Afficher un rapport à partir d'une JSP
    Par Crazyblinkgirl dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 07/09/2004, 09h00
  4. Afficher tous les champs d'une table avec dbexpress et MySQL
    Par LHT dans le forum Bases de données
    Réponses: 2
    Dernier message: 25/06/2004, 17h11
  5. Afficher noms des tables d'une base
    Par jeff37 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/01/2004, 16h00

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