tkinter: How to change labels inside the program itself - python

I was asked to edit my code so I decided to include the entire calculator script
from tkinter import *
global choice
choice = 0
#Program
def calculate(*event):
if choice == 1:
try:
add1 = ccalc1.get()
add2 = ccalc2.get()
except:
no = Label(app, text="You must use a number").grid(row=0, column=0)
answ = add1 + add2
answer = Label(app, text = answ).grid(row=1, column=0)
elif choice == 2:
try:
sub1 = ccalc1.get()
sub2 = ccalc2.get()
except:
no = Label(app, text="You must use a number").grid(row=1, column=0)
answ = sub1 - sub2
answer = Label(app, text = answ).grid(row=1, column=0)
def choice2():
global choice
choice = 2
#End Program
#GUI
#Window Info
calc = Tk()
calc.title("Calculator")
calc.geometry("200x140")
#End Window Info
#Build Window
app = Frame(calc)
app.grid()
ccalc1 = IntVar()
ccalc2 = IntVar()
#Widgets
if choice == 0:
welcome = Label(app, text="Select a choice")
elif choice == 2:
welcome.config(text="Subtraction")
calcbox1 = Entry(app,textvariable=ccalc1)
calcbox2 = Entry(app,textvariable=ccalc2)
submit = Button(app, text="CALCULATE", command = calculate)
welcome.grid(row=0,column=0)
calcbox1.grid(row=2, column=0)
calcbox2.grid(row=3, column=0)
submit.grid(row=4, column=0)
calc.bind('<Return>', calculate)
#End Widgets
#Menu
menu=Menu(calc)
#Operations
filemenu = Menu(menu,tearoff=0)
filemenu.add_command(label="Subtract", command = choice2)
menu.add_cascade(label="Operations",menu=filemenu)
calc.config(menu=menu)
calc.mainloop()
#End GUI
what wrong is that the welcome label text wont change accordingly.
Update: I included the entire calculator code
Any help is appreciated.

It's hard to understand what you expect to happen. For example, look at this code:
#Widgets
if choice == 0:
welcome = Label(app, text="Select a choice")
elif choice == 2:
welcome.config(text="Subtraction")
This code will only ever execute once, and choice will always be zero since that's what you initialize it to. It executes once because it's not in a function and not in a loop, so as python parses the code it will run it and move to the next line. That block of text will never be processed a second time.
If you want the label to change when the user selects a menu item, you'll need to execute that code inside the choice2 function:
def choice2():
global choice
choice = 2
welcome.config(text="Subtraction")

Related

How to get a value to change immediately after a button is pressed in tkinter?

When the rock button is pressed I want your score to go up by one immediately after you press the button. However the score updates on the button press after instead of immediately updating after one button press. To see what I mean press the rock button twice and you will get a score of 1. How would I fix this problem?
from tkinter import *
import random
root = Tk()
results = Label(root)
your_score = 0
def rock_input():
global results
global your_score
options = ['scissors']
cpu = random.choice(options)
win = Label(root, text='you win!!!')
human_score = Label(root, text='Your score: ' + str(your_score))
win.config(font=('Courier', 44))
human_score.config(font=('Courier', 15))
results.grid_forget()
if cpu == 'scissors':
your_score += 1
human_score.grid(row=2, column=1)
results = win
results.grid(row=4, column=0)
rock_button = Button(root, text='rock', bg='#a85032', padx=20, pady=15, command=rock_input)
rock_button.grid(row=1, column=0)
root.mainloop()
I have tried playing around with your code and im not sure what you're trying to achieve, so pardon me if im wrong. I think there is two ways to achieve what i think you want.
Way 1 (does not change your function code):
Simply changing your_score = 0 to your_score = 1 will fix the issue for now.
Way 2 (change inside your function, rearranging the code):
def rock_input():
global results
global your_score
options = ['scissors']
cpu = random.choice(options)
if cpu == 'scissors':
your_score += 1
win = Label(root, text='you win!!!')
human_score = Label(root, text='Your score: ' + str(your_score))
win.config(font=('Courier', 44))
human_score.config(font=('Courier', 15))
results.grid_forget()
human_score.grid(row=2, column=1)
results = win
results.grid(row=4, column=0)
Let me know if any errors or doubts :D

Guess the number with Tkinter, Python3

here is my code:
from tkinter import *
import random
def initGame():
window = Tk()
window.title("Guess the number game")
lbl = Label(window, text="Guess number from 1 to 100. Insert how many tries would you like to have: ", font=("",16))
lbl.grid(column=0, row=0)
txt = Entry(window, width=10)
txt.grid(column=0, row=1)
txt.focus() #place cursor auto
def clicked():
number_dirty = txt.get()
tries = int(number_dirty)
playGame(tries)
btn = Button(window, text="Start", command=clicked)
btn.grid(column=0, row=2)
window.geometry('800x600')
window.mainloop()
def playGame(tries):
number_of_tries = int(tries)
number = random.randint(1,100)
higher_notification = "Number is HIGHER"
lower_notification = "Number is LOWER"
game_window = Tk()
game_window.title("Game Window")
lbl = Label(game_window, text="Guess numbers between 1 and 100, you have %s tries !" %(number_of_tries), font=("",14))
lbl.grid(column=0, row=0)
txt = Entry(game_window, width=10)
txt.grid(column=0, row=1)
txt.focus()
print(number)
print(number_of_tries)
def clicked():
user_input = txt.get()
compareNumbers(number, user_input)
btn_try = Button(game_window, text="Try!", command="clicked")
btn_try.grid(column=0, row=2)
def compareNumbers(number, user_input):
if user_input == number:
messagebox.showinfo('You have won!', 'Right! the number was %s ' %(number))
else:
if user_input > number:
lbl.configure(lower_notification)
number_of_tries -1
else:
lbl.configure(higher_notification)
number_of_tries -1
game_window.geometry('600x600')
game_window.mainloop()
initGame()
On the first screen (initGame) everything works fine, when I click the button I do indeed get the second screen, which displays all objects normally. When I click the button in the game screen I get no feedback at all, nothing happens.
What am I missing?
Thank you very much !
The problem is in this line:
btn_try = Button(game_window, text="Try!", command="clicked")
Note that the command "clicked" is inside quotaions marks and therefor a string and not the method you tried to reference. What you want is:
btn_try = Button(game_window, text="Try!", command=clicked)

Tkinter problem creating button to collect text from user

I am new to Tkinter, and am trying to create a hangman app. I have already created a command-line version, so I thought it would be a nice beginning project. When learning I was told to use window.mainloop() for creating/updating, but my program contains a while loop, and so that hasn't worked. I am not able to type into the textbox i have created at all and when I click the button, it gives me a NameError saying textEntry in my click() method is not defined. Any help or guidance of where else to look would be much appreciated. Thanks! My code is posted below
from tkinter import *
from random import choice
def click():
guess = textEntry.get()
return guess
def main():
input_file = open('hangman_word_list.txt','r')
word_list = input_file.read().split()
window = Tk()
window.title("Play Hangman!")
window.configure(background="black")
p1 = PhotoImage(file='h1.gif')
p2 = PhotoImage(file='h2.gif')
p3 = PhotoImage(file='h3.gif')
p4 = PhotoImage(file='h4.gif')
p5 = PhotoImage(file='h5.gif')
p6 = PhotoImage(file='h6.gif')
Label(window,image=p1,bg="purple").grid(row=0,column=0,columnspan=4)
word = choice(word_list)
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
lives = 6
again = True
nowPhoto = p1
guess = 'empty'
while lettersLeft > 0 and again == True:
Label(window,text="Your word is "+hiddenWord ,bg="gray",fg="purple",font="none 12 bold").grid(row=1,column=0,sticky=W)
Label(window,text="Enter a letter: " ,bg="gray",fg="purple",font="none 12 bold").grid(row=2,column=0,sticky=W)
textEntry = Entry(window,width=5,bg="white")
textEntry.grid(row=2,column=1,sticky=W)
guess = Button(window,text="Guess",width=5,command=click).grid(row=3,column=2,sticky=W)
window.update()
main()
The mainloop() listens continously for any hook that you have defined, which means you don't have to worry about that. Just define the right hooks, like the button command.
I introduced a nicer way to handle the images by putting them in a list and then reducing the list for each image requested. This makes it easier to update the image.
Then put all processing, like checking if a uessed letter is in the word etc. in the click() function.
from tkinter import *
window = Tk()
# Make a list of all the pictures
pic_list = ['h6.gif','h5.gif','h4.gif','h3.gif','h2.gif','h1.gif']
img = PhotoImage(file=pic_list.pop()) # Get image from list of images
hangman = Label(window, image=img) # Save reference to the Label as
hangman.grid(row=0,column=0,columnspan=4) # you will update it later
# I simplified the word selection a bit
word = 'Wensleydale'
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
guess = 'empty'
# Build the rest of the GUI
Label(window,text="Your word is " + hiddenWord, bg="gray", fg="purple",
font="none 12 bold").grid(row=1, column=0, sticky=W, columnspan=4)
Label(window,text="Enter a letter: ", bg="gray", fg="purple",
font="none 12 bold").grid(row=2, column=0, sticky=W)
textEntry = Entry(window, width=10, bg="white")
textEntry.grid(row=2, column=1, sticky=W, columnspan=3)
def click(): # Callback function
guess = textEntry.get()
# Put all other processing here.
# Updating the image
img = PhotoImage(file=pic_list.pop()) # Get next image from list
hangman.configure(image=img) # Replace image in label
hangman.image = img # Keep reference to the new image
# Create button and associate it with the command callback function
guess_button = Button(window, text="Guess", width=5,
command=click).grid(row=3, column=2, sticky=W)
window.mainloop() # Will loop continously listening for buttonpress
Firstly, a while loop is not recommended for use when it comes to using tkinter module as the window would be running on the main thread. Logically, when using buttons, you can use if statements so that it won't trigger a specific part of code until lettersLeft > 0 and again == True. And the use of variable textEntry in a function is obviously not available to Python because there is no declaration of it. So you either pass the variable as argument or declare a global variable.
Here is what I would think of:
from tkinter import *
from random import choice
def get_wordlist():
return open("Hangman word list.txt", 'r').read().split("split by something here.")
class Hangman(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.title("Hangman")
self.master.configure(bg="black")
self.wordlist = get_wordlist()
self.p1 = PhotoImage(file="h1.gif")
self.word = choice(self.wordlist)
self.hidden_word = list("".join("_" for x in word))
self.wrong_guess = []
self.lives = 6
self.word_display = Label(window, text=str(*(hidden for hidden in hidden_word)), image=p1, bg="purple", fg="white")
self.word_display.grid(row=0, column=0, columnspan=4)
Label(window, text="Enter a letter: ", bg="gray", fg="purple", font="none 12 bold").grid(row=2, column=0, sticky=W)
self.entry = Entry(window, width=5, bg="white")
self.entry.grid(row=2, column=1, sticky="W")
self.guess = Button(window, text="Guess", command=lambda: button_action(self))
self.guess.grid()
self.again = False
def button_action(self):
user_input = self.entry.get()
if len(user_input) == len(word):
for i in range(len(word)):
if word[i] == user_input[i]:
self.hidden_word[i] = word[i]
if "_" not in self.hidden_word:
self.word_display.config(text="You won! The correct word was: " + self.word)
self.after(3000, self.quit())
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
if self.lives <= 0:
self.word_display.config(text="You lost! The correct word was: " + self.word)
self.master.after(3000, self.quit())
Please note 2 things:
Try not to create redundant variables
Before even asking a question, please do look on python tkinter docs.

python - opening an GUI from a list

import random
from tkinter import *
import tkinter as tk
scores = []
score = 0
#introduction
def start():
print(" Welcome to Maths Smash \n")
print("Complete the questions the quickest to get a high score\n")
name = input("What is your name? ")
print("Ok", name, "let's begin!")
#menu
def main():
choice = None
while choice !="0":
print(
"""
Maths Smash
0 - Exit
1 - Easy
2 - Medium
3 - Hard
4 - Extreme
5 - Dashboard
"""
)
choice = input("Choice: ")
print()
#exit
if choice == "0":
print("Good-bye!")
break
#easy
elif choice == "1":
print(" Easy Level ")
print("Complete the test within two minutes to get 10 extra points\n")
easy_level()
#medium
elif choice == "2":
print(" Medium Level ")
print("Complete the test within two minutes to get 10 extra points\n")
medium_level()
#hard
elif choice == "3":
print(" Hard Level ")
print("Complete the test within two minutes to get 10 extra points\n")
hard_level()
#extreme
elif choice == "4":
print(" Extreme Level ")
print("Complete the test within two minutes to get 10 extra points\n")
extreme_level()
#teacher login
elif choice == "5":
print("Dashboard")
dashboard(Frame)
#if the input does not = to choices
else:
print("Sorry but", choice, "isn't a vaild choice.")
class dashboard(Frame):
def __init__(self, master):
super(dashboard, self).__init__(master)
self.grid()
self.main_menu()
def main_menu(self):
#student dashboard button
bttn1 = Button(self, text = "Student",
command=self.student, height = 2, width= 15)
bttn1.grid()
#teacher dashboard button
bttn2 = Button(self, text = "Teacher",
command=self.teacher, height = 2, width= 15)
bttn2.grid()
#exit button
bttn3 = Button(self, text = "Exit",
command=root.destroy, height = 2, width= 15)
bttn3.grid()
self.main_page_buttons = bttn1, bttn2, bttn3 # Save button widgets.
def student(self):
for button in self.main_page_buttons: # Hide the main page Buttons.
button.grid_forget()
#view highscores button
bttn1 = Button(self, text = "Highscores",
command=self.view_scores, height = 2, width= 15)
bttn1.grid()
#print score button
bttn2 = Button(self, text = "Save Score",
command=self.save_score, height = 2, width= 15)
bttn2.grid()
#exit button
bttn3 = Button(self, text = "Exit",
command=root.destroy, height = 2, width= 15)
bttn3.grid()
self.student_page_buttons = bttn1, bttn2, bttn3 # Save button widgets.
def save_score(self):
f = open("Maths Test Score.txt','w")
score = input("What did you score?\n")
f.write(name, score)
f.close()
def teacher(self):
for button in self.main_page_buttons: # Hide the main page Buttons.
button.grid_forget()
#add highscores button
bttn1 = Button(self, text = "Add Highscore",
command=self.add_score, height = 2, width= 15)
bttn1.grid()
#remove score button
bttn2 = Button(self, text = "Remove Highscore",
command=self.remove_score, height = 2, width= 15)
bttn2.grid()
#view highscores
bttn3 = Button(self, text = "View Highscores",
command=self.view_scores, height = 2, width= 15)
bttn3.grid()
#exit button
bttn4 = Button(self, text = "Exit",
command=root.destroy, height = 2, width= 15)
bttn4.grid()
self.teacher_page_buttons = bttn1, bttn2, bttn3, bttn4 # Save button widgets.
def add_score(self):
global scores
score = int(input("What score do you want to add?\n"))
scores.append(score)
def remove_score(self):
global scores
score = int(input("Remove which score?\n"))
if score in scores:
scores.remove(score)
def view_scores(self):
global scores
print("High Scores")
for score in scores:
print(score)
#calling functions
start()
main()
#main for gui
root = Tk()
root.title("Dashboard")
root.geometry("300x170")
app = dashboard(root)
root.mainloop()
Being trying to get this to work for a while now but, what I want to do is open the GUI when the user enters choice '5' but I'm not sure if there is a different way to call a class or something, have looked online for a bit couldn't see any useful examples to help. Any help would be much appreciated, cheers.
I couldn't run code at this moment but I see one mistake.
When dashboard is created it needs parent instance - like root - but in menu() you use Frame which is class name, not instance.
In menu() you will have to create root before you create dashboard, and use root.mainloop() after that.
elif choice == "5":
print("Dashboard")
root = Tk()
root.title("Dashboard")
root.geometry("300x170")
app = dashboard(root)
root.mainloop()
EDIT: full working code.
Because now root is local variable inside main() so in dashboard I use self.master instead of root - see command=self.master.destroy
import random
from tkinter import *
scores = []
score = 0
#introduction
def start():
print(" Welcome to Maths Smash \n")
print("Complete the questions the quickest to get a high score\n")
name = input("What is your name? ")
print("Ok", name, "let's begin!")
#menu
def main():
choice = None
while choice !="0":
print(
"""
Maths Smash
0 - Exit
1 - Easy
2 - Medium
3 - Hard
4 - Extreme
5 - Dashboard
"""
)
choice = input("Choice: ")
print()
#exit
if choice == "0":
print("Good-bye!")
break
#easy
elif choice == "1":
print(" Easy Level ")
print("Complete the test within two minutes to get 10 extra points\n")
easy_level()
#medium
elif choice == "2":
print(" Medium Level ")
print("Complete the test within two minutes to get 10 extra points\n")
medium_level()
#hard
elif choice == "3":
print(" Hard Level ")
print("Complete the test within two minutes to get 10 extra points\n")
hard_level()
#extreme
elif choice == "4":
print(" Extreme Level ")
print("Complete the test within two minutes to get 10 extra points\n")
extreme_level()
#teacher login
elif choice == "5":
print("Dashboard")
root = Tk()
root.title("Dashboard")
root.geometry("300x170")
app = Dashboard(root)
root.mainloop()
#if the input does not = to choices
else:
print("Sorry but", choice, "isn't a vaild choice.")
class Dashboard(Frame):
def __init__(self, master):
super(Dashboard, self).__init__(master)
self.grid()
self.main_menu()
def main_menu(self):
#student dashboard button
bttn1 = Button(self, text = "Student",
command=self.student, height = 2, width= 15)
bttn1.grid()
#teacher dashboard button
bttn2 = Button(self, text = "Teacher",
command=self.teacher, height = 2, width= 15)
bttn2.grid()
#exit button
bttn3 = Button(self, text="Exit",
command=self.master.destroy, height = 2, width= 15)
bttn3.grid()
self.main_page_buttons = bttn1, bttn2, bttn3 # Save button widgets.
def student(self):
for button in self.main_page_buttons: # Hide the main page Buttons.
button.grid_forget()
#view highscores button
bttn1 = Button(self, text = "Highscores",
command=self.view_scores, height = 2, width= 15)
bttn1.grid()
#print score button
bttn2 = Button(self, text = "Save Score",
command=self.save_score, height = 2, width= 15)
bttn2.grid()
#exit button
bttn3 = Button(self, text = "Exit",
command=self.master.destroy, height = 2, width= 15)
bttn3.grid()
self.student_page_buttons = bttn1, bttn2, bttn3 # Save button widgets.
def save_score(self):
f = open("Maths Test Score.txt','w")
score = input("What did you score?\n")
f.write(name, score)
f.close()
def teacher(self):
for button in self.main_page_buttons: # Hide the main page Buttons.
button.grid_forget()
#add highscores button
bttn1 = Button(self, text = "Add Highscore",
command=self.add_score, height = 2, width= 15)
bttn1.grid()
#remove score button
bttn2 = Button(self, text = "Remove Highscore",
command=self.remove_score, height = 2, width= 15)
bttn2.grid()
#view highscores
bttn3 = Button(self, text = "View Highscores",
command=self.view_scores, height = 2, width= 15)
bttn3.grid()
#exit button
bttn4 = Button(self, text = "Exit",
command=self.master.destroy, height = 2, width= 15)
bttn4.grid()
self.teacher_page_buttons = bttn1, bttn2, bttn3, bttn4 # Save button widgets.
def add_score(self):
global scores
score = int(input("What score do you want to add?\n"))
scores.append(score)
def remove_score(self):
global scores
score = int(input("Remove which score?\n"))
if score in scores:
scores.remove(score)
def view_scores(self):
global scores
print("High Scores")
for score in scores:
print(score)
#calling functions
start()
main()

Creating a Tkinter math Quiz

I am learning python and am having trouble getting this program to work correctly.
from Tkinter import*
import time
import tkMessageBox
import random
def Questions():
number1 = random.randrange(1,25,1)
number2 = random.randrange(1,50,2)
answer = number1 + number2
prompt = ("Add " + str(number1) + " and " + str(number2))
label1 = Label(root, text=prompt, width=len(prompt), bg='yellow')
label1.pack()
return answer
def start():
global count_flag
Questions()
count_flag = True
count = 0.0
while True:
if count_flag == False:
break
# put the count value into the label
label['text'] = str(count)
# wait for 0.1 seconds
time.sleep(0.1)
# needed with time.sleep()
root.update()
# increase count
count += 0.1
def Submit(answer, entryWidget):
""" Display the Entry text value. """
global count_flag
count_flag = False
print answer
if entryWidget.get().strip() == "":
tkMessageBox.showerror("Tkinter Entry Widget", "Please enter a number.")
if int(answer) != entryWidget.get().strip():
tkMessageBox.showinfo("Answer", "INCORRECT!")
else:
tkMessageBox.showinfo("Answer", "CORRECT!")
# create a Tkinter window
root = Tk()
root.title("Math Quiz")
root["padx"] = 40
root["pady"] = 20
# Create a text frame to hold the text Label and the Entry widget
textFrame = Frame(root)
#Create a Label in textFrame
entryLabel = Label(textFrame)
entryLabel["text"] = "Answer:"
entryLabel.pack(side=LEFT)
# Create an Entry Widget in textFrame
entryWidget = Entry(textFrame)
entryWidget["width"] = 50
entryWidget.pack(side=LEFT)
textFrame.pack()
#directions
directions = ('Click start to begin. You will be asked a series of questions like the one below.')
instructions = Label(root, text=directions, width=len(directions), bg='orange')
instructions.pack()
# this will be a global flag
count_flag = True
answer = Questions()
Sub = lambda: Submit(answer, entryWidget)
# create needed widgets
label = Label(root, text='0.0')
btn_submit = Button(root, text="Submit", command = Sub)
btn_start = Button(root, text="Start", command = start)
btn_submit.pack()
btn_start.pack()
label.pack()
# start the event loop
root.mainloop()
It just says "INCORRECT!" every time I push submit regardless of what I enter into the text box. Any suggestions would be appreciated. Thanks, Scott
Left side is an integer, right side is a string, so it's always False:
int(answer) != entryWidget.get().strip()
You can try:
int(answer) != int(entryWidget.get().strip())

Categories