Partage
  • Partager sur Facebook
  • Partager sur Twitter

Réseau et interface graphique Tkinter

Sujet résolu
    17 janvier 2015 à 18:56:49

    Bonsoir les zéros.

    Je suis en train d'essayer une sorte de mini tchat en réseau sur interface graphique et non sur console.

    Seulement j'ai un problème avec ma boucle qui attend les entrées de texte du client, tant que le client ne met pas fin à la conversation, côté serveur rien ne se passe car le mainloop n'est activé qu'une fois sorti de la boucle. J'ai essayé de mettre le mainloop() dans la boucle mais sans succès.

    J'ai aussi essayé avec la méthode select() mais n'ayant pas vraiment tout compris à cette méthode, je n'ai pas réussi à la mettre en oeuvre correctement.

    Si vous aviez une astuce pour me débloquer, merci de me la soumettre :)

    # -*- coding: utf-8 -*-
    
    import socket
    import select
    from tkinter import *
    	
    	
    hote = ""
    port = 12800
    
    mainWindow = Tk()
    
    quitButton = Button(mainWindow, text = "Quitter", command = mainWindow.destroy).pack()
    
    connexion_main = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connexion_main.bind((hote, port))
    connexion_main.listen(5)
    
    text1 = Label(mainWindow, text = "Le serveur écoute sur le port {}".format(port), fg = "red").pack()
    
    connexion_customer, info_connexion = connexion_main.accept()
    
    text2 = Label(mainWindow, text = "Une connexion a été établie avec un client").pack()
    
    window1 = Toplevel()
    window1.title("Infos client")
    text3 = Label(window1, text = info_connexion).pack()
    
    msg_received = b""
    
    while msg_received != "fin" :
    	msg_received = connexion_customer.recv(1024)
    	text4 = Label(window1, text= msg_received.decode()).pack()
    	connexion_customer.send(b"d'accord")
    	
    
    	
    text_closeConnexion = Label(mainWindow, text = "Fermeture de la connexion", fg = "red")
    
    connexion_customer.close()
    connexion_main.close()
    
    window1.mainloop()
    mainWindow.mainloop()
    
    
    
    

    PS : Oui tous mes noms de variables et autres sont en anglais, car je trouve que rien que ça c'est un bon exercice pour s'entraîner en anglais.

    • Partager sur Facebook
    • Partager sur Twitter
      18 janvier 2015 à 10:33:09

      Salut,

      La solution est à la fois simple et compliquée.

      Il faut "simplement" utiliser les threads, c'est à dire la capacitée qu'a un ordinateur pour faire plusieurs taches en même temps.

      Ce lien pourra peut-être t'aider pour les threads en général : http://python.developpez.com/faq/?page=Thread.

      Quant à celui-là, il pourra t'aider pour les threads + socket : http://ilab.cs.byu.edu/python/threadingmodule.html(en anglais)

      pour de plus amples informations, "thread pyhton" sur google ;)

      • Partager sur Facebook
      • Partager sur Twitter
      Bevet Breizh! Breizh dizalc'h! Betek an trec'h! Ha mallozh ruz d'ar c'hallaoued! Trouvez votre voie
        18 janvier 2015 à 11:48:48

        D'accord merci pour ta réponse pythan, je laisse le sujet ouvert pour l'instant si certains on d'autres solutions à proposer.

        Je vais essayer la tienne en attendant, mais elle ne me parait pas super simple après un rapide coup d'oeil à tes liens ^^

        Mais en même temps, pourquoi faire simple quand on peut faire compliquer ? #Thread :p

        • Partager sur Facebook
        • Partager sur Twitter
          18 janvier 2015 à 12:21:40

          Re,

          Malheureusement je pense que c'est la seul solution : il faut gérer une interface graphique + réception + envoi.

          • Partager sur Facebook
          • Partager sur Twitter
          Bevet Breizh! Breizh dizalc'h! Betek an trec'h! Ha mallozh ruz d'ar c'hallaoued! Trouvez votre voie
            18 janvier 2015 à 13:20:08

            Salut

            Je ne sais pas si c'est la seule, mais en tout cas c'est la plus connue, et quand on parle de threading on parle de multi-tâche, donc le module threading me paraît approprié x)

            -
            Edité par InhumanRampage 18 janvier 2015 à 13:48:25

            • Partager sur Facebook
            • Partager sur Twitter
              18 janvier 2015 à 13:28:55

              Je suis d'accord. Cependant si tu es sous Python 3.4, tu voudras peut-être regarder au module asyncio. J'ai trouvé une discussion ici qui pourrait t'aider.

              Mais ça fait aussi beaucoup de choses à lire. :)

              • Partager sur Facebook
              • Partager sur Twitter
                19 janvier 2015 à 20:04:19

                J'ai réussi à comprendre le module threading je crois, il n'est pas si compliqué que ça en fait.

                Par contre j'ai un soucis, ma fenetre définie dans une classe ne s'ouvre que lorsque mon autre classe serveur y fait appel pour y placer des Label, autrement dit, elle ne s'ouvre que lorsque j'éxécute le programme client.

                Or moi je souhaiterais que ma fenêtre s'ouvre, et que ma classe serveur la mette à jour lorsqu'un client se connecte.

                Et une autre petite chose, pourquoi est ce que ça ne marchait pas quand j'ai voulu passer ma variable fenetre_principale en global dans ma fonction connexion de la classe Serveur, pour ne pas avoir à donner fenetre_principale en argument de ma fonction, ce que j'ai du faire au final, et je pense du coup que c'est ça qui fait merder, mais je suis pas sur du tout.

                from tkinter import *
                from socket import *
                from threading import Thread
                
                
                class fenetres(Thread) :
                
                	def __init__(self) :
                		Thread.__init__(self)		
                	
                	def fenetre_principale(self) :
                		fenetre_principale = Tk()
                		fenetre_principale.title("Serveur")
                		
                		return fenetre_principale
                		fenetre_principale.mainloop()
                		
                		
                class Serveur(Thread) :
                
                	def __init__(self) :
                		Thread.__init__(self)
                		
                	def connexion(self, fen) :
                		hote = ""
                		port = 12800
                		
                		connexion_principale = socket(AF_INET, SOCK_STREAM)
                		connexion_principale.bind((hote, port))
                		connexion_principale.listen(5)
                		text1 = Label(fen, text = "Le serveur écoute sur le port {}".format(port) ).pack()
                		
                		connexion_client, infos_client = connexion_principale.accept()
                		text2 = Label(fen, text = "Connexion avec le client établie.").pack()
                
                
                
                fenetre1 = fenetres()
                fen = fenetre1.fenetre_principale()
                fenetre1.start()
                fenetre1.join()
                
                ouvrir_serveur = Serveur()
                ouvrir_serveur.connexion(fen)
                ouvrir_serveur.start()
                ouvrir_serveur.join()
                



                • Partager sur Facebook
                • Partager sur Twitter
                  21 janvier 2015 à 17:44:34

                  quelqu'un aurait une réponse à apporter à mon problème s'il vous plaît ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 janvier 2015 à 16:28:49

                    Help please ! ca fait une semaine que j'attend une réponse ^^
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      26 janvier 2015 à 17:01:24

                      Pour commencer par la base un str est différent d'un bytes.

                      >>> b"fin" == "fin"
                      False



                      • Partager sur Facebook
                      • Partager sur Twitter
                        26 janvier 2015 à 21:44:24

                        Tkinter doit tourner dans le Thread principal. Ca signifie que tu ne peux pas le mettre dans une classe qui hérite de Thread. Ton serveur par contre lui doit tourner dans son propre Thread. Rapidos, ça pourrait donner:

                        !/usr/bin/env python3

                        -- encoding: utf-8 --

                        from tkinter import from socket import from threading import Thread

                        class Serveur(Thread):

                        def __init__(self, fen) :
                            Thread.__init__(self)
                            self.fen = fen
                             
                        def run(self) :
                            hote = ""
                            port = 12800
                             
                            connexion_principale = socket(AF_INET, SOCK_STREAM)
                            connexion_principale.bind((hote, port))
                            connexion_principale.listen(5)
                            text1 = Label(self.fen, text = "Le serveur écoute sur le port {}".format(port) ).pack()
                             
                            connexion_client, infos_client = connexion_principale.accept()
                            text2 = Label(self.fen, text = "Connexion avec le client établie.").pack()
                        

                        fenetre_principale = Tk() fenetre_principale.title("Serveur")

                        ouvrir_serveur = Serveur(fenetre_principale) ouvrir_serveur.start()

                        fenetre_principale.mainloop()

                        </pre>

                        Par contre le module socket est assez low-level. Regarde peut-être à socket-server

                        -
                        Edité par Dan737 27 janvier 2015 à 19:46:20

                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 janvier 2015 à 19:14:18

                          Merci Dan737, ce que tu dis parait très logiques, mais après des essais dans tous les sens en recopiant exactement ton code, aucune fenêtre ne s'ouvre tant que l'éxetuable client n'est pas lancé :(

                          Je comprend pas...

                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 janvier 2015 à 19:47:32

                            Quand je lance le code que j'ai posté, j'ai une fenêtre Tkinter qui apparait où il est inscrit: "Le serveur écoute sur le port 12800". Tu n'as pas ça??

                            • Partager sur Facebook
                            • Partager sur Twitter
                              27 janvier 2015 à 20:14:58

                              Si je l'ai cette fenêtre en question, mais que quand je lance l'exécutable client.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                27 janvier 2015 à 20:16:36

                                Ah si je viens de le refaire maintenant ça marche... WTF ?

                                J'avais du faire une fausse manip, comprend pas trop, enfin bref ça marche, je suis super content je vais pouvoir avancer :)

                                Merci beaucoup Dan737 pour ton aide ! :magicien:

                                • Partager sur Facebook
                                • Partager sur Twitter

                                Réseau et interface graphique Tkinter

                                × 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