Partage
  • Partager sur Facebook
  • Partager sur Twitter

Attendre bouton appuyer-tkinter

Crible Eratosthène-tkinter

Sujet résolu
    2 octobre 2022 à 10:43:31

    Bonjour,

    j'ai créé une interface graphique pour illustrer le Crible d'Eratosthene avec tkinter.

    J'aimerais que l'algorithme patiente jusqu'à appuyer sur un bouton "continuer", j'ai essayé plusieurs choses sans succès.

    Merci pour votre aide.

    from tkinter import*
    
    fenetre = Tk()
    fenetre.title("Crible d'Eratosthene")
    fenetre.resizable(False,False)
         
    interface = Canvas(fenetre,width=505,height=600,bg="white")
    interface.pack()
    
    
    interface.create_rectangle(0,0,505,505,fill="black")
    for i in range(10) :
        for j in range(10) :
            interface.create_rectangle(50*j+7,50*i+7,50*j+50,50*i+50,fill="white")
            interface.create_text(27.5+50*j,27.5+50*i,text=j+1+10*i)
    
    presse=False
    
    def bouton() :
        global presse
        presse=True
    
    def decomposition(i) :
        p=i//10
        q=i-10*p
        if q==0 :
            p,q=p-1,9
        else :
            q=q-1
        return q,p
    
    L=[]
    for i in range(1,101) :
        L+=[i]
    
    P='Nombres premiers :'
    
    
    x=1
    
    
        
    def premier() :
        global L,P,x,presse
        while len(L)!=0:
            if 1 in L :
                interface.create_rectangle(7,7,50,50,fill="gray")
                interface.create_text(27.5,27.5,text=1,fill="black",font=("arial",15))
                del L[0]
                while bouton()==False :
                    pass
                presse=False
            else :
                i=L[0]
                x=i
                P['text']=P['text']+' '+str(i)
                del L[0]
                u,v=decomposition(i)        
                interface.create_rectangle(50*u+7,50*v+7,50*u+50,50*v+50,fill="red")
                interface.create_text(27.5+50*u,27.5+50*v,text=i,fill="black",font=("arial",30))
                while bouton()==False :
                    pass
                presse=False
                for j in L :
                    if j%x==0 :
                        del L[L.index(j)]
                        u,v=decomposition(j)
                        interface.create_rectangle(50*u+7,50*v+7,50*u+50,50*v+50,fill="gray")
                        interface.create_text(27.5+50*u,27.5+50*v,text=j,fill="black",font=("arial",15))
                        while presse==False :
                            pass
                        presse=False
    
    
    P=Label(fenetre)
    P.place(x=10,y=550)
    
    Valider=Button(fenetre,text='Premiers',command=premier)
    Valider.place(x=150,y=520)
    
    Continuer=Button(fenetre,text='Continuer',command=bouton)
    Continuer.place(x=250,y=520)
    
    
    Quitter=Button(fenetre,text='Quitter',command=fenetre.destroy)
    Quitter.place(x=200,y=575)
    
    fenetre.mainloop()



    • Partager sur Facebook
    • Partager sur Twitter
      2 octobre 2022 à 11:36:00

      Bonjour,

      Déjà, il y a des bugs

      Quand on appuie sur le bouton Premiers, on tombe dans une boucle infinie ligne 70 ...

      Ligne 63 : presse = False

      donc ligne 70 : tant que presse == False ................ on tourne, on tourne

      Ligne 50 tu testes la valeur de bouton(), mais ta fonction bouton() ne retourne rien

      -
      Edité par Phil_1857 2 octobre 2022 à 11:46:16

      • Partager sur Facebook
      • Partager sur Twitter
        2 octobre 2022 à 11:45:22

        Merci pour votre réponse.

        Oui en effet, lorsqu'on appuie sur le bouton "premiers" le bouton reste allumé et ça boucle. Cependant si j'enlève :

        while presse==False :
             pass
             presse=False

        Cela fonctionne parfaitement et le programme affiche les nombres premiers en rouge et élimine les autres. Mais je souhaiterais qu'il fasse des pauses à certains endroits en attendant qu'un bouton soit pressé.

        • Partager sur Facebook
        • Partager sur Twitter
          2 octobre 2022 à 11:51:38

          Et le bug de la ligne 50 ? (regarde mon message à nouveau)

          qu'il fasse des pauses à certains endroits

          ok, à quels endroits ?

          • Partager sur Facebook
          • Partager sur Twitter
            2 octobre 2022 à 11:55:10

            J'ai rajouté un "return b" dans bouton(), mais il boucle encore...

            from tkinter import *
            
            
            fenetre = Tk()
            fenetre.title("Crible d'Eratosthene")
            fenetre.resizable(False,False)
                 
            interface = Canvas(fenetre,width=505,height=600,bg="white")
            interface.pack()
            
            
            interface.create_rectangle(0,0,505,505,fill="black")
            for i in range(10) :
                for j in range(10) :
                    interface.create_rectangle(50*j+7,50*i+7,50*j+50,50*i+50,fill="white")
                    interface.create_text(27.5+50*j,27.5+50*i,text=j+1+10*i)
            
             
            
            def bouton() :
                global b
                b=1
                return b
            
            def decomposition(i) :
                p=i//10
                q=i-10*p
                if q==0 :
                    p,q=p-1,9
                else :
                    q=q-1
                return q,p
            
            L=[]
            for i in range(1,101) :
                L+=[i]
            
            P='Nombres premiers :'
            b=0
            x=1
            
            
                
            def premier() :
                global L,P,x,b
                while len(L)!=0:
                    if 1 in L :
                        interface.create_rectangle(7,7,50,50,fill="gray")
                        interface.create_text(27.5,27.5,text=1,fill="black",font=("arial",15))
                        del L[0]
                        while b==0 :
                            b=0
                        b=0
                    else :
                        i=L[0]
                        x=i
                        P['text']=P['text']+' '+str(i)
                        del L[0]
                        u,v=decomposition(i)        
                        interface.create_rectangle(50*u+7,50*v+7,50*u+50,50*v+50,fill="red")
                        interface.create_text(27.5+50*u,27.5+50*v,text=i,fill="black",font=("arial",30))
                        while b==0 :
                            b=0
                        b=0
                        for j in L :
                            if j%x==0 :
                                del L[L.index(j)]
                                u,v=decomposition(j)
                                interface.create_rectangle(50*u+7,50*v+7,50*u+50,50*v+50,fill="gray")
                                interface.create_text(27.5+50*u,27.5+50*v,text=j,fill="black",font=("arial",15))
                                while b==0 :
                                    b=0
                                b=0
            
            P=Label(fenetre)
            P.place(x=10,y=550)
            
            Valider=Button(fenetre,text='Premiers',command=premier)
            Valider.place(x=150,y=520)
            
            Continuer=Button(fenetre,text='Continuer',command=bouton,)
            Continuer.place(x=250,y=520)
            
            
            Quitter=Button(fenetre,text='Quitter',command=fenetre.destroy)
            Quitter.place(x=200,y=575)
            
            fenetre.mainloop()

            Je souhaiterais qu'il fasse des pauses après affichage de chaque nombres premiers et l'élimination de chaque nombres non premiers.



            • Partager sur Facebook
            • Partager sur Twitter
              2 octobre 2022 à 12:01:26

              Moi, je verrais bien une solution

              Créer une variable tkinter : var = IntVar()

              dans la définition du bouton Continuer, tu remplaces command = bouton par command = une fonction lambda pour initialiser var

              et dans ta boucle for ligne 65, tu ajoutes l'attente de l'initialisation de var : interface.wait_variable(var)

              Tant qu'on ne clique pas le bouton, la boucle attend, et redémarre à chaque clic

              • Partager sur Facebook
              • Partager sur Twitter
                2 octobre 2022 à 14:18:33

                Merci cela fonctionne maintenant.

                Bonne journée.

                • Partager sur Facebook
                • Partager sur Twitter
                  2 octobre 2022 à 16:53:53

                  Super !

                  Mais ton code fait un peu fouillis

                  Tu devrais mettre dans cet ordre :

                  imports

                  définition de fonctions

                  initialisation de variables

                  création de la fenêtre et des boutons

                  from tkinter import*
                   
                  def decomposition(i):
                      p=i//10
                      q=i-10*p
                  
                      if q==0 :
                          p,q=p-1,9
                      else :
                          q=q-1
                  
                      return q,p
                  
                  def premier() :
                      global L,P,x
                  
                      while len(L)!=0:
                          if 1 in L :
                              interface.create_rectangle(7,7,50,50,fill="gray")
                              interface.create_text(27.5,27.5,text=1,fill="black",font=("arial",15))
                              del L[0]
                  
                          else :
                              i=L[0]
                              x=i
                              P['text']=P['text']+' '+str(i)
                              del L[0]
                              u,v=decomposition(i)       
                              interface.create_rectangle(50*u+7,50*v+7,50*u+50,50*v+50,fill="red")
                              interface.create_text(27.5+50*u,27.5+50*v,text=i,fill="black",font=("arial",30))
                  
                              for j in L :
                                  if j%x==0 :
                                      del L[L.index(j)]
                                      u,v=decomposition(j)
                                      interface.create_rectangle(50*u+7,50*v+7,50*u+50,50*v+50,fill="gray")
                                      interface.create_text(27.5+50*u,27.5+50*v,text=j,fill="black",font=("arial",15))
                          interface.wait_variable(var)
                  
                  L=[i for i in range(1,101)]
                  x=1
                  
                  fenetre = Tk()
                  fenetre.title("Crible d'Eratosthene")
                  fenetre.resizable(False,False)
                        
                  interface = Canvas(fenetre,width=505,height=600,bg="white")
                  interface.pack()
                  
                  interface.create_rectangle(0,0,505,505,fill="black")
                  for i in range(10) :
                      for j in range(10) :
                          interface.create_rectangle(50*j+7,50*i+7,50*j+50,50*i+50,fill="white")
                          interface.create_text(27.5+50*j,27.5+50*i,text=0)
                  
                  P=Label(fenetre)
                  P.place(x=10,y=550)
                  
                  var = IntVar()
                  
                  Valider=Button(fenetre,text='Premiers',command=premier)
                  Valider.place(x=150,y=520)
                   
                  Continuer=Button(fenetre,text='Continuer',command=lambda: var.set(1))
                  Continuer.place(x=250,y=520)
                  
                  Quitter=Button(fenetre,text='Quitter',command=fenetre.destroy)
                  Quitter.place(x=200,y=575)
                   
                  fenetre.mainloop()



                  • Partager sur Facebook
                  • Partager sur Twitter
                    4 octobre 2022 à 23:42:46

                    Bonjour,

                    j'ai remis de l'ordre, j'ai ajouté un paramètre pour le nombre de colonnes dans le tableau et une explication de chaque étape. Merci encore et bonne soirée.

                    from tkinter import *
                    
                     
                    ##nombre de colonnes :
                    n=10
                    
                       
                    def decomposition(i) :
                        p=i//n
                        q=i-n*p
                        if q==0 :
                            p,q=p-1,n-1
                        else :
                            q=q-1
                        return q,p
                    
                    
                    
                    P='Nombres premiers :'
                    Affiche=''
                    
                    
                        
                    def premier() :
                        global L,P,var,Affiche
                        Valider.destroy()
                        Continuer=Button(fenetre,text='Continuer',command=lambda:var.set(1))
                        Continuer.place(x=45*n/2,y=520)
                        while len(L)!=0:
                            if 1 in L :
                                interface.create_rectangle(7,7,50,50,fill="gray")
                                interface.create_text(27.5,27.5,text=1,fill="black",font=("arial",15))
                                Affiche['text']="1 n'est pas premier"
                                del L[0]
                                interface.wait_variable(var)
                            else :
                                i=L[0]
                                P['text']=P['text']+' '+str(i)
                                Affiche['text']=str(i)+" "+"est premier"
                                del L[0]
                                u,v=decomposition(i)        
                                interface.create_rectangle(50*u+7,50*v+7,50*u+50,50*v+50,fill="red")
                                interface.create_text(27.5+50*u,27.5+50*v,text=i,fill="black",font=("arial",30))
                                interface.wait_variable(var)
                                for j in L :
                                    if j%i==0 :
                                        del L[L.index(j)]
                                        Affiche['text']=str(j)+" "+"est un multiple de"+" "+str(i)+" "+"donc"+" "+str(j)+" "+"n'est pas premier" 
                                        u,v=decomposition(j)
                                        interface.create_rectangle(50*u+7,50*v+7,50*u+50,50*v+50,fill="gray")
                                        interface.create_text(27.5+50*u,27.5+50*v,text=j,fill="black",font=("arial",10))
                                        interface.wait_variable(var)
                    
                    L=[]
                    for i in range(1,10*n+1) :
                        L+=[i]
                                        
                    fenetre = Tk()
                    fenetre.title("Crible d'Eratosthene")
                    fenetre.resizable(False,False)
                    
                    
                    
                    interface = Canvas(fenetre,width=50.5*n,height=675,bg="white")
                    interface.pack()
                    
                    
                    
                    interface.create_rectangle(0,0,51*n,505,fill="black")
                    for i in range(10) :
                        for j in range(n) :
                            interface.create_rectangle(50*j+7,50*i+7,50*j+50,50*i+50,fill="white")
                            interface.create_text(27.5+50*j,27.5+50*i,text=j+1+n*i)
                    
                    
                    
                    
                    
                    
                    Affiche=Label(fenetre,font=("arial",20),wraplength=50*n)
                    Affiche.pack()
                    
                    
                    P=Label(fenetre,font=("arial",25),wraplength=50*n)
                    P.place(x=10,y=550)
                    
                    var=IntVar()
                    
                    Valider=Button(fenetre,text='Premiers',command=premier)
                    Valider.place(x=45*n/2,y=520)
                    
                    Quitter=Button(fenetre,text='Quitter',command=fenetre.destroy)
                    Quitter.place(x=45*n/2,y=650)
                    
                    fenetre.mainloop()



                    • Partager sur Facebook
                    • Partager sur Twitter
                      5 octobre 2022 à 12:59:01

                      Bonjour

                      remis, de l'ordre, faut voir ...

                      les lignes 19 et 20 sont inutiles (je les avait supprimées du code que je t'ai donné)

                      n=0 devrait être en ligne 57

                      les lignes 27 et 28 doivent être après la ligne 90

                      #nombre de colonnes :
                      n=10
                      L=[i for i in range(1,10*n+1)]

                       J'ai testé ton code, il n'y a plus que le chiffre 2 qui s'affiche ...

                      Le sujet n'est pas résolu du tout


                      -
                      Edité par Phil_1857 5 octobre 2022 à 13:19:36

                      • Partager sur Facebook
                      • Partager sur Twitter
                        6 octobre 2022 à 19:47:49

                        C'est rigolo parce que chez moi, ça marche parfaitement et également sur d'autres ordinateurs. 

                        En tout cas, vous avez répondu à mes attentes, merci.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          7 octobre 2022 à 13:25:55

                          Bonjour,

                          Chez moi, seul le chiffre 2 s'affiche, ensuite quand on appuie sur continuer, il ne se passe plus rien

                          par contre le code que j'ai donné précedemment marche bien ...

                          • Partager sur Facebook
                          • Partager sur Twitter
                            7 octobre 2022 à 14:59:10

                            J'ai testé le code de Jules et il fonctionne correctement chez moi aussi (win10) 

                            Peut-être une différence lié à l'OS ? 

                            • Partager sur Facebook
                            • Partager sur Twitter
                              7 octobre 2022 à 17:46:27

                              Bonjour Umfred,

                              Qu'entends-tu par "il fonctionne" ?

                              J'ai à nouveau copié/collé son code tel quel, sans rien y changer, à chaque fois que l'on clique sur continuer, on ne parcourt que les nb pairs, et donc ça donne ça (je suis sur Win10) :

                              (mais peut-être est-ce ce qu'il voulait ?)

                              -
                              Edité par Phil_1857 7 octobre 2022 à 17:47:51

                              • Partager sur Facebook
                              • Partager sur Twitter
                                7 octobre 2022 à 17:56:37

                                donc ça fonctionne, il élimine les nombres multiples du nombre premier trouvé, donc on commence par supprimer tous les multiples de 2, si tu continues ensuite ça passe au 3 en nombre premier puis élimine les multiples de 3, etc, ce qui correspond au crible d'Eratosthene  https://www.larousse.fr/encyclopedie/divers/crible_d_%C3%89ratosth%C3%A8ne/49083

                                -
                                Edité par umfred 7 octobre 2022 à 17:58:16

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  7 octobre 2022 à 18:06:52

                                  Bonjour,

                                  ah ok, je m'étais arrêté à 100 :-)

                                  Mais bon, le code reste un peu désordonné, plein de ligne vides,

                                  l'initialisation de n au début,

                                  et les 2 lignes inutiles : 19 et 20 

                                  -
                                  Edité par Phil_1857 7 octobre 2022 à 18:10:16

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    7 octobre 2022 à 18:20:56

                                    peut-être possibilité de faire autrement, je ne me suis pas penché sur la question.

                                    Je pense une légère amélioration serait d'éviter de recréer les rectangles et leur texte, mais de les maintenir dans une variable (une pour les rectangles, une pour les textes): 
                                    #à la création
                                    rectangles[j+i*10]= interface.create_rectangle(..)
                                    textes[j+i*10]=interface.create_text(..)
                                    
                                    #pour modifier
                                    interface.itemconfig(rectangles[i],fill="gray")
                                    interface.itemconfig(textes[i],fill="black",font=("arial",10)) #à vérifier

                                    -
                                    Edité par umfred 7 octobre 2022 à 19:02:20

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Attendre bouton appuyer-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