Beginners Problem! NameError on python tkinter - python

New to python so this is probably a dumb question...
I want to say that if text1.get() == "1" then x = 0 and if text2.get() = "2" then y = 8. Then I want a button that adds x and y.
from tkinter import *
new = Tk()
new.title("Lockdown?")
new.geometry("700x400")
text3=Entry(new, width = "60")
text3.place(rely=0.15)
if text3.get() == "":
label9 = Label(new, text="required field", fg="red")
label9.place(rely=0.17)
elif text3.get() == "1":
x = "0"
elif text3.get() == "2":
x = "1"
elif text3.get() == "10":
x = "9"
else:
label10 = Label(new, text = "Please use a number ranging from 1-10")
text4=Entry(new, width = "60")
text4.place(rely=0.26)
if text4.get() == "":
label11 = Label(new, text="Required Field", fg = "red")
label11.place(rely=0.19)
elif text4.get() == "7":
y = "3"
elif text4.get() == "8":
y = "2"
elif text4.get() == "9":
y = "1"
elif text4.get() == "10":
y = "0"
else:
label11 = Label(new, text = "Please use a number ranging from 1-10")
def cmd3():
label15 = Label(new, text = x + y)
label15.place(rely=0.8)
btn3 = Button(new, text = "Submit Answers", command = cmd3, font=("Arial Bold", 25), bg = "white", fg = "black")
btn3.place(rely=0.71)
new.mainloop()

GUI frameworks (tkinter, PyQt, wxPython, etc., and in other languages) don't work like function input(). Entry doesn't wait for your data - it only inform mainloop what it has to display in window. And mainloop starts all - it displays window, etc. If you want to get value from Entry then you should do it in function assigned to Button.
My version with other changes
I use pack() instead of place() because it is simpler to organize widgets.
I create all labels at start (with empty text) and later I replace text in labels.
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def cmd3():
# default value at start
x = None
y = None
# remove previous text
label1['text'] = ""
label2['text'] = ""
text = text1.get()
if text == "":
label1['text'] = "required field"
elif text == "1":
x = 0
elif text == "2":
x = 1
elif text == "10":
x = 9
else:
label1['text'] = "Please use a number ranging from 1-10"
text = text2.get()
if text == "":
label2['text'] = "required field"
elif text == "7":
y = 3
elif text == "8":
y = 2
elif text == "9":
y = 1
elif text == "10":
y = 0
else:
label2['text'] = "Please use a number ranging from 1-10"
print(x, y)
# it can't be `if x and y:` because `0` will gives `False`
if (x is not None) and (y is not None):
label_result['text'] = str(x + y)
# --- main ---
new = tk.Tk()
# empty at start
label1 = tk.Label(new, text="", fg="red")
label1.pack()
text1 = tk.Entry(new, width="60") # PEP8: arguments without spaces around `=`
text1.pack()
# empty at start
label2 = tk.Label(new, text="", fg="red")
label2.pack()
text2 = tk.Entry(new, width="60")
text2.pack()
btn3 = tk.Button(new, text="Submit Answers", command=cmd3)
btn3.pack()
# empty at start
label_result = tk.Label(new, text="", fg="green")
label_result.pack()
new.mainloop()

Related

I wrote a simple chatterbot using tkinter in python, I'm wondering how I could do to improve it to make it easier to use and general make it better a?

I'm wrote a basic chatterbot and wondering what you would do to pretty much improve it and make it better then this?
Because I want this chatterbot to be the best it could be and I really want other people's opinion of how they would improve it.
Here is the code:
import tkinter as tk
# --- functions ---
def cmd3():
# default value at start
x = None
y = None
# remove previous text
label1['text'] = ""
label2['text'] = ""
text = text1.get()
if text == "":
label1['text'] = "Statement"
elif text == "Hello":
x = "Hello"
elif text == "Goodbye":
x = "Goodbye"
elif text == "Hi":
x = "Hello"
else:
label1['text'] = "Please enter a valid statement"
text = text2.get()
if text == "":
label2['text'] = "Question"
elif text == "How are You?":
y = "I'm going good"
elif text == "What is your name?":
y = "I'm Turing"
elif text == "When did your Creator start working on you?":
y = "In the year 2022"
elif text == "Do you like Star Wars?":
y = "Yes, I was actually inspired by the personallities from droids from Star Wars."
else:
label2['text'] = "please enter a valid question"
print(x, y)
if (x is not None) and (y is not None):
label_result['text'] = str(x + " " + y)
# --- main ---
new = tk.Tk()
label1 = tk.Label(new, text="", fg="red")
label1.pack()
text1 = tk.Entry(new, width="60")
text1.pack()
label2 = tk.Label(new, text="", fg="red")
label2.pack()
text2 = tk.Entry(new, width="60")
text2.pack()
btn3 = tk.Button(new, text="Enter", command=cmd3)
btn3.pack()
label_result = tk.Label(new, text="", fg="green")
label_result.pack()
new.mainloop()
I'll be so grateful for your help with this.

Tkinter keyboard simulator

I need the dif () function to compose text of different lengths from a dictionary depending on the complexity.
More precisely, I need to somehow change k when choosing the complexity.
def dif():
global start_time
message.pack()
text_widget.pack()
start_time = time.time()
global test_text
with open("words.txt", "r") as words:
test_words1 = choices(list(words), k)
len_word_list = [len(word.strip()) for word in test_words1]
index_nostrip1 = 6
end_of_line1 = 0
final_word_list1 = []
lines_list1 = []
line1 = ""
for i in range(len(test_words1)):
if end_of_line1 == index_nostrip1 - 1:
final_word_list1.append(test_words1[i])
line1 += test_words1[i].strip()
lines_list1.append(line1)
line1 = ""
end_of_line1 = 0
else:
final_word_list1.append(test_words1[i].strip())
line1 += f"{test_words1[i].strip()} "
end_of_line1 += 1
# create the final string to be used in the test
test_text = " ".join(final_word_list1)
text_widget = Text(root, height=10, width=100,
padx=20, pady=20, font=("Arial ", 16))
text_widget.insert(END, test_text)
text_widget.configure(state="disabled")
text_widget.tag_config("correct", background="green", foreground="white")
text_widget.tag_config("wrong", background="red", foreground="white")
text_widget.bind("<KeyPress>", key_type)
text_widget.focus()
The command1 () function is executed if the start button is pressed
def command1():
if var.get() == 0:
k=10
dif()
elif var.get() == 1:
k=15
dif()
elif var.get() == 2:
k=20
dif()
root.deiconify()
top.destroy()

How to update the gui while the program is running in tkinter?

Essentially I just want to update the grid on the GUI while the Tkinter program is running, the changes I want to make while the program is running are under the return true part in the function but I can't find how to do this.
import random
from tkinter import *
def input_validation(coordinates, user_input):
if coordinates [0] <0 or coordinates [1] <0 or coordinates [0] >2 or coordinates [1] >2:
pass
elif (int(user_input) == int(frame.grid_slaves(coordinates[0], coordinates[1])[0]['text'])):
return True
Label (frame, text = frame.grid_slaves(coordinates[0], coordinates[1])[0]['text']
).grid(row= previous_coordinates[0], column= previous_coordinates[1])
Label (frame, text = "").grid(row= coordinates[0], column= coordinates[1])
def button_click():
if (input_validation(coordinates_up, number_input.get()) == True):
pass
elif(input_validation(coordinates_left, number_input.get()) == True):
pass
elif(input_validation(coordinates_right, number_input.get()) == True):
pass
elif(input_validation(coordinates_down, number_input.get()) == True):
pass
else:
print("hello")
text_display.configure(text="Please input a number that is surrounding the empty space")
puzzle = Tk()
puzzle.title("Eight Puzzle")
frame = Frame(puzzle)
space_coordinates = [2,2]
frame.pack()
number_input= Entry(frame, width= 20)
number_input.grid(row = 5, column =7)
button = Button(frame, text="Enter", command = button_click)
button.grid(row = 6, column = 7)
number = 8
text_display = Label(frame, text="Input the number you want to move into the empty space \n *make sure the number is next to the empty space*", fg="red")
text_display.grid(row = 3, column = 7)
for i in range (0,3):
for a in range (0,3):
if number == 0:
Label (frame, text = " ").grid(row=i, column=a)
else:
Label (frame, text = number).grid(row=i, column=a)
number= number -1
previous_coordinates = []
previous_coordinates.append(space_coordinates[0])
previous_coordinates.append(space_coordinates[1])
coordinates_up = [previous_coordinates[0], previous_coordinates[1]-1]
coordinates_left = [previous_coordinates[0]-1, previous_coordinates[1]]
coordinates_right = [previous_coordinates[0]+1, previous_coordinates[1]]
coordinates_down = [previous_coordinates[0],previous_coordinates[1]+1]
You will need puzzle.mainloop() at the end of your tkinter program. Also, if you want to update the window mid-function, you can use: window.update()

How to update tkinter window every 4 seconds?

I am trying to create a program that reads lines from a file and puts them into a tkinter window. At the moment my code is this:
def read_notifications():
#def update():
# window.config(text=str(random.random()))
# window.after(1000, update)
aaa = 1
while True:
re = open("Y:/System Info/notifications.txt", "r")
rf = re.read()
rh = rf.count("\n")
re.close()
lines = [line.rstrip('\n') for line in open("Y:/System Info/notifications.txt")]
rk = -1
while True:
aaa = aaa + 2
rk = rk + 1
#print(lines[rk])
rl = rk + 1
ya = lines[rk].split("#")
yb = str(tomrt)
if ya[1] == yb:
yc = "Tommorow"
else:
if ya[1] == "0":
yc = "Monday"
if ya[1] == "1":
yc = "Tuesday"
if ya[1] == "2":
yc = "Wednesday"
if ya[1] == "3":
yc = "Thursday"
if ya[1] == "4":
yc = "Friday"
if ya[1] == "5":
yc = "Saturday"
if ya[1] == "6":
yc = "Sunday"
c = 650
window = tk.Tk()
#back = tk.Frame(width=700, height=c)
#back.pack()
window.title("Notifications")
window.iconbitmap("1235.ico")
#Subject
lbl = tk.Label(window, text=ya[0])
lbl.config(font=("Courier", 18))
lbl.grid(column=0, row=0)
#lbl.pack(side=tk.LEFT,)
#Day
lbl = tk.Label(window, text=" " + yc)
lbl.config(font=("Courier", 16))
lbl.grid(column=2, row=0)
#Type
lbl = tk.Label(window, text=ya[2])
lbl.config(font=("Courier", 16))
lbl.grid(column=4, row=0)
#Descripion
lbl = tk.Label(window, text=ya[4])
lbl.config(font=("Courier", 16))
lbl.grid(column=6, row=0)
#lbl.pack(side=tk.LEFT)
#window.after(1000, update)
if rl == rh:
print("hello")
break
if aaa > 2:
time.sleep(4)
window.destroy()
else:
window.mainloop()
I am not sure why this doesn't work properly. I am trying to make it so the tkinter window will update itself every 4 seconds, as another program is making changes to the notifications.txt file and I want the tkinter windows to update accordingly.
You code is a bit hard to re-work but here is a working example of how one can monitor a file.
Say I have a file that contains 4 lines and we call this file my_file:
1 test
2 testing
3 more testing
4 test again
All we want to do is update the labels ever 4 seconds so we can use the after() method to keep us going.
Take a look at this below code.
import tkinter as tk
window = tk.Tk()
window.title("Notifications")
file_to_monitor = "./my_file.txt"
def read_notifications():
with open(file_to_monitor, "r") as f:
x = f.read()
string_list = x.split("\n")
lbl1.config(text=string_list[0])
lbl2.config(text=string_list[1])
lbl3.config(text=string_list[2])
lbl4.config(text=string_list[3])
window.after(4000, read_notifications)
lbl1 = tk.Label(window, text="")
lbl1.grid(column=0, row=0, stick="w")
lbl2 = tk.Label(window, text="")
lbl2.grid(column=0, row=1, stick="w")
lbl3 = tk.Label(window, text="")
lbl3.grid(column=0, row=2, stick="w")
lbl4 = tk.Label(window, text="")
lbl4.grid(column=0, row=3, stick="w")
read_notifications()
window.mainloop()
What we start out with on the first read:
Then after I have made a change to the file and saved from my notepad:

Using Python to update labels Tkinter

I am in the process of making a Hangman type game. So far, I have written the CLI version which works well, i'm just porting it over to create a GUI.
I have become stuck :-(. The program is not complete, and there's still more to do but I have two issues. The first is the label update.
When a letter is chosen, it creates enough dashes for the letter, and places this in a label called 'letter'.
When a user enters a letter, it replaces the dashes, however it then adds a new label next to the old label, instead, I would like to replace this label. I have tried using the .set() but this doesn't seem to work.
My second issue, and this is more of a logic error (I think), is that I wanted to keep track of the letters entered so that I could compare this to newly entered letters and alert the user. This works well, however when a letter has been entered it will warn the user even if its the first time it has been typed.
Here's the code:
import tkinter
from tkinter import *
from tkinter import messagebox
import random
guesses = 8
def play():
print("play game")
wordList = ["talking", "dollar","choice", "famous", "define", "features"]
wordChoice = random.choice(wordList)
print(wordChoice)
wordLength = (len(wordChoice))
print(wordLength)
guessedLetters = []
dashes = []
def enterLetter():
print("Guess")
global guesses
print(guessedLetters)
while guesses != 0:
guess = entry.get().lower()
if len(guess) >1:
messagebox.showinfo("Error","Sorry, only one letter at a time")
entry.delete("0","end")
return
elif guess.isalpha() == False:
messagebox.showinfo("Error","Letters only please")
entry.delete("0","end")
return
elif guess in guessedLetters:
messagebox.showinfo("Error","You have already used the letter")
entry.delete("0","end")
return
guessedLetters.append(guess)
print(guessedLetters)
print(guesses)
count = 0
for i in range(wordLength):
if wordChoice[i] == guess:
dashes[i] = guess
count = count +1
letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)
if count == 0:
guesses -= 1
if guesses == 0:
print("You have ran out of guesses!")
print("The word was:",wordChoice)
###### Play Game GUI
play = Toplevel()
play.title("Play Hangman!")
label = Label(play, text="HANGMAN", font = ("Arial",16)).grid(row = 0)
label = Label(play, text="Enter your guess >").grid(row = 3, column = 0)
for i in range(wordLength):
dashes.append("-")
letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)
entry = Entry(play)
entry.grid(row = 3, column = 1, columnspan = wordLength)
enterButton = Button(play, text = "Enter Guess", width = 15, command = enterLetter).grid(row = 3, column = (wordLength+2))
label = Label(play, text = "Letter used: ").grid(row = 4, columnspan = 2)
label = Label(play, text = "").grid(row= 4, columnspan = 6)
def scores():
print("check scores")
def howToPlay():
print("how to play")
####### Main Menu
root = Tk()
root.geometry("500x300")
root.title("HANGMAN")
label = Label(root, text="HANGMAN", font = ("Arial",30)).grid(row = 0, columnspan = 3)
label = Label(root, text = "Option 1 :", font = ("Arial",12)).grid(row = 1, column = 1)
playButton = Button(root, text = "Play Game", width = 15, command = play).grid(row = 1, column = 2)
label = Label(root, text = "Option 2 :", font = ("Arial",12)).grid(row = 2, column = 1)
instructionsButton = Button(root, text = "How to play", width = 15, command = howToPlay).grid(row = 2, column = 2)
label = Label(root, text = "Option 3 :", font = ("Arial",12)).grid(row = 3, column = 1)
scoresButton = Button(root, text = "View Scores", width = 15, command = scores).grid(row = 3, column = 2)
label = Label(root, text = "Option 4 :", font = ("Arial",12)).grid(row = 4, column = 1)
exitButton = Button(root, text = "Exit", width = 15, command = exit).grid(row = 4, column = 2)
root.mainloop()
You need to configure the Label, not recreate it.
Why do you use a while-loop in enter_letter? Its just run when the Button is clicked, it needs to be an if guesses > 0:
Your program did not terminate when the right word was entered; I added this.
Code:
import tkinter
from tkinter import *
from tkinter import messagebox
import random
guesses = 8
letter = None
def play():
global letter
print("play game")
wordList = ["talking", "dollar","choice", "famous", "define", "features"]
wordChoice = random.choice(wordList)
print(wordChoice)
wordLength = (len(wordChoice))
print(wordLength)
guessedLetters = []
dashes = []
play = Toplevel()
play.title("Play Hangman!")
label = Label(play, text="HANGMAN", font = ("Arial",16)).grid(row = 0)
label = Label(play, text="Enter your guess >").grid(row = 3, column = 0)
for i in range(wordLength):
dashes.append("-")
letter = Label(play, text = dashes, font = ("Arial",20))
letter.grid(row = 2, column = i+1,padx = 10, pady =10)
print(letter)
def enterLetter():
print("Guess")
global guesses, letter
print(guessedLetters)
if guesses != 0:
guess = entry.get().lower()
if len(guess) >1:
messagebox.showinfo("Error","Sorry, only one letter at a time")
return
elif guess.isalpha() == False:
messagebox.showinfo("Error","Letters only please")
return
elif guess in guessedLetters:
messagebox.showinfo("Error","You have already used the letter")
return
entry.delete("0","end")
guessedLetters.append(guess)
#print(guessedLetters)
#print(guesses)
print(dashes)
count = 0
for i in range(wordLength):
if wordChoice[i] == guess:
dashes[i] = guess
count += 1
letter.configure(text = dashes)
if count == 0:
guesses -= 1
if "".join(dashes) == wordChoice:
print("succsess!")
play.destroy()
return
if guesses == 0:
print("You have ran out of guesses!")
print("The word was:",wordChoice)
###### Play Game GUI
entry = Entry(play)
entry.grid(row = 3, column = 1, columnspan = wordLength)
enterButton = Button(play, text = "Enter Guess", width = 15, command = enterLetter).grid(row = 3, column = (wordLength+2))
label = Label(play, text = "Letter used: ").grid(row = 4, columnspan = 2)
label = Label(play, text = "").grid(row= 4, columnspan = 6)
def scores():
print("check scores")
def howToPlay():
print("how to play")
####### Main Menu
root = Tk()
root.geometry("500x300")
root.title("HANGMAN")
label = Label(root, text="HANGMAN", font = ("Arial",30)).grid(row = 0, columnspan = 3)
label = Label(root, text = "Option 1 :", font = ("Arial",12)).grid(row = 1, column = 1)
playButton = Button(root, text = "Play Game", width = 15, command = play).grid(row = 1, column = 2)
label = Label(root, text = "Option 2 :", font = ("Arial",12)).grid(row = 2, column = 1)
instructionsButton = Button(root, text = "How to play", width = 15, command = howToPlay).grid(row = 2, column = 2)
label = Label(root, text = "Option 3 :", font = ("Arial",12)).grid(row = 3, column = 1)
scoresButton = Button(root, text = "View Scores", width = 15, command = scores).grid(row = 3, column = 2)
label = Label(root, text = "Option 4 :", font = ("Arial",12)).grid(row = 4, column = 1)
exitButton = Button(root, text = "Exit", width = 15, command = exit).grid(row = 4, column = 2)
root.mainloop()
I hope this helps you.
The reason you cant update your label is because you haven't stored it in any variable. The grid, pack and place functions of the Label object and of all other widgets returns None, therefore when you call:
letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)
your label cannot be accessed by variable letter. To fix this you should split it like so:
letter = Label(play, text = dashes, font = ("Arial",20))
letter.grid(row = 2, column = i+1,padx = 10, pady =10)
To update text of that label, you can call .configure(text = 'new text') on it.
# letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10) #
letter.configure(text = dashes)
As for your second issue, i think you confused while loop and if statement in the function enterLetter. It's called once per click and you only need to check one time if player has ran out of guesses.
if guesses != 0:
...
elif guesses == 0:
....

Categories

Resources