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

Python Discussion :

Retour de chaine après fonction


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Janvier 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 24
    Par défaut Retour de chaine après fonction
    Bonjour, je suis débutant en Python, J'ai bouquiné une quinzaine d'heure avant de me lancer, mais j'ai de grosses lacunes.
    Voici mon 1er programme:

    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
    import time
    import sys
    from Tkinter import *
    from socket import *
     
    IP = "0.0.0.0"
     
     
    def find_tibbo():
        MYPORT = 65535
        donnee = 'X'
        print("sending X")
        time.sleep(.5)
        s = socket(AF_INET, SOCK_DGRAM)     #UDP with DGRAM
        s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
        s.sendto(donnee, ('<broadcast>', MYPORT))
        data , addr = s.recvfrom(1024)
        print "RECV: ", data, " from:",addr #addr is a tuple
        IP_found = addr[0]                  # just IP, no port
        print IP_found
        s.close()
        return IP_found
     
    Win = Tk()
     
    Win.geometry('400x400+800+300')
    Win.title('subrack controler')
     
     
    Wintxt = Label(Win,text='Search for IP address').place(x=18,y=15)
    Winbutton = Button(Win,text = 'Go',command = find_tibbo).place(x=200,y=10)
    WinIP = Label(Win,text=IP).place(x=250,y=15)
     
     
    Win.mainloop()
    Alors voilà, il y a une grosse partie qui fonctionne (Python 2.7.3rc2 sur Raspberry Pi), une fenetre s'ouvre et j'affiche bien une adresse IP bidon (0.0.0.0) au départ. Quand je clique sur "GO" une fonction permet d'aller sur le réseau chercher l'adresse IP d'un module électronique qui réponds bien, par exemple:

    >>>
    sending X
    RECV: A0.36.119.80.199/000001001/N**M/**/Herve //4 from: ('192.168.150.117', 65535)
    192.168.150.117
    >>>

    Donc l'adresse IP est bien trouvée puisqu'imprimée.

    Maintenant, et après avoir passé beaucoup de temps à trouver la solution, je n'arrive pas à changer l'adresse IP bidon de ma fenetre par la véritable adresse trouvée par ma fonction, après avoir cliqué "Go". (dans IP_found)
    (Mes divers essais ne fonctionnaient pas, ou donnaient des choses... étranges)


    Merci de votre aide
    Hervé

  2. #2
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    Salut hherve.

    Tu commences fort pour un premier programme: tkinter, socket...

    Je ne maitrise ni l'un ni l'autre. Mais j'essaierais de voir du côté d'un "refresh". Ton label WinIP doit changé après avoir trouvé l'IP, c'est ça? Dans ce cas il faudrait insérer ceci quelque part:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WinIP.update_idletasks()
    Habituellement lorsque j'utilise tkinter (très rare), je créé un classe "Application" dans laquelle j'initialise l'interface. J'écris ensuite une méthode "Progress" qui décrit tous les processus. Comme ceci:

    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
     
    class App:
        # This class defines the main program
     
        def __init__(self,root):
            # Build the interface
     
            self.Win = Frame(root)
            self.Win.geometry('400x400+800+300')
            self.Win.title('subrack controler')
            self.Wintxt = Label(Win,text='Search for IP address').place(x=18,y=15)
     
            # Defini le label WinIP comme étant variable (important selon moi)
            self.labelText = StringVar()
            self.labelText.set('0.0.0.0')
            self.WinIP = Label(Win,textvariable=labelText).place(x=250,y=15)
     
            self.Winbutton = Button(self.Win,text = 'Go',command = self.Process).place(x=200,y=10)
     
     
        def Process(self):
             # Define the processus
     
             # Appelle ta fonction et récupère l'ip en tant que string
             IP = str(find_tibbo())
             # Modifie la variable "labelText"
             self.labelText.set(IP)
             # Update le label
             self.WinIP.update_idletasks()
     
     
    root = Tk()
    app = App(root)
    root.mainloop()
    Bon, mon code ne marchera pas (j'ai pas essayé mais le contraire serait un miracle). Mais il y a dedans deux choses importantes. La première c'est qu'il faut définir un label variable, et la suivante c'est qu'il faut updater ton label après avoir changer le contenu de ta variable.

    Bon courage!


    Ju

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 750
    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 750
    Par défaut
    Salut,
    Pour mettre à jour le label via la fonction "réseau", on peut passer par des StringVar, çà donne:
    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
    import time
    import sys
    import Tkinter as tk
     
    IP = "0.0.0.0"
     
     
    def find_tibbo(var):
        var.set('1.2.3.4')
     
    if __name__ == '__main__':
        app = tk.Tk()
     
        app.geometry('400x400+800+300')
        app.title('subrack controler')
     
        ip_variable = tk.StringVar(value=IP)
     
        tk.Label(text='Search for IP address').place(x=18,y=15)
        tk.Button(text = 'Go',command= lambda var=ip_variable: find_tibbo(var)).place(x=200,y=10)
        tk.Label(textvariable=ip_variable).place(x=250,y=15)
        tk.mainloop()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Janvier 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 24
    Par défaut
    @ Julien N

    Des idées intéressantes... Mais comme tu t'en doutais, ton code ne fonctionne pas. C'est pas évident pour un débutant de prendre des idées si, au départ, ça écrit tout rouge !
    _____

    Merci Wiztricks,

    Parfait ! J'ai inclus mon code dedans et... J'affiche l'IP lue sur le réseau.
    J'ai appris pour le:

    if __name__ == '__main__':

    Je l'avais lu avant, mais sans un exemple concret, je voyais pas bien le truc...

    Juste quelques questions:
    je comprends pas bien le app = tk.Tk()
    et si je désire un 2éme label, je peux l'appeler comment ?
    Je demande cela car c'est différent de la forme dont j'avais écris (plus haut) et qui me semblait... acquise

    Amicalement
    Hervé

  5. #5
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Janvier 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 24
    Par défaut
    Salut,

    Avec le dernier "source" je récupérais l'adresse IP depuis la fonction find_tibbo pour l'afficher.

    Maintenant que j'ai obtenu cette IP dans ip_variable, je désire aussi l'utiliser pour communiquer en TCP. J'ai donc crée une fonction qui permet d'envoyer les données qui vont bien à mon électronique. Malheureusement, je ne réussis pas à récupérer cette IP dans ma nouvelle fonction nommée auto_man.
    J'ai mis un print pour voir la variable mais je lis PY_VAR0 au lieu de mon IP

    Qu'est-ce que je n'ai pas compris ?

    Merci d'avance

    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
    45
    46
    47
    48
    import time
    import sys
    import Tkinter as tk
    from socket import *
     
    IP = "0.0.0.0"
    mode = "Unknow"
     
     
    def find_tibbo(var):
        s = socket(AF_INET, SOCK_DGRAM)     #UDP with DGRAM
        s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
        s.sendto('X', ('<broadcast>', 65535))
        data , addr = s.recvfrom(1024)
        print "RECU: ", data, " depuis:",addr #pour debug
        IP = addr[0]                        # just IP, no port
        s.close()
        var.set(IP)
     
    def auto_man(var2):
        print var2          
        s = socket(AF_INET, SOCK_STREAM)    #TCP with STREAM
        s.connect((var2,10001))
        time.sleep(.1)
        s.send("MODE?\n")
        time.sleep(.1)
        mode = s.recv(1024)
        s.close()
        var2.set(mode)
     
    if __name__ == '__main__':
        app = tk.Tk()
     
        app.geometry('400x400+800+300')
        app.title('subrack controler')
     
        ip_variable = tk.StringVar(value=IP)
        mode_variable = tk.StringVar(value=mode)
     
        tk.Label(text='Search for IP address').place(x=18,y=15)
        tk.Button(text = 'Go',command= lambda var=ip_variable: find_tibbo(var),fg = "blue").place(x=200,y=10)
        tk.Label(textvariable=ip_variable).place(x=250,y=15)
     
        tk.Label(text='Mode AUTO or MANUAL ?').place(x=18,y=45)
        tk.Button(text = 'Go',command= lambda var1=mode_variable: auto_man(ip_variable),fg = "blue").place(x=200,y=40)    
        tk.Label(textvariable=mode_variable).place(x=250,y=45)
     
        tk.mainloop()

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 750
    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 750
    Par défaut
    Salut,

    Citation Envoyé par hherve Voir le message
    J'ai mis un print pour voir la variable mais je lis PY_VAR0 au lieu de mon IP
    En écrivant "ip_variable = tk.StringVar(value=IP)" la variable Python sera associée à une variable de l'interpréteur TCL. Tkinter (le côté Python) réalise cette association en créant une instance de tk.StringVar et génère, par défaut, le nom de la variable TCL: PY_VARn.
    Si on écrit: "ip_variable = tk.StringVar(name='ip_variable', value=IP)", le nom de la variable TCL sera 'ip_variable'.
    print (ip_variable) applique la méthode __str__ à l'instance de tk.StringVar associée qui retourne le nom de la variable.
    Si on veut afficher/récupérer son contenu, il faut appliquer la méthode .get
    à l'objet référencé par "ip_variable" - comme le .set pour lui assigner une nouvelle valeur.
    Qu'est-ce que je n'ai pas compris ?
    Le danger de ce forum est de récupérer des "bouts de code" utilisant des fonctionnalités qui demandent d'avoir "accumulé" quantité de connaissances pour être "accessible".
    Etre "accessible" est une notion relative.
    Elle traduit vos possibilités de prendre le temps de comprendre "pourquoi": lire la documentation associée, tester un peu pour s'assurer qu'on a un peu compris ce quelle raconte,... pour arriver à maîtriser ce qu'il se passe.

    Repartez plutôt sur une construction "simple".
    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
    import time
    import sys
    import tkinter as tk
    from socket import *
     
    IP = "0.0.0.0"
    mode = "Unknow"
     
    def find_tibbo():
        s = socket(AF_INET, SOCK_DGRAM)     #UDP with DGRAM
        s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
        s.sendto('X', ('<broadcast>', 65535))
        data , addr = s.recvfrom(1024)
        print "RECU: ", data, " depuis:",addr #pour debug
        s.close()
        return addr[0]
     
    def do_find_tibbo():
        '''dans ce cas, on récupère la variable par son nom tk'''
        ip = find_tibbo()
        ip_label.config(text=ip)    
     
    if __name__ == '__main__':
        app = tk.Tk()
     
        app.geometry('400x400+800+300')
        app.title('subrack controler')
     
        tk.Label(text='Search for IP address').place(x=18,y=15)
        ip_label = tk.Label(text=IP)
        ip_label.place(x=250,y=15)
        tk.Button(text = 'Go',command=do_find_tibbo ,fg = "blue").place(x=200,y=10)
     
        tk.mainloop()
    L'objet à modifier sera ip_label.
    • Comme l'objet tk.Label est stocké dans une variable "globale", pas besoin de la passer en paramètre à la commande "do_find_tibbo": çà évite de passer par "lamba" qui est "mieux" mais difficile.
    • Séparer do_find_tibbo et find_tibbo permet de tester find_tibbo sans se soucier de l'intégration avec le GUI qui est le boulot de "do_find_tibbo"


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

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 750
    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 750
    Par défaut
    Salut,

    Citation Envoyé par hherve Voir le message
    Juste quelques questions:
    je comprends pas bien le app = tk.Tk()
    et si je désire un 2éme label, je peux l'appeler comment ?
    Je demande cela car c'est différent de la forme dont j'avais écris (plus haut) et qui me semblait... acquise
    Je ne suis pas sur de bien avoir compris vos questions.

    Le "app = tk.Tk()" est induit par le remplacement du "from Tkinter import *" (1) par "import Tkinter as tk". Ca n'a aucune importance lorsqu'on débute mais c'est une bonne habitude à prendre pour diverses raisons.

    Ecrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.Winbutton = Button(self.Win,text = 'Go',command = self.Process).place(x=200,y=10)
    ou:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Winbutton = Button(Win,text = 'Go',command = Process).place(x=200,y=10)
    amène 2 autres questions:
    tk.Button est une classe.
    tk.Button(...) retourne l'instance d'un tk.Button.
    tk.Button(...).place(...) retourne le résultat de l'appel à .place(...) qui est "None".
    Stocker cela dans une variable globale ou l'attribut d'une instance n'a aucun intérêt sauf à écrire 2 lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Winbutton = Button(Win,text = 'Go',command = Process)
    Winbutton.place(x=200,y=10)
    ou à se prendre les pieds dans le "None" lorsqu'il sera utile d'y accéder.
    Ceci dit, pourquoi stocker la référence à un objet qui ne sera pas (encore) utilisée: si c'est pour éviter leur destruction par le "garbage collector", tkinter s'en occupe déjà.

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

  8. #8
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Janvier 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 24
    Par défaut
    OK,

    Merci pour les explications.... Je vois qu'il me faut bosser davantage (Je viens du basic sur microcontroleurs PIC, merci le changement ) et lire un max.
    D'ailleurs, vu le temps ce week-end, je sais que je passerais quelques heures sur Python...

    Bien, je ne voudrais pas ennuyer le monde, mais sincèrement, si vous pouvez me dépanner pour ma question du post#5, (sans modifier trop de choses si possible) ce serait peut-être le déclic pour moi qui rame sur ces passages de
    données d'une fonction à une autre.

    Cordialement
    Hervé

Discussions similaires

  1. Réponses: 4
    Dernier message: 14/02/2006, 08h35
  2. [debutant]Chaine et fonction
    Par Halobox dans le forum C
    Réponses: 9
    Dernier message: 20/11/2005, 00h39
  3. Réponses: 7
    Dernier message: 24/10/2005, 23h10
  4. [XSL-FO] retour à la ligne après un tableau ?
    Par Mrlud dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 25/04/2005, 17h15
  5. Retour NULL d'une fonction utilisateur
    Par tiboleo dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 18/11/2004, 15h40

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