Vous êtes ici : Accueil / Forums & ML / Forums Python / Forum général Python / Problème d'arret du programme

Problème d'arret du programme

Remonter à Forum général Python
  • Problème d'arret du programme

    Envoyé par jbj le 16 Novembre 2006 à 17:19
    Bonjour à tous,
    J'ai crée un réveil en python qui permet de se faire réveiller par la musique de son choix.
    Tout marche nikel à une exeption, lorsque je clique sur la croix de fermeture de mon GUI et si le Thread gérant l'heure de réveil à été activé, le GUI disparait mais mon programme tourne toujours. Je pensais que cela venait du Thread, j'ai donc crée une fonction qui est sensé arretter totallement mon appli, mais rien à faire, toujours le même probleme et Python ne lève aucune exception.

    Voici mon code:

    #!/usr/env python
    # -*- coding: utf-8 -*-

    from Tkinter import *
    import time, string, sys, tkFileDialog, threading, pygame.mixer, ConfigParser

    class myThread(threading.Thread):
    global test
    def __init__(self, string_heureDeSonnerie):
    threading.Thread.__init__(self, target=self.run, args=())
    self.string_heureDeSonnerie = string_heureDeSonnerie
    self.test=True
    self.start()

    def run(self):
    while(self.test):
    heure_courante = time.strftime("%H:%M:%S")
    if (self.string_heureDeSonnerie == heure_courante):
    pygame.mixer.init()
    sound = pygame.mixer.Sound(musique)
    sound.play(-1)
    self.test=False
    else:
    time.sleep (1)

    def clock():
    """Donne l'heure courante au format hh:mmm:ss et l'affiche"""
    temps = time.strftime("%H:%M:%S")
    heure_actuelle.config(text=temps)
    root.after(200, clock)

    def activer():
    global test
    """Vérifie que les parametres necessaires sont corrects et active le réveil"""
    if (activer.cget("text") == "Activer"):
    hours = heure.get()
    mins = minutes.get()
    if (hours.isdigit()== False or int(hours) > 23):
    erreur("Heures: paramètres invalides")
    elif (mins.isdigit() == False or int(mins) > 59):
    erreur("Minutes: paramètres invalides")
    elif (musique == ""):
    erreur("Aucune sonnerie définie")
    else:
    erreur("parametres: ok")
    heure_sonnerie = hours+':'+mins+':'+'00'
    sauverParametres()
    t = myThread(heure_sonnerie)
    etat.config(text="Etat: Sonnera à "+heure_sonnerie)
    activer.config(text="Stopper")

    elif (activer.cget("text") == "Stopper"):
    if (pygame.mixer.get_busy()):
    pygame.mixer.stop()
    test = False
    etat.config(text="Etat: Inactif")
    activer.config(text="Activer")

    def choisirSonnerie():
    """permet de choisir la sonnerie du réveil"""
    global musique
    musique = tkFileDialog.askopenfilename()
    #TODO: vérifier que le fichier est bien une musique
    if (musique.endswith(".wav") or musique.endswith(".org")):
    s.config(text = "Sonnerie: "+str(musique))
    erreur("Sonnerie: ok")
    else:
    musique =""
    erreur("Seuls les formats wav et ogg sont acceptés")

    def erreur(string_erreur):
    """Affiche l'erreur correspondante"""
    message_erreur.config(text=string_erreur)

    def testerSonnerie():
    """permet de tester la sonnerie"""
    if (test_sonnerie.cget("text") == "Tester la sonnerie"):
    if (musique ==""):
    erreur("Veuillez choisir une sonnerie.")
    else:
    pygame.mixer.init()
    sound = pygame.mixer.Sound(musique)
    sound.play(-1)
    test_sonnerie.config(text="Arretter le test")
    erreur("Sonnerie: en test")
    elif (test_sonnerie.cget("text") == "Arretter le test"):
    if (pygame.mixer.get_busy()):
    pygame.mixer.stop()
    erreur("")
    test_sonnerie.config(text="Tester la sonnerie")


    def restaurerParametres():
    """restaure les parametres présents dans le fichier 'config.ini' si présent"""
    global musique
    try:
    conf = ConfigParser.ConfigParser()
    conf.read("config.ini")
    conf_heures = conf.get("MAIN", "heures")
    heure.delete(0, END)
    heure.insert(END, conf_heures)
    conf_minutes = conf.get("MAIN", "minutes")
    minutes.delete(0, END)
    minutes.insert(END, conf_minutes)
    conf_sonnerie = conf.get("MAIN", "sonnerie")
    musique = conf_sonnerie
    s.config(text="Sonnerie: "+conf_sonnerie)
    except:
    creerFichier()

    def sauverParametres():
    """Enregistre les parametres dans le fichier 'config.ini'"""
    try:
    fichier = open("config.ini", "w")
    fichier.write("")
    fichier.close()
    conf = ConfigParser.ConfigParser()
    conf.read("config.ini")
    conf.add_section("MAIN")
    conf.set("MAIN", "heures", heure.get())
    conf.set("MAIN", "minutes", minutes.get())
    conf.set("MAIN", "sonnerie", musique)
    conf.write(open("config.ini","w"))
    except:
    erreur("Erreur dans l'enregistrement des paramètres")

    def creerFichier():
    try:
    conf = ConfigParser.ConfigParser()
    conf.add_section("MAIN")
    conf.set("MAIN", "heures", "")
    conf.set("MAIN", "minutes", "")
    conf.set("MAIN", "sonnerie", "")
    conf.write(open('config.ini','w'))
    except:
    erreur("Impossible de créer le fichier de sauvegarde")

    def quitter():
    global test
    test=False #arret du thread
    print test
    if (pygame.mixer.get_busy()):
    pygame.mixer.stop() #arret du mixer
    print "mixer arrette"
    root.destroy() #destruction de la fenetre
    sys.exit(0) #arret du programme
    print "arret"

    musique = ""
    #GUI
    root = Tk()
    root.title("JBJ Wake-Up!")
    heure_actuelle = Label()
    heure_actuelle.grid(row=0, column=0, columnspan = 3, sticky="n")
    etat = Label(text="Etat: Inactif")
    etat.grid(row = 1, column = 0, columnspan=3, sticky="w")
    heure_reveil = Label(text="Heure de réveil: ")
    heure_reveil.grid(row = 2, column = 0, columnspan=2, sticky="w")
    frame= Frame()
    frame.grid(row =2, column =2, sticky="w")
    heure = Entry(frame, width=2)
    heure.grid( row = 0, column = 0, sticky="w")
    h = Label(frame, text="h")
    h.grid(row = 0, column = 1, sticky="w")
    minutes = Entry(frame, width=2)
    minutes.grid(row = 0, column = 2, sticky="w")
    s = Label(text="Sonnerie : Aucune")
    s.grid(row = 3, column = 0, columnspan =3, sticky ="w")
    activer = Button(text="Activer", command = activer)
    activer.grid(row = 4, column = 0, sticky="w")
    choix_sonnerie = Button(text = "Sonnerie", command = choisirSonnerie)
    choix_sonnerie.grid(row = 4, column = 1, sticky="w")
    test_sonnerie = Button(text="Tester la sonnerie", command = testerSonnerie)
    test_sonnerie.grid(row = 4, column = 2, sticky="w")
    message_erreur = Label()
    message_erreur.grid(row = 5, column = 0, columnspan = 3, sticky="w")

    clock()
    restaurerParametres()
    root.protocol("WM_DELETE_WINDOW", quitter)
    root.mainloop()



    merci d'avance à ceux qui auront eu la patience de tout lire, et éventuellement de me donner un coup de main :)
    • Re: Problème d'arret du programme

      Envoyé par fraoustin le 17 Novembre 2006 à 13:05
      quand tu arrêtes tu vois quoi comme print:
      print "mixer arrette"
      print "arret"

      ?
    • Re: Problème d'arret du programme

      Envoyé par jbj le 17 Novembre 2006 à 21:30
      Je les vois tous, sauf print "arret"
    • Re: Problème d'arret du programme

      Envoyé par skygreg le 19 Novembre 2006 à 11:37
      Normal que tu ne vois pas le print "arret", il est après le sys.exit

      Il faut que tu join() ton thread avant de quitter le prog
      • Re: Problème d'arret du programme

        Envoyé par jbj le 21 Novembre 2006 à 21:26
        skygreg" a écrit:
        Normal que tu ne vois pas le print "arret", il est après le sys.exit

        Il faut que tu join() ton thread avant de quitter le prog


        Salut,
        A quel endoit du programme je dois utiliser cette méthode? J'ai essayé au endroits qui me semblaient le plus logique, mais le programme freeze.
        Merci pour ton aide!
    • Re: Problème d'arret du programme

      Envoyé par jbj le 19 Novembre 2006 à 11:42
      merci pour l'aide! Aurais tu un exemple pour illustrer ton propos?
      merci d'avance, bon dimanche à toi :)
    • Re: Problème d'arret du programme

      Envoyé par jbj le 21 Novembre 2006 à 22:26
      J'ai trouvé un moyen, mais c'est crade:
      def quitter():
      global test
      global t
      test=False #arret du thread
      try:
      if t.isAlive():
      t._Thread__stop()
      except: pass
      if (pygame.mixer.get_busy()):
      pygame.mixer.stop() #arret du mixer
      root.destroy() #destruction de la fenetre
      sys.exit(0) #arret du programme

      Si qqun à une meilleure façon de faire (ce que je ne doute pas!) je suis preneur!
    • Re: Problème d'arret du programme

      Envoyé par skygreg le 22 Novembre 2006 à 08:39
      Il faut que tu mettes ton myThread dans une variable globale, et pour quitter ton prog il faut mettre myThread.test à False, puis t.join() après le "if t.isAlive()"

      Tu y es presque en faite :)

      myThread tourne en boucle, il n'a donc jamais l'occasion de s'arreter sauf si self.test=False
    • Re: Problème d'arret du programme

      Envoyé par jbj le 22 Novembre 2006 à 09:01
      Merci skygreg! C'est la premiere fois que j'ai à utiliser des Threads donc je suis un peu perdu ;)
      Je vais faire ça cet aprem, je posterais le résultat, desfoi que ça puisse interesser qqun.
    • Re: Problème d'arret du programme

      Envoyé par jbj le 22 Novembre 2006 à 17:54
      Voilà, c'est terminé et ça marche nikel.
      Un grand merci à skygreg pour son aide avec le thread!
      Voici le code, desfois qu'il puisse interesser quelqu'un. Il s'agit d'un réveil jouant le fichier wav ou ogg de votre choix.


      #!/usr/env python
      # -*- coding: utf-8 -*-

      from Tkinter import *
      import time, string, sys, tkFileDialog, threading, pygame.mixer, ConfigParser

      class myThread(threading.Thread):
      def __init__(self, string_heureDeSonnerie):
      threading.Thread.__init__(self, target=self.run, args=())
      self.string_heureDeSonnerie = string_heureDeSonnerie
      self.test=True
      self.start()

      def run(self):
      while(self.test):
      heure_courante = time.strftime("%H:%M:%S")
      if (self.string_heureDeSonnerie == heure_courante):
      pygame.mixer.init()
      sound = pygame.mixer.Sound(musique)
      sound.play(-1)
      self.test=False
      else:
      time.sleep (1)



      def clock():
      """Donne l'heure courante au format hh:mmm:ss et l'affiche"""
      temps = time.strftime("%H:%M:%S")
      heure_actuelle.config(text=temps)
      root.after(200, clock)

      def activer():
      global t
      """Vérifie que les parametres necessaires sont corrects et active le réveil"""
      if (activer.cget("text") == "Activer"):
      hours = heure.get()
      mins = minutes.get()
      if (hours.isdigit()== False or int(hours) > 23):
      erreur("Heures: paramètres invalides")
      elif (mins.isdigit() == False or int(mins) > 59):
      erreur("Minutes: paramètres invalides")
      elif (musique == ""):
      erreur("Aucune sonnerie définie")
      else:
      erreur("parametres: ok")
      heure_sonnerie = hours+':'+mins+':'+'00'
      sauverParametres()
      t = myThread(heure_sonnerie)
      etat.config(text="Etat: Sonnera à "+heure_sonnerie[0:5])
      activer.config(text="Stopper")

      elif (activer.cget("text") == "Stopper"):
      if (pygame.mixer.get_busy()):
      pygame.mixer.stop()
      t.test = False
      etat.config(text="Etat: Inactif")
      activer.config(text="Activer")

      def choisirSonnerie():
      """permet de choisir la sonnerie du réveil"""
      global musique
      musique = tkFileDialog.askopenfilename()
      #TODO: vérifier que le fichier est bien une musique
      if (musique.endswith(".wav") or musique.endswith(".org")):
      s.config(text = "Sonnerie: "+str(musique))
      erreur("Sonnerie: ok")
      else:
      musique =""
      erreur("Seuls les formats wav et ogg sont acceptés")

      def erreur(string_erreur):
      """Affiche l'erreur correspondante"""
      message_erreur.config(text=string_erreur)

      def testerSonnerie():
      """permet de tester la sonnerie"""
      if (test_sonnerie.cget("text") == "Tester la sonnerie"):
      if (musique ==""):
      erreur("Veuillez choisir une sonnerie.")
      else:
      pygame.mixer.init()
      sound = pygame.mixer.Sound(musique)
      sound.play(-1)
      test_sonnerie.config(text="Arretter le test")
      erreur("Sonnerie: en test")
      elif (test_sonnerie.cget("text") == "Arretter le test"):
      if (pygame.mixer.get_busy()):
      pygame.mixer.stop()
      erreur("")
      test_sonnerie.config(text="Tester la sonnerie")


      def restaurerParametres():
      """restaure les parametres présents dans le fichier 'config.ini' si présent"""
      global musique
      try:
      conf = ConfigParser.ConfigParser()
      conf.read("config.ini")
      conf_heures = conf.get("MAIN", "heures")
      heure.delete(0, END)
      heure.insert(END, conf_heures)
      conf_minutes = conf.get("MAIN", "minutes")
      minutes.delete(0, END)
      minutes.insert(END, conf_minutes)
      conf_sonnerie = conf.get("MAIN", "sonnerie")
      musique = conf_sonnerie
      s.config(text="Sonnerie: "+conf_sonnerie)
      except:
      creerFichier()

      def sauverParametres():
      """Enregistre les parametres dans le fichier 'config.ini'"""
      try:
      fichier = open("config.ini", "w")
      fichier.write("")
      fichier.close()
      conf = ConfigParser.ConfigParser()
      conf.read("config.ini")
      conf.add_section("MAIN")
      conf.set("MAIN", "heures", heure.get())
      conf.set("MAIN", "minutes", minutes.get())
      conf.set("MAIN", "sonnerie", musique)
      conf.write(open("config.ini","w"))
      except:
      erreur("Erreur dans l'enregistrement des paramètres")

      def creerFichier():
      try:
      conf = ConfigParser.ConfigParser()
      conf.add_section("MAIN")
      conf.set("MAIN", "heures", "")
      conf.set("MAIN", "minutes", "")
      conf.set("MAIN", "sonnerie", "")
      conf.write(open('config.ini','w'))
      except:
      erreur("Impossible de créer le fichier de sauvegarde")

      def quitter():
      global t
      try:
      t.test=False #arret du thread
      t.join()
      except NameError: pass #Ignorer l'erreur, le thread n'a pas été lancé
      if (pygame.mixer.get_busy()):
      pygame.mixer.stop() #arret du mixer
      root.destroy() #destruction de la fenetre
      sys.exit(0) #arret du programme

      musique = ""
      #GUI
      root = Tk()
      root.title("JBJ Wake-Up!")
      heure_actuelle = Label()
      heure_actuelle.grid(row=0, column=0, columnspan = 3, sticky="n")
      etat = Label(text="Etat: Inactif")
      etat.grid(row = 1, column = 0, columnspan=3, sticky="w")
      heure_reveil = Label(text="Heure de réveil: ")
      heure_reveil.grid(row = 2, column = 0, columnspan=2, sticky="w")
      frame= Frame()
      frame.grid(row =2, column =2, sticky="w")
      heure = Entry(frame, width=2)
      heure.grid( row = 0, column = 0, sticky="w")
      h = Label(frame, text="h")
      h.grid(row = 0, column = 1, sticky="w")
      minutes = Entry(frame, width=2)
      minutes.grid(row = 0, column = 2, sticky="w")
      s = Label(text="Sonnerie : Aucune")
      s.grid(row = 3, column = 0, columnspan =3, sticky ="w")
      activer = Button(text="Activer", command = activer)
      activer.grid(row = 4, column = 0, sticky="w")
      choix_sonnerie = Button(text = "Sonnerie", command = choisirSonnerie)
      choix_sonnerie.grid(row = 4, column = 1, sticky="w")
      test_sonnerie = Button(text="Tester la sonnerie", command = testerSonnerie)
      test_sonnerie.grid(row = 4, column = 2, sticky="w")
      message_erreur = Label()
      message_erreur.grid(row = 5, column = 0, columnspan = 3, sticky="w")

      clock()
      restaurerParametres()
      root.protocol("WM_DELETE_WINDOW", quitter)
      root.mainloop()

    • Re: Problème d'arret du programme

      Envoyé par jbj le 22 Novembre 2006 à 17:58
      Pour télécharger le fichier .py directement:
      http://jeanbaptiste.jung.free.fr/apps/reveil/reveil.py
Rendu par Ploneboard