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

Tkinter Python Discussion :

Thread s'exécutant seuls au lancement + Freeze


Sujet :

Tkinter Python

  1. #1
    Nouveau Candidat au Club Avatar de Jorgebaratamc
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Thread s'exécutant seuls au lancement + Freeze
    Salut à tous !
    J'ai décidé de passer aux grands moyens et de venir consulter Le Forum face à un souci qui me fait tourner la tête.

    Intro:
    C'est un script Python tournant sur Raspberry Pi A+ construit autour du GUI Tkinter et qui permet via 8 boutons différents de faire 8 actions différentes (incroyable ).
    Nom : projet.png
Affichages : 272
Taille : 9,4 Ko

    Symptômes:
    Au lancement du script, la fenêtre se construit correctement et le code s'execute entièrement.
    Un peu trop d'ailleurs car je m'attendais à ce que le "command" liés aux boutons ne se déclenchent que lors du Clic sur le bouton.
    Au contraire, ils se lancent au démarrage du script sans y avoir cliqu dessus
    Cela a pour conséquence le lancement de tous les Thread en simultané et le Freeze de l'application

    Plus:
    J'aimerais également votre avis sur les points suivants:
    • Afficher une fenêtre Tkinter via SSH
    J'accède à mon RPi via SSH. La nécessité d'ajouter la balise suivante est la seule façon que j'ai trouvée pour arriver à afficher une fenêtre Tkinter sur mon poste client (Windows)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    os.system("sudo cp ~pi/.Xauthority ~root/")
    J'imagine que le problème sous-jacent à cela est qu'à chaque lancement du script il réécrira ces mêmes valeurs au même endroit tant qu'un Reboot ne sera pas effectué
    Des suggestions quand à son utilisation ou à une quelconque alternative?

    • Utilisation du module "os" pour l'appel de commandes externes
    Je compte lancer un Streaming à partir de la caméra du RPi. Pour cela, je dois effectuer une commande externe.
    Est-ce une bonne pratique ? J'ai déjà exploré le module "subprocess" mais sans succès à ce jour.

    • La fonction "dispatchCmd" est-elle de trop ?
    Passer par la commande suivante ne serait pas moins verbeux?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    command=Thread(target=loop1_5).start()
    Merci d'avance pour votre clairvoyance
    Voici le 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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    #!/usr/bin/python
    # coding: utf-8
     
    ############################
    # IMPORTATION DES LIBRAIRIES
    import os
    import time
    from threading import Thread
    import RPi.GPIO as GPIO
    # GUI
    from Tkinter import *
    import tkFont
    import tkMessageBox
     
    os.system("sudo cp ~pi/.Xauthority ~root/")
     
    ###########################
    # DÉCLARATION DES FONCTIONS
    def dispatchCmd(arg):
    	if   arg == 1:
    	    #Eclairage
    		Thread(target=lightUp).start()
    	elif arg == 2:
    	    #Prise de vue
    		Thread(target=loop1_5).start()
    	elif arg == 3:
    	    #Bell
    		Thread(target=loop6_10).start()
    	elif arg == 4:
    	    #Lancement du Stream
    		Thread(target=loop11_15).start()
    	elif arg == 5:
    	    #Zoom numérique
    		Thread(target=loop16_20).start()
    	elif arg == 6:
    	    #Lancement du radar à ultrasons
    		Thread(target=loop1_5).start()
    	else:
    		print("ERROR: UNKNOWN METHOD")
     
    def loop1_5():
    	for i in range(1, 6):
    		time.sleep(1)
    		print(i)
     
    def loop6_10():
    	for i in range(6, 11):
    		time.sleep(1)
    		print(i)
     
    def loop11_15():
    	for i in range(11, 16):
    		time.sleep(1)
    		print(i)
     
    def loop16_20():
    	for i in range(16, 21):
    		time.sleep(1)
    		print(i)
     
    def lightUp():
    	if GPIO.input(22) :
    		GPIO.output(22, GPIO.LOW)
    		ledBtn["text"] = "LED\nOFF"
    		ledBtn["bg"] = "#FF0000"
    		statusBar["text"] = "LEDs éteintes"
    	else:
    		GPIO.output(22,GPIO.HIGH)
    		ledBtn["text"] = "LED\nON"
    		ledBtn["bg"] = "#70AD47"
    		statusBar["text"] = "LEDs allumées"
     
    def showInfo():
    	tkMessageBox.showinfo("Informations", "Made by\nJorgio")
     
    def exitProg():
    	GPIO.cleanup()
    	win.quit()
     
    ###########################
    # PRÉPARATION DE LA FENÊTRE
    win = Tk()
    win.title("Interface d'administration")
    win.geometry('480x500+300+100')
    myFont = tkFont.Font(size=22, weight="bold")
     
    # Découpage de la fenêtre
    frameUp	= Frame(win)
    frameDown = Frame(win)
    frameUp.pack(side=TOP, padx=5, pady=5)
    frameDown.pack(padx=5, pady=5)
     
    # Construction des boutons
    ledBtn	= Button(frameUp, text="LED\nOFF",	font=myFont, bg="#FF0000", command=dispatchCmd(1), height=4, width=7, padx=5, pady=5)
    photoBtn	= Button(frameUp, text="PHOTO",	font=myFont, bg="#BBBBBB",command=dispatchCmd(2), height=4, width=7, padx=5, pady=5)
    bellBtn	= Button(frameUp, text="BELL",		font=myFont, bg="#70AD47",command=dispatchCmd(3), height=4, width=7, padx=5, pady=5)
    streamBtn	= Button(frameUp, text="STREAM",	font=myFont, bg="#70AD47",command=dispatchCmd(4), height=4, width=7, padx=5, pady=5)
    zoomBtn	= Button(frameUp, text="ZOOM",	font=myFont, bg="#BBBBBB",command=dispatchCmd(5), height=4, width=7, padx=5, pady=5)
    radarBtn	= Button(frameUp, text="RADAR", 	font=myFont, bg="#70AD47",command=dispatchCmd(6), height=4, width=7, padx=5, pady=5)
    infoBtn	= Button(frameDown, text="INFO",	font=myFont, bg="#00A0FF", command=showInfo, height=4, width=7, padx=5, pady=5)
    exitButton	= Button(frameDown, text="EXIT",	font=myFont, bg="#FF0000", command=exitProg,  height=4, width=7, padx=5, pady=5)
     
    # Disposition des boutons
    ledBtn.grid	(row=0, column=0)
    photoBtn.grid	(row=0, column=1)
    bellBtn.grid	(row=0, column=2)
    streamBtn.grid	(row=1, column=0)
    zoomBtn.grid	(row=1, column=1)
    radarBtn.grid	(row=1, column=2)
    infoBtn.grid	(row=2, column=1, padx=5)
    exitBtn.grid	(row=2, column=2, padx=5)
     
    # Barre d'état
    statusBar = Label(win, text="Nothing to show...", bd=1, relief=SUNKEN, anchor=W)
    statusBar.pack(side=BOTTOM, fill=X)
     
    #####################
    # PROGRAMME PRINCIPAL
    if __name__ == '__main__':
    	win.mainloop()
    	win.destroy()

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    C'est bien joli de raconter tout çà mais votre problème se résume quand même à des Buttons qui appellent la même fonction avec des arguments différents.... et à lire ce sujet de la FAQ.

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

  3. #3
    Nouveau Candidat au Club Avatar de Jorgebaratamc
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Salut wiztricks,
    En effet, cela a pour but ici de tester l'execution des Thread avant de remplacer ces fonctions par d'autres que je décris brièvement plus bas.
    Le programme n'est pas du tout destiné à effectuer 6 fois la même action avec qques paramètres différents mais bien d'effectuer les tâches suivantes en parallèle:
    • Allumer des LEDs (LED ON)
    • Lancer un Stream (STREAM)
    • Sauver une image dudit Stream (PHOTO)
    • Pouvoir Zoomer sur ledit Stream (ZOOM)
    • Enclencher une suite d'impulsions sonores (BELL)
    • Lancer une fonction de détection d'obstacle (RADAR)
    • Afficher une fenêtre d'informations (INFO)
    • Quitter le programme (EXIT)

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Jorgebaratamc Voir le message
    Le programme n'est pas du tout destiné à effectuer 6 fois la même action avec qques paramètres différents mais bien d'effectuer les tâches suivantes en parallèle
    Mouais, ben, c'est pas moi qui ait écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ledBtn	= Button(..., command=dispatchCmd(1), ...)
    photoBtn	= Button(..., command=dispatchCmd(2), ...)
    bellBtn	= Button(... , command=dispatchCmd(3), ...)
    ...
    où la fonction dispatchCmd est appelée avec les arguments 1, 2, 3,.... suivant le Button et non lorsqu'on va cliquer sur le Button correspondant... Pour constater que:
    Au contraire, ils se lancent au démarrage du script sans y avoir clique dessus
    A vous de prendre le temps de lire ce qu'on trouve dans la FAQ tkinter sur ce sujet afin de coder cela plus proprement.

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

  5. #5
    Nouveau Candidat au Club Avatar de Jorgebaratamc
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    L'utilisation de fonctions anonymes via le mot-clé "lambda" m'ont permis de résoudre le problème.
    Les fonctions se lancent désormais uniquement au clic des boutons et ne Freezent plus l'application.

    J'ai remplacé la ligne suivante (et similaires)
    command=dispatchCmd(1)
    par celle-ci
    command=lambda:Thread(target=lightUp).start()

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Jorgebaratamc Voir le message
    J'ai remplacé la ligne suivante (et similaires)
    command=dispatchCmd(1)
    par celle-ci
    command=lambda:Thread(target=lightUp).start()
    Pourquoi virer la fonction? command=lambda: dispatchCmd(1) fonctionnait aussi.

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

  7. #7
    Nouveau Candidat au Club Avatar de Jorgebaratamc
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Pourquoi virer la fonction? command=lambda: dispatchCmd(1) fonctionnait aussi.
    C'était verbeux je trouve. Dans ce cas-ci, ce n'était présent que pour des questions de test.
    Vu que je peux m'en passer, autant se débarrasser du code inutile

    Si jamais cela me serait utile de retourner à cette structure afin de compléter mes fonctions avec d'autres fonctionnalités, je saurai comment procéder.
    Merci encore wiz'

Discussions similaires

  1. Code exécuté une seule au lancement de Tomcat
    Par DomIII dans le forum Struts 1
    Réponses: 6
    Dernier message: 19/11/2010, 21h07
  2. Réponses: 2
    Dernier message: 23/12/2009, 14h41
  3. Script qui s'exécute seul régulièrement
    Par xess91 dans le forum Langage
    Réponses: 1
    Dernier message: 02/09/2009, 21h15
  4. Threads s'exécutant en parallèle
    Par Emyleet dans le forum MFC
    Réponses: 3
    Dernier message: 09/06/2008, 10h53
  5. Comment arréter un thread qui exécute une instruction bloquante
    Par nibor2luxe dans le forum Concurrence et multi-thread
    Réponses: 15
    Dernier message: 28/02/2008, 17h03

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