ValueError: valore letterale non valido per int () con base 10: '' (Tkinter)

Sep 10 2020

Quando provo a eseguire questo codice, ValueErrorappare un alluso alla funzione numRandom. Ho pensato che Python potesse passare una rappresentazione di stringa di un int a un file int.

import tkinter
import random

window = tkinter.Tk()
window.geometry('600x500')

x = random.randint(1,300)
remainingTime = True
Attempts = 4

def numRamdom():
    global Attempts
    while Attempts > 0:
        numWritten = int(entryWriteNumber.get())
        if numWritten > x:
            lblClue.configure(text = 'Its a bigger number')
            Attempts = Attempts -1
        if numWritten < x:
            lblClue.configure(text = 'Its a smaller number')
            Attempts = Attempts -1
        if numWritten == x:
            lblClue.configure(text = 'Congratulations ;)')
            remainingTime = False
            return remainingTime, countdown(0)
        if Attempts == 0:
            remainingTime = False
            return remainingTime, countdown(0), Attempts, gameOver()

entryWriteNumber = tkinter.Entry(window)
entryWriteNumber.grid(column = 0, row = 1, padx = 10, pady = 10)

numRamdom()

window.mainloop()

Risposte

CoolCloud Sep 10 2020 at 21:43

Il problema è perché quando il codice viene eseguito, chiama direttamente numRamdom(), cioè inizialmente i widget di immissione sono vuoti e lo eseguono con quei widget di immissione vuoti e quindi l'errore. Quindi assegna solo un pulsante e un comando, come:

b = tkinter.Button(root,text='Click me',command=numRamdom)
b.grid(row=1,column=0)

Assicurati di dirlo prima del mainloop()dopo def numRamdom():. Il pulsante esegue la funzione solo quando si fa clic sul pulsante.

O se vuoi senza pulsanti, prova:

METODO 1:

root.after(5000,numRamdom) #after 5 sec it will execute function

Ma tieni presente che se l'utente non inserisce correttamente in 5 secondi, verrà visualizzato un errore.

METODO 2:

def numRamdom(event):
......

entryWriteNumber.bind('<Return>',numRamdom)

Questo è così che, se si preme il tasto Invio nel widget della voce (dopo aver inserito i dati) verrà eseguita la funzione.

Spero che questo aiuti, fammi sapere se ci sono errori.

Saluti

SanguineL Sep 10 2020 at 21:53

Ecco un esempio completamente funzionante basato sul tuo codice. Il tuo problema stava tentando di convertire il contenuto della voce prima che ci fosse qualcosa al suo interno. Per risolvere questo problema, puoi aggiungere un pulsante che richiama il comandonumRamdom()

import tkinter
import random

window = tkinter.Tk()
window.geometry('600x500')

x = random.randint(1,300)
remainingTime = True
Attempts = 4

def numRamdom():
    global Attempts, lblClue, x
    if Attempts > 0:
            numWritten = int(entryWriteNumber.get())
            if numWritten < x:
                lblClue.configure(text = 'Its a bigger number')
                Attempts = Attempts -1
            elif numWritten > x:
                lblClue.configure(text = 'Its a smaller number')
                Attempts = Attempts -1
            else:
                lblClue.configure(text = 'Congratulations ;)')
                remainingTime = False
                #return remainingTime, countdown(0)
            if Attempts == 0:
                remainingTime = False
                #return remainingTime, countdown(0), Attempts, gameOver()
    else:
        lblClue.configure(text = "You ran out of attempts!")

entryWriteNumber = tkinter.Entry(window)
entryWriteNumber.grid(column = 0, row = 1, padx = 10, pady = 10)

entryWriteButton = tkinter.Button(window, text = "Push me!", command = numRamdom)
entryWriteButton.grid(column = 1, row = 1)

lblClue = tkinter.Label(window)
lblClue.grid(row = 2, column = 1)


window.mainloop()

Riceverai comunque un errore se il valore passato non può essere convertito in un numero intero, ma è facile risolverlo con ifun'istruzione.