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

wxPython Discussion :

Thread et création de fenêtres


Sujet :

wxPython

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut Thread et création de fenêtres
    Bonjour à tous,

    Je planche sur un grand programme qui travaille avec IRC sans aucun module pré-conçu. Mais ce n'est pas cette partie qui pose problème mais la partie graphique.

    Mon application est faite de deux threads: le principal qui fait tourner le MainLoop de mon interface et l'autre qui gère la connexion IRC. Dès qu'un message privé arrive je dois ouvrir une fenêtre contenant le message avec le pseudo de la personne.

    Cependant, la création de la fenêtre fonctionne sauf que elle est bloquée/gelée (sablier et "ne répond pas"). Par contre les autres fenêtres ne sont pas bloquées, elles fonctionnent et les autres évenements attaché à IRC continue de fonctionner correctement. D'après moi le problème vient du thread car mes autres fenêtres sont créées directement dans mon wx.Frame, de plus j'ai créé le script sans thread et ça fonctionne.

    J'ai réussi à reproduire ceci dans un petit exemple:
    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
     
     
    import wx
    import threading
    from time import sleep
     
    class Bonjour(wx.Frame):
        def __init__(self, titre):
            wx.Frame.__init__(self, None, -1, title = titre, size = (200, 100))
            self.conteneur = wx.Panel(self, -1, size = self.GetClientSize())
            self.etiquette = wx.StaticText(self.conteneur, -1, "Bonjour tout le monde !", style = wx.ALIGN_CENTRE)
     
            self.etiquette.CentreOnParent()
            wx.EVT_SIZE(self, self.OnSize)
     
        def OnSize(self, evt):
            self.SetTitle("Exemple %s" % evt.GetSize())
            self.conteneur.SetSize(self.GetClientSize())
            self.etiquette.CentreOnParent()
     
    class MonApp(wx.App):
        def OnInit(self):                
            #fen2 = Bonjour("Exemple 3")
            #fen2.Show(True)
            #self.SetTopWindow(fen2)
            (threading.Thread(None, Launch, None, (), {'frame':self})).start()
            return True
     
    def Launch(frame):
        i=0
        while (True):
            if (i == 10): #Lorsqu'un message arrive
                fen = Bonjour("Exemple 1")
                fen.Show(True)
                frame.SetTopWindow(fen)
            i+=1
     
    app = MonApp()
    app.MainLoop()
    Comment feriez vous à ma place ? Surtout qu'il faut imaginer un programme beaucoup plus complexe dans Launch() car c'est là que dans mon programme je traite tous les messages IRC (les pings notamment etc...).
    J'ai failli oublier: L'appel de la fenêtre est faite dans une boucle while comme ici, est-ce que cela peut venir de ça ?

    Merci d'avance et bonne journée

  2. #2
    Membre expérimenté Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Points : 1 728
    Points
    1 728
    Par défaut
    Je n'ai pas de reponse à te donner mais ce lien explique l'utilisation des threads avec wx.
    if you do decide to use threads in your application, it is strongly recommended that no more than one thread calls GUI functions. The thread sample shows that it is possible for many different threads to call GUI functions at once (all the threads created in the sample access GUI), but it is a very poor design choice for anything except an example. The design which uses one GUI thread and several worker threads which communicate with the main one using events is much more robust and will undoubtedly save you countless problems (example: under Win32 a thread can only access GDI objects such as pens, brushes, &c created by itself and not by the other threads).
    Bonne lecture.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Points : 139
    Points
    139
    Par défaut
    Bonjour,

    oui, travailler avec l'API graphique en dehors de la thread main pose des problèmes. Heureusement, avec CallAfter on peut poster une commande pour qu'elle soit exécutée à l'intérieur de la thread main.
    wx.CallAfter(fen.Show,True)
    a la place the fen.Show(True)
    devrait faire l'affaire (il faut peut etre aussi le faire avec settopwindow?)

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut
    Bonjour,

    Merci beaucoup pour vos réponses à vous deux.
    J'ai lu et compris qu'il y avait des threads directement fait pour wxPython, ça peut être intéressant, si je peux utiliser ceux-ci en modifiant un minimum de code (car il est long) et comme dans mon exemple ci-dessus le Mainloop occupe le premier thread, or je pense que mettre cette boucle dans un thread n'arrange pas l'affaire (et ainsi utiliser le thread principal pour mon long code). Je ne sais pas ce que je peux faire donc ?

    Citation Envoyé par Fructidor Voir le message
    oui, travailler avec l'API graphique en dehors de la thread main pose des problèmes. Heureusement, avec CallAfter on peut poster une commande pour qu'elle soit exécutée à l'intérieur de la thread main.
    wx.CallAfter(fen.Show,True)
    a la place the fen.Show(True)
    devrait faire l'affaire (il faut peut etre aussi le faire avec settopwindow?)
    Oui, alors ce serait une bonne idée, le seul problème c'est que mon thread principal est déjà utilisé par MainLoop comme dit plus haut et illustré par mon exemple de code. Je suis un peu bloqué. Le mieux serait même d'utiliser les thread de wx comme le dis la documentation donnée par pacificator, peut-être ?

    Comment feriez-vous à ma place ? Merci d'avance, et je vais fouiller un peu ces wxThreads.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Points : 139
    Points
    139
    Par défaut
    Oui, alors ce serait une bonne idée, le seul problème c'est que mon thread principal est déjà utilisé par MainLoop comme dit plus haut et illustré par mon exemple de code. Je suis un peu bloqué. Le mieux serait même d'utiliser les thread de wx comme le dis la documentation donnée par pacificator, peut-être ?
    C'est le principe d'un framework graphique: c'est la mainloop qui récupère les événements utilisateurs. Par ailleurs, les threads de wx sont des threads comme les autres, ca ne devrait rien changer.

    Je ne comprends pas "utiliser le thread principal pour mon long code". S'il y a un calcul long à faire et qu'il est effectué dans le thread de la mainloop, l'application ne répondra plus à l'utilisateur. Elle gèlera.

    Est ce que vous avez essayé avec CallAfter?

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut
    Citation Envoyé par Fructidor Voir le message
    C'est le principe d'un framework graphique: c'est la mainloop qui récupère les événements utilisateurs. Par ailleurs, les threads de wx sont des threads comme les autres, ca ne devrait rien changer.

    Je ne comprends pas "utiliser le thread principal pour mon long code". S'il y a un calcul long à faire et qu'il est effectué dans le thread de la mainloop, l'application ne répondra plus à l'utilisateur. Elle gèlera.

    Est ce que vous avez essayé avec CallAfter?
    §1 Je n'ai jamais utilisé CallAfter pour l'instant, mais je vais apprendre

    §2 En fait je dois gérer la connexion avec un serveur IRC en permanence, c'est ça mon long code car le thread l'exécutant n'est et ne sera jamais libéré (tant que la connexion existe).

    En utilisant CallAfter avec un évenement défini, pour exécuter un code (dans le thread principal): Est-ce que l'interface géle entre le moment où le code est exécuté et le moment où le MainLoop a de nouveau la main? Si oui, cela ne pose-t-il pas problème ?
    Si on prend mon exemple de code, est-ce qu'il serait possible de me faire un exemple très basique?

    Merci beaucoup,
    Bonne soirée.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut
    J'ai finalement réussi à l'intégrer dans mon application. C'est très simple en fait et ça passe bien. L'application n'est plus gélée comme avant, quel soulagement.

    Merci beacuoup !

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

Discussions similaires

  1. Thread et création de fenêtre.
    Par Ldoppea dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 16/04/2009, 15h50
  2. [VC++6]Créations de fenêtres et objets GDI
    Par Yoyo@ dans le forum MFC
    Réponses: 20
    Dernier message: 10/07/2005, 17h12
  3. [MFC + Win32] Création de fenêtre
    Par nmarf dans le forum MFC
    Réponses: 2
    Dernier message: 05/07/2005, 11h25
  4. Création de fenêtres sans icone dans la barre des taches
    Par bruce_will dans le forum Windows
    Réponses: 2
    Dernier message: 06/12/2004, 05h29
  5. Problème de création de fenêtre
    Par tomateauketchup dans le forum DirectX
    Réponses: 1
    Dernier message: 08/06/2003, 20h42

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