Tkinter回调中的异常:由于循环在后台继续,所以不包括特殊字符或引号。

2024-10-02 22:32:19 发布

您现在位置:Python中文网/ 问答频道 /正文

大家好,来自论坛的各位

我现在是python和编程的初学者,所以请不要对我大喊大叫:)我知道我有很多全局变量,犯了很多错误。在

我正面临一个可怕的不结束循环问题,它不会真正影响我的tkinter窗口本身,但是当关闭它时,很遗憾在tkinter回调问题中看到这个异常。在

实际上,我不知道为什么Valider()函数中的batman变量没有结束所有这些循环 有人能帮我做这个吗?在

注:抱歉代码中有法语 谢谢

以下是源代码:

    from tkinter import*
from random import* 
import time 
from tkinter import messagebox
from tkinter import ttk

#Initialisation des variables
bonne_reponse=0
mauvaise_reponse=0
nbr_total=0
batman=False
nbr_q=10 # 10 question 

t=10 # t est definit le temps que l'utilisateur a pour repondre a la question



#_______________Fonction qui genere 2 nombres au hasard dans des intervalles differents selon la difficultee choisie__________________________#



def Division ():
    nbr1 = randint (1,9) 
    nbr2 = randint (1,9)
    div=nbr1*nbr2
    calcul_affiche  = ("CALCUL : " + str(div) + "/" + str(nbr2) + " =")
    label1.configure(text=calcul_affiche)
    calcul=nbr1
    return calcul





##### Fonction qui demarre le programme et donc qui lance la barre de progression lors du clic sur "Demarrer". 

def Démarrer():
    global reponse_final
    global batman
    batman=False

    reponse_final=Division()
    start_time=time.time()

    # defini un temps de demarrage car le module time compte le temps depuis 1974
    while batman==False:
        now =t-((time.time())-(start_time))
        root.update()
        #Redefini la valeur de la barre de progression
        wq=(now/t)*100
        progress["value"] = wq
        # Fausse le resultat apres le temps ecoule (avec un calcul improbable) 
        if wq<=0:
            batman=True
    if batman==True:
        Valider()



##### Fonction de validation

def Valider(): 
    global bonne_reponse
    global mauvaise_reponse
    global nbr_total
    global batman 
    utilisateur_reponse=entryWidget.get() #recupere la valeur de la boite d'entree
    entryWidget.delete(0, END) #supprime ce qu'il y a dans la barre d'entree
    # empeche l'utlisateur d'entrer des lettres dans la boite d'entrée 
    batman=True 
    try:  
        if reponse_final != int(utilisateur_reponse):
            titre="Réponse"
            bon_rep=str("Mauvaise réponse ! La bonne réponse était: "+str(reponse_final))
            messagebox.showinfo(titre, bon_rep)
            mauvaise_reponse+=1
            nbr_total+=1

        elif reponse_final== int(utilisateur_reponse):
            #messagebox.showinfo("Réponse", "Bonne réponse!")
            bonne_reponse+=1
            nbr_total+=1
    except:
        messagebox.showerror("Boite d'entrée", "Temps ecoulé ou Entrez uniquement des nombres")
        mauvaise_reponse+=1
        nbr_total+=1
    #on arrete le jeux lorsque le nombre de question souhaité est atteint   
    if nbr_total==nbr_q:
        exitnote()   
    Démarrer()




######################Création fenetre principale Tkinter "root" ###################

root = Tk()
root.title("Calcul Mental")
root.configure(bg="gainsboro")
root["padx"] = 60
root["pady"] = 40

# On definit un style et un theme pour les widgets
s = ttk.Style()
s.theme_use('clam')


# Creation du label correspondant a la consigne en debut de page
consigne= ("Cliquez sur démarrer pour commencer. Un nombre illimité de calculs va vous être proposé.")
instructions = ttk.Label(root, text=consigne)
instructions.pack()

label_trait4= ttk.Label(root, text="--------------------------------------------------------------------------------------------------")
label_trait4.pack()

# Création de la barre de progression
s.configure("blue.Horizontal.TProgressbar", foreground='aquamarine3', background='aquamarine3')
progress = ttk.Progressbar(root, style="blue.Horizontal.TProgressbar", orient="horizontal", length=500, mode="determinate")
progress["maximum"] = 100
progress.pack()


### Création d'une boite de texte pour un label texte et la boite d'entree 
text_boite= Frame(root)

# Création du label de calcul 
label1 = ttk.Label(text_boite, background="white", width=15)
label1["text"] = ""
label1.pack(side=LEFT)


# Création d'un Entry Widget dans text_boite
entryWidget = ttk.Entry(text_boite)
entryWidget['width'] = 50
entryWidget.pack(side=RIGHT)

text_boite.pack()


# Bouton valider
root.bind("<Return>", lambda event: Valider())

btn_valider = ttk.Button(root, text="Valider", command=Valider)
# fait en sorte que quand l'utilisateur appui sur la touche entrer ca lance la fonction valider. 


# On rend inutilisable le bouton demarrer apres le 1er clic
def btndemarrer():
    btn_démarrer.config(state=DISABLED)
    instructions.destroy()
    Démarrer()

btn_démarrer = ttk.Button(root, text="Démarrer", command = btndemarrer)
btn_démarrer.pack()

# Affiche la note dans une boite et detruit la fenetre
def exitnote():
    global batman
    batman=True
    try:
        note=(bonne_reponse*20/nbr_total)
        w=("Votre note est de "+str(note)+"/20.0 ")
        messagebox.showinfo("Voici votre note",str(w))
        root.destroy()

    # Si note n'est pas definit car l'utilisateur n'a pas encore appuye sur Entrer, on affiche le message suivant:
    except:  
        messagebox.showinfo("DEVNOTE","Je respecte votre choix mais vous n'avez meme pas essayé.")
        root.destroy()

btn_valider.pack()
btn_arret = ttk.Button(root, text="Arrêt", command=exitnote)
btn_arret.pack()

# On lance la boucle Tkinter qui s'interompt lors de la fermeture de la fenetre 
root.mainloop()

以下是例外:

^{pr2}$

Tags: textletimederootgloballapack
1条回答
网友
1楼 · 发布于 2024-10-02 22:32:19

好吧,这里有两件事:

1)根据上面的代码,Valider()函数不需要参数,因此您可以简单地绑定而不使用lambda

root.bind('<Return>', Valider)

2)当按钮/返回被触发,并且你的Valider()被调用时,据我所知,对触发事件的引用会被传递(至少在wxPython中是这样做的,短时间的google为tkinter提供了相同的方法)。在

这意味着您的已触发函数(在本例中为Valider())也必须处理该引用。根据这一点,您的Valider()定义应该如下所示:

^{pr2}$

以这种方式定义Valider()可以处理对触发函数的事件的传入引用,但可以使用

Valider()

因为event参数的默认值设置为None

希望有帮助。 格里兹:-)

相关问题 更多 >