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

GUI Python Discussion :

GUI et multithread


Sujet :

GUI Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 7
    Par défaut GUI et multithread
    Bonjour,

    Pour un projet, j'essaye de lier du multithread à une interface graphique. Voici l'idée du projet : On modélise un restaurant par un serveur python. Des clients peuvent se connecter au serveur pour commander leur repas. Chaque client est livré par un livreur. Il y a un nombre fini de livreur, si tous les livreurs sont occupés, les nouveaux clients doivent attendre. Pour l'instant, je ne suis qu'au début du développement. J'ai mon serveur et mon client. Le client se connecte au serveur et reste connecté un certain temps jusqu'a etre livré. Comme plusieurs clients peuvent se connecter en même temps, je gère cela par du multithread.

    Mon probleme arrive lorsque je veux lier ce code à une interface graphique. En effet, j'aimerais faire une interface assez simple mais dynamique qui permet de voir la liste des clients qui se connectent, qui sont en attente de livraison ou qui ont été livrés et la liste des livreurs qui sont disponibles ou non. Le problème est que j'ai fait cette interface sous Tkinter et lorsque j'appelle des fonctions de mon interface dans ma fonction thread, j'obtiens l'erreur : main thread is not in main loop.
    Après quelques recherches, j'ai trouvé que Tkinter a bien un probleme avec le multithread mais je n'ai pas du tout compris la solution apportée par les internautes...
    Je voudrais donc savoir s'il y a une solution "simple" ou un autre module que Tkinter qui pourrait faire l'affaire.

    Merci

  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,

    Si tu n'es pas tenue à TKinter, alors je te recommande PyQt.

    http://pyqt.developpez.com/tutoriels/

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 738
    Par défaut
    Salut,

    Citation Envoyé par fgallais Voir le message
    Après quelques recherches, j'ai trouvé que Tkinter a bien un probleme avec le multithread mais je n'ai pas du tout compris la solution apportée par les internautes... Je voudrais donc savoir s'il y a une solution "simple" ou un autre module que Tkinter qui pourrait faire l'affaire.
    Quelque soit le GUI (tk, Qt,...) il n'est pas recommandé:
    - d'utiliser pour le GUI un autre thread que le thread principal,
    - d'effectuer des mises à jour des widgets depuis des threads secondaires.

    Citation Envoyé par fgallais Voir le message
    Le client se connecte au serveur et reste connecté un certain temps jusqu’à être livré. Comme plusieurs clients peuvent se connecter en même temps, je gère cela par du multithread.
    Rien ne vous empêche de démarrer le GUI et le serveur dans un thread secondaire.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 7
    Par défaut
    Je crois que je n'ai très bien compris la notion de thread.
    Pour moi on a un serveur, et dès qu'un client se connecte, on crée un nouveau thread. Le problème est qu'une fois qu'un client est connecté, il lui arrive des choses, et je veux que ça se voit sur l'interface graphique. Donc je n'arrive pas à comprendre comment l'interface graphique pourrait etre gérée à l'extérieur...

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 738
    Par défaut
    Salut,

    Citation Envoyé par fgallais Voir le message
    Pour moi on a un serveur, et dès qu'un client se connecte, on crée un nouveau thread. Le problème est qu'une fois qu'un client est connecté, il lui arrive des choses, et je veux que ça se voit sur l'interface graphique. Donc je n'arrive pas à comprendre comment l'interface graphique pourrait etre gérée à l'extérieur...
    L'interface graphique est dans sa main-thread le serveur et les différents threads correspondant à chaque client tournent dans le même programme.
    Je ne comprends pas ce qui serait "exterieur" à quoi.

    Pour le reste, postez du code....

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 7
    Par défaut
    C'est vrai que je ne suis pas très claire. Peut être que ce sera plus simple d'expliquer avec 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
    listeClient=[]
     
    def f_thread(clisock):
        loopEnd = True
        t=0
        #On cherche le premier livreur disponible:
        num_livreur=0 
        while restaurant[num_livreur].occupe==True:
    		num_livreur +=1
     
        restaurant[num_livreur].occupe=True
     
     
     
     
        while loopEnd:
            data = clisock.recv(2048)
            if t==0:
    			print data
    			num = data[6]
    			t+=1
            clisock.send(data)
     
     
    	if not data:
    	   clisock.shutdown(0)
               listeClient.remove(clisock)
    	   print "Le client"+num+" a ete livre par le livreur"+str(restaurant[num_livreur].num)
    	   restaurant[num_livreur].occupe=False
    	   loopEnd = False
     
     
     
     
     
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('',8001))
    sock.listen(5)
    while True:
    	clisock, addr = sock.accept()
    	listeClient.append(clisock)
    	print "Un client a passe commande"
    	t = threading.Thread(target=f_thread, args=(clisock,))
    	t.start()
    Il s'agit, pour moi, de la partie serveur.

    Donc, quand un client se connecte, on entre dans la fonction "f_thread", jusqua ce que le client se deconnecte. C'est a dire que pour moi, toutes les modifications apportées sur le client s'effectuent dans cette fonction. Et c'est de cette fonction que j'ai essayé d'appeler une fonction de mon interface et que j'ai eu mon erreur. Je ne vois donc pas comment faire pour lier client et interface si je n'utilise pas l'interface dans f_thread.

    J'espere avoir été claire.. merci de votre aide

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 738
    Par défaut
    Salut,

    Comme dans votre but de code, la partie GUI n'est pas présente pas facile...
    De toutes façons, l'architecture de votre code devrait ressembler à çà:
    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
    import Tkinter as tk
    from threading import Thread
    import time
     
    def run_server(label):
        def do_update():
            label.configure(text=n)
     
        n = 0
        while True:
            root.after_idle(do_update)   
            n += 1
            time.sleep(0.5)
     
     
    root = tk.Tk()
    label = tk.Label(root)
    label.pack()
     
    server = Thread(target=run_server, args=(label,))
    server.daemon = True
    server.start()
     
    tk.Button(root, text='quit', command=root.quit)
     
    root.mainloop()
    On démarre le GUI dans le thread principal, le serveur dans un thread secondaire et les mises à jour se font via un mécanisme où on poste une requête depuis le thread serveur qui s'exécutera dans le contexte du thread principal (GUI).

    Une façon plus conventionnelle est de passer par une Queue (au lieu d'empiler dans la mainloop du GUI) qu'on vide via une tache répétitive:
    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
    import Tkinter as tk
    from threading import Thread
    import time
    import Queue
     
    def run_server(label):
     
        n = 0
        while True:
            f = lambda: label.configure(text=n) 
            cmdQ.put(f)
            n += 1
            time.sleep(0.5)
     
     
    cmdQ = Queue.Queue()
    def check_ui_updates(delay=500):
        while True:
            try:
                cmd = cmdQ.get_nowait()
            except Queue.Empty:
                break
            else:
                cmd()
     
        root.after(delay, check_ui_updates)
     
    root = tk.Tk()
    root.after_idle(check_ui_updates)
     
    label = tk.Label(root)
    label.pack()
     
    server = Thread(target=run_server, args=(label,))
    server.daemon = True
    server.start()
    Tous les GUI imposent cette architecture.
    Les différences sont "comment la mettre en œuvre".


    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. [WinAPI C++] MultiThreading?
    Par Gruik dans le forum Windows
    Réponses: 2
    Dernier message: 25/03/2004, 00h08
  2. [editeur GUI][info]
    Par lunatix dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 26/01/2004, 15h59
  3. [GUI] Ou trouver les standard ?
    Par Braim dans le forum Windows
    Réponses: 5
    Dernier message: 01/10/2003, 08h13
  4. [Win32]App multithread
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 25/09/2003, 09h57
  5. Multithreading sous HP Ux 11
    Par pykoon dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 18/10/2002, 23h36

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