Tkinter Displaying Wrong Thing at Incorrect Time - python

I am trying to create a clicker game, and all the basic fundamentals are in; there's a button, you can click it, there's an upgrade, you can infinitely buy it while the price goes up 15%. Now, all of this is fine, but I want to implement a "prestige" for the upgrade; if you buy the upgrade 10 times, you will have to pay a price 5x the cost, but after that the upgrade will give you more rewards. I decided to put a counter in, and whenever you buy the upgrade, it goes up. Now, here is my problem. I put an if statement for when the counter reaches 10 (all of the data for that upgrade is stored in its own dictionary), it will change the text and cost. This does not work at all. Instead, it keeps the same text, and after buying it 1 - 3 more times, it will change the reward given, but nothing else.
Here is my code:
from tkinter import *
from threading import Timer
window = Tk()
window.minsize(1200, 500)
window.title("Clicker Game")
# general setup
default_font = ("Calibri", 15, "normal")
clicks = 0
click_power = 1
# upgrade variables
upgrade1_stats = {
"cost": 15,
"can buy": False,
"times bought": 0,
"click power given": 1,
"prestige": False,
}
# functions
def check_clicks():
global clicks, upgrade1_stats
if clicks >= 10:
upgrade1.place(x=200, y=50)
if clicks >= upgrade1_stats["cost"]:
upgrade1_stats["can buy"] = True
else:
upgrade1_stats["can buy"] = False
def get_upgrade1():
global clicks, upgrade1_stats, click_power
if upgrade1_stats["times bought"] == 10 and upgrade1_stats["can buy"]:
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 5)
update_stats()
upgrade1_stats["prestige"] = False
upgrade1_stats["click power given"] += 1
upgrade1_stats["times bought"] += 1
if upgrade1_stats["can buy"]:
clicks -= upgrade1_stats["cost"]
click_power += upgrade1_stats["click power given"]
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 1.15)
upgrade1_stats["times bought"] += 1
update_stats()
else:
not_enough_clicks()
check_clicks()
if upgrade1_stats["prestige"]:
upgrade1.config(text=f"MAX UPGRADES BOUGHT\nPRESTIGE COST: {upgrade1_stats['cost']}")
else:
upgrade1.config(text=f"+{upgrade1_stats['click power given']} Click Power\nCost: {upgrade1_stats['cost']}")
def not_enough_clicks():
new_label = Label(text="NOT ENOUGH CLICKS", font=("Calibri", 80, "bold"))
new_label.place(x=125, y=180)
t = Timer(1, new_label.destroy)
t.start()
def increase_score(*args):
global clicks
if len(args) > 0:
update_amount = args[0]
else:
update_amount = click_power
clicks += update_amount
update_stats()
check_clicks()
def update_stats(**kwargs):
global clicks, click_power
click_display.config(text=f"{clicks} Clicks")
if click_power == 1:
click_power_display.config(text=f"{click_power} Click per Button Click")
else:
click_power_display.config(text=f"{click_power} Clicks per Button Click")
# title text
title_label = Label(text="Clicker Game", font=("Calibri", 30, "bold"))
title_label.grid(column=1, columnspan=2, row=1)
window.grid_columnconfigure(2, weight=1)
window.grid_rowconfigure(1, weight=1)
# click display
click_display = Label(text=f"{clicks} Clicks", font=default_font)
click_display.grid(column=2, row=2)
window.grid_rowconfigure(2, weight=0, pad=70)
# button to click
clicker = Button(text="Click Me", command=increase_score, height=3, width=10, bg="red")
clicker.grid(column=2, row=3)
window.grid_rowconfigure(3, pad=200)
# click power display
click_power_display = Label(text=f"{click_power} Click per Button Click", font=default_font)
click_power_display.place(x=495, y=150)
# upgrades
upgrade1 = Button(text=f"+1 Click Power\nCost: {upgrade1_stats['cost']}", command=get_upgrade1)
window.mainloop()
The expectation is that once buying the upgrade 10 times, it would change the text to "MAX UPGRADES REACHED. PRESTIGE COST: (prestige cost here)". This is not at all what is happening, and I am very confused why. Any and all help would be greatly appreciated by me.
EDIT
With the help of #Alexander, I did update my code to this:
from tkinter import *
from threading import Timer
window = Tk()
window.minsize(1200, 500)
window.title("Clicker Game")
# general setup
default_font = ("Calibri", 15, "normal")
clicks = 0
click_power = 1
# upgrade variables
upgrade1_stats = {
"cost": 15,
"can buy": False,
"times bought": 0,
"click power given": 1,
"prestige": False,
}
# functions
def check_clicks():
global clicks, upgrade1_stats
if clicks >= 10:
upgrade1.place(x=200, y=50)
if clicks >= upgrade1_stats["cost"]:
upgrade1_stats["can buy"] = True
else:
upgrade1_stats["can buy"] = False
def get_upgrade1():
global clicks, upgrade1_stats, click_power
if upgrade1_stats["times bought"] == 10 and upgrade1_stats["can buy"]:
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 5)
update_stats()
upgrade1_stats["prestige"] = True
upgrade1_stats["click power given"] += 1
upgrade1_stats["times bought"] += 1
elif upgrade1_stats["can buy"] and upgrade1_stats["times bought"] != 10:
clicks -= upgrade1_stats["cost"]
click_power += upgrade1_stats["click power given"]
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 1.15)
upgrade1_stats["times bought"] += 1
upgrade1_stats["prestige"] = False
update_stats()
else:
not_enough_clicks()
check_clicks()
if upgrade1_stats["prestige"]:
upgrade1.config(text=f"MAX UPGRADES BOUGHT\nPRESTIGE COST: {upgrade1_stats['cost']}")
else:
upgrade1.config(text=f"+{upgrade1_stats['click power given']} Click Power\nCost: {upgrade1_stats['cost']}")
def not_enough_clicks():
new_label = Label(text="NOT ENOUGH CLICKS", font=("Calibri", 80, "bold"))
new_label.place(x=125, y=180)
t = Timer(1, new_label.destroy)
t.start()
def increase_score(*args):
global clicks
if len(args) > 0:
update_amount = args[0]
else:
update_amount = click_power
clicks += update_amount
update_stats()
check_clicks()
def update_stats(**kwargs):
global clicks, click_power
click_display.config(text=f"{clicks} Clicks")
if click_power == 1:
click_power_display.config(text=f"{click_power} Click per Button Click")
else:
click_power_display.config(text=f"{click_power} Clicks per Button Click")
# title text
title_label = Label(text="Clicker Game", font=("Calibri", 30, "bold"))
title_label.grid(column=1, columnspan=2, row=1)
window.grid_columnconfigure(2, weight=1)
window.grid_rowconfigure(1, weight=1)
# click display
click_display = Label(text=f"{clicks} Clicks", font=default_font)
click_display.grid(column=2, row=2)
window.grid_rowconfigure(2, weight=0, pad=70)
# button to click
clicker = Button(text="Click Me", command=increase_score, height=3, width=10, bg="red")
clicker.grid(column=2, row=3)
window.grid_rowconfigure(3, pad=200)
# click power display
click_power_display = Label(text=f"{click_power} Click per Button Click", font=default_font)
click_power_display.place(x=495, y=150)
# upgrades
upgrade1 = Button(text=f"+1 Click Power\nCost: {upgrade1_stats['cost']}", command=get_upgrade1)
window.mainloop()
Now, there is still another problem:
The prestige only shows up after "buying" the upgrade 2 or 3 times after you actually bought it 10 times. I want it to show up after EXACTLY 10 times. Could anybody help me with this?

The reason it takes more than 10 clicks for it to appear is because you do not increment the upgrade1_stats["times bought"] until after you have already checked how many times user has previously clicked the bonus. So it takes exactly 11 times.
The solution would be to increment the times bought before checking if it has been bought 10 times, or alternatively you could start the times bought counter at 1 instead of 0.
upgrade1_stats["times bought"] += 1
I would recommend moving the above line and making a few other alterations to reduce some unnecessary code and improve readability. See inline notes in example below.
from tkinter import *
from threading import Timer
window = Tk()
window.minsize(1200, 500)
window.title("Clicker Game")
# general setup
default_font = ("Calibri", 15, "normal")
clicks = 0
click_power = 1
# upgrade variables
upgrade1_stats = {
"cost": 15,
"times bought": 0,
"click power given": 1
}
def get_upgrade1():
global clicks, click_power
if clicks < upgrade1_stats["cost"]: # if there is not enough clicks
return not_enough_clicks() # exit the function early
upgrade1_stats["times bought"] += 1 # increase times bought before check
if upgrade1_stats["times bought"] == 10:
upgrade1_stats["cost"] *= 5 # simplified multiplication
upgrade1_stats["click power given"] += 1
upgrade1.config(text=f"+{upgrade1_stats['click power given']} Click Power\nCost: {upgrade1_stats['cost']}")
else:
clicks -= upgrade1_stats["cost"]
click_power += upgrade1_stats["click power given"]
upgrade1_stats["cost"] = int(upgrade1_stats["cost"] * 1.15)
upgrade1.config(text=f"MAX UPGRADES BOUGHT\nPRESTIGE COST: {upgrade1_stats['cost']}")
update_stats()
def not_enough_clicks():
new_label = Label(text="NOT ENOUGH CLICKS", font=("Calibri", 80, "bold"))
new_label.place(x=125, y=180)
t = Timer(1, new_label.destroy)
t.start()
def increase_score(*_):
global clicks
clicks += click_power
if clicks >= 10:
upgrade1.place(x=200, y=50)
update_stats()
def update_stats(**_):
verb = "Click" if click_power == 1 else "Clicks"
click_display.config(text=f"{clicks} {verb}")
click_power_display.config(text=f"{click_power} {verb} per Button Click")
# title text
title_label = Label(text="Clicker Game", font=("Calibri", 30, "bold"))
title_label.grid(column=1, columnspan=2, row=1)
window.grid_columnconfigure(2, weight=1)
window.grid_rowconfigure(1, weight=1)
# click display
click_display = Label(text=f"{clicks} Clicks", font=default_font)
click_display.grid(column=2, row=2)
window.grid_rowconfigure(2, weight=0, pad=70)
# button to click
clicker = Button(text="Click Me", command=increase_score, height=3, width=10, bg="red")
clicker.grid(column=2, row=3)
window.grid_rowconfigure(3, pad=200)
# click power display
click_power_display = Label(text=f"{click_power} Click per Button Click", font=default_font)
click_power_display.place(x=495, y=150)
# upgrades
upgrade1 = Button(text=f"+1 Click Power\nCost: {upgrade1_stats['cost']}", command=get_upgrade1)
window.mainloop()

Related

Is there a way to make a function run after a specified amount of time in Python without the after method?

I am trying to create a simple program that tracks a user's clicks per second in Tkinter, but I have no idea how to make the program wait without freezing the program using the after method. The problem is that I need to log the high score after the time finishes, but using this method, the score logs before the click counter goes up. Here is my code:
from tkinter import *
import time
root = Tk()
root.geometry('600x410')
screen = Canvas(root)
h = 6 #button height
w = 12 #button width
c = 0 #counts amount of times clicked
start_btn = 0 #logs clicks of the start button
high_score = 0 #logs the highest score
time = 0
def count_hs():
high_score = c
def remove_time():
global time
time -= 1
def countdown(n):
for i in range(n):
time = n
root.after(1000, remove_time())
#alternatively i tried this:
#time.sleep(1)
#remove_time()
if time <= 0:
b["text"] = "Test done."
break
def start_test():
global start_btn
b["text"] = "Click to begin."
start_btn += 1
print("start button: " + str(start_btn))
def button_click():
global start_btn
global c
c+=1
print("click counter: " + str(c))
#resets the amount of clicks on the large button when the start button is pressed
if c >= 1 and start_btn >= 1:
print("test1")
c = 1
start_btn = 0
if b["text"] == "Click to begin.":
print("test2")
b["text"] = "Click!"
countdown(6)
count_hs()
print("hs: " +str(high_score))
#primary button
b = Button(root, text=" ", font=("Arial", 40), height = h, width = w, command = lambda: button_click())
b.grid(row=0, column=0)
#start button
start = Button(root, text="Start.", command = lambda: start_test())
start.grid(row=0, column=1)
root.mainloop()
Give it a try
from tkinter import *
root = Tk()
root.geometry('600x410')
screen = Canvas(root)
h = 6 # button height
w = 12 # button width
c = 0 # counts amount of times clicked
start_btn = 0 # logs clicks of the start button
high_score = 0 # logs the highest score
time = 0
def count_hs():
global high_score
if c > high_score:
high_score = c
return high_score
def remove_time():
global time
time -= 1
if time > 0:
root.after(1000, remove_time)
else:
show_score()
def start_test():
global start_btn
global c
global time
b["text"] = "Click to begin."
start_btn += 1
print("start button: " + str(start_btn))
# Reset your timer and counter
time = 6
c = 0
def button_click(*args):
global start_btn
global c
# resets the amount of clicks on the large button when the start button is pressed
if c == 0 and start_btn >= 1:
start_btn = 0
b["text"] = "Click!"
root.after(1000, remove_time)
print("hs: " + str(high_score))
else:
c += 1
print("click counter: " + str(c))
def show_score():
global c
score_label.configure(text=str(c))
high_score_label.configure(text=str(count_hs()))
c = 0
b['text'] = ""
# primary button
b = Button(root, text="", font=("Arial", 40), height=h, width=w, command=button_click)
b.grid(row=0, column=0, rowspan=5)
# start button
start = Button(root, text="Start.", command=lambda: start_test())
start.grid(row=0, column=1)
Label(root, text="Your score").grid(row=1, column=1)
score_label = Label(root, text="")
score_label.grid(row=2, column=1)
Label(root, text="High score").grid(row=3, column=1)
high_score_label = Label(root, text="")
high_score_label.grid(row=4, column=1)
root.mainloop()
Few changes:
In count_hs I assume you would update the highscore only if current score beats it.
You can use remove_time as a timer by making it calling itself until time <= 0, in which case you should end your game.
I've used the start button as a resetter, so that when it is clicked it will reset c and time.
On button_click you can now only bother with updating c (and change text at the beginning).
Finally I've added few labels to show the final results, both current and high scores.
Few suggestions to move on:
Instead of global variables you could create a class for the app, it should make it easier for you to exchange info and avoid subtle errors.
You could improve the layout, especially for the newly added labels.
You could make your original timer a parameter (currently, it is set within start_test).
Instead of importing from tkinter import *, I'd suggest you to do something like import tkinter as tk or from tkinter import ... since it increases readability and reduces the sources of errors.

Jumping between functions in tkinter

so I am working on this school project and I need to be able to run the random number generator then if it is 1 go to the headspinner module but if it is 2 go to the tailspinner module. After that the code should add up the score and print it to the user.
Any advice on how to jump from one function to another in my code would be much appreciated thank you.
from tkinter import * # access tkinter library
import random # get random number generator
money = 100
#create coin flip module
def coinFlip():
flip = random.randint(1, 2)
if flip == 1:
headspinner()
else:
tailspinner()
#create headspinner module
def headspinner():
global money
head = random.randint(1, 2)
if head == 1:
money = money + 30
else:
money = money - 25
#create tailspinner module
def tailspinner():
global money
tail = random.randint(1, 4)
if tail == 1:
money = money + 2
elif tail == 2:
money = money + 5
elif tail == 3:
money = money + 10
else:
money = money + 15
#gains or losses module
def upordown():
global money
if money > 100:
screen.itemconfig(message, text = f"Congratulations, you won ${(money - 100):.2f}", font = ("Calibri", "18"))
else:
screen.itemconfig(message, text = f"Congratulations, you won ${(100 - money):.2f}", font = ("Calibri", "18"))
#create pop up box
root = Tk()
#creating canvas
screen = Canvas (root, height = 600, width = 800, bg = "lightgreen")
screen.pack()
#flip button
go = Button(root, text = "Flip", cursor = "hand2", command = coinFlip)
goButton = screen.create_window(400, 530, window = go)
#cerate title
title = screen.create_text(400, 100, text = "Welcome to Flip and Spin", font = ("Calibri", "35"))
#text for instructions
text1 = Label(root, text = "Welcome to the Flip and Spin game! \nThis game includes a quick fate of what you could encounter. \nIt starts off with a fast flip of a coin followed by a dizzying spin of a spinner. \nCome and play to decide if you will lose money, \nmake your money back, or win some easy money!", font = ("Calibri", "20"), justify = CENTER, bg = "light green")
text1label = screen.create_window(400, 300, window = text1,)
#text for final results
message = screen.create_text(400, 400, text = "Results", font = ("Calibri", "18"))
#close canvas
mainloop()
You are already switching from function to function in def coinFlip.
You just need to put everything together.
Here's a simple example to get you started:
from tkinter import Tk, Button, Label, X, LEFT, RIGHT
import random
money = 100
#create coin flip module
def coin_flip():
flip = random.randint(1, 2)
if flip == 1:
headspinner()
else:
tailspinner()
#create headspinner module
def headspinner():
global money
head = random.randint(1, 2)
if head == 1:
money = money + 30
else:
money = money - 25
text.config(text=f"Headspinner: {money}", bg="#aaafff")
#create tailspinner module
def tailspinner():
global money
tail = random.randint(1, 4)
if tail == 1:
money = money + 2
elif tail == 2:
money = money + 5
elif tail == 3:
money = money + 10
else:
money = money + 15
text.config(text=f"Tailspinner: {money}", bg="#ffaaaa")
def show_result():
global money
text.config(text=f"Result: {money}.\nClick the Flip button to start over.", bg="#fffaaa")
money = 100 # reset
root = Tk()
root.title("Game")
# the text here changes when the buttons are pressed
text = Label(root, text="Welcome to the Flip and Spin game!", font = ("Calibri", "18"))
text.pack()
rules = Label(root, text="This game includes a quick fate of what you could encounter. \nIt starts off with a fast flip of a coin followed by a dizzying spin of a spinner. \nCome and play to decide if you will lose money, \nmake your money back, or win some easy money!", font = ("Calibri", "10"))
rules.pack()
# click the button to run the command and change the text in the Label
flip_button = Button(root, text="Flip", command=coin_flip, fg="blue")
flip_button.pack(fill=X, side=LEFT, expand=True)
# click the button to run the command and change the text in the Label
result_button = Button(root, text="Result", command=show_result, fg="blue")
result_button.pack(fill=X, side=RIGHT, expand=True)
root.mainloop()

Button isn't displaying the timer

I'm making a little game for my 4-year-old nephew. you plug two mice into the computer and try to press your button and I need the start button to turn into a timer. The problem is the button isn't displaying the time. It stops responding until the time is up and then displays "1". (keep in mind this is unfinished)
import tkinter
from tkinter import ttk
import time
score = 0
window = tkinter.Tk()
window.geometry("300x200")
def button1():
score = score - 1
def button2():
score = score + 1
def Start():
t = 30
while t > 0:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
start.config(text=t)
print(timer, end="\r")
time.sleep(1)
t -= 1
start = ttk.Button( window, text = "Start", command = Start)
start.pack(padx= 2, pady = 1)
one = ttk.Button( window, text = "Player 1", command = button1)
one.pack(padx= 2, pady = 1)
two = ttk.Button( window, text = "Player 2", command = button2)
two.pack(padx= 2, pady = 1)
window.mainloop()
Here is an answer on the while loops indegestibility with the tkinter mainloop.
You could also solve this by running your start() function in its own thread:
import threading
def start():
t = 30
while t > 0:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
start_button.config(text=t)
print(timer, end="\r")
time.sleep(1)
t -= 1
def start_in_thread():
thread = threading.Thread(target=start)
thread.daemon = True # forces thread to close when the tkinter mainloop is closed
thread.start()
start_button = ttk.Button(window, text="Start", command=start_in_thread)
Another issue is that you buttonX() functions change the global variable score without gloal keyword:
def button1():
global score
score = score - 1
You just need to remove the while and replace it with a call to after. I also cleaned up your script a little, and solved a future problem you were going to have. Using threading like the other answer states is overkill. You just need to stop blocking the mainloop with the while.
import tkinter as tk
window = tk.Tk()
window.geometry("300x200")
_PLAYTIME = 10
t, score = _PLAYTIME, 0
def tally(i):
global score
score += i
start = tk.Button(window, text="Start")
start.pack(padx= 2, pady = 1)
tk.Button(window, text="Player 1", command=lambda: tally(1)).pack(padx=2, pady=1)
tk.Button(window, text="Player 2", command=lambda: tally(-1)).pack(padx=2, pady=1)
def game():
global t, score
if t > 0:
timer = '{:02d}:{:02d}'.format(*divmod(t, 60))
start.config(text=f'Time: {timer} | Score: {score}')
t -= 1
start.after(1000, game)
else:
start.config(text=f'Score: {score} | Start')
t, score = _PLAYTIME, 0
start.configure(command=game)
window.mainloop()
Here's the exact same game, but made giant and colorful as I assume 4 year olds like things... ;). I also added a 3-2-1-Go! countdown after start is pressed so, the person pressing start doesn't lose an advantage. The red and green rects are your click area. Red subtracts and green adds.
I'm not sure if you are prepared for this but, plugging 2 mice into the same computer is not going to give you 2 pointers. Maybe that's part of your game ~ fighting a 4 year old for mouse control :D. If it isn't, you are going to need TeamPlayer or something similar. Or you could simply bind keyboard keys instead of the mouse.
import tkinter as tk
root = tk.Tk()
root.geometry("800x640")
root.title('CLICKFIGHT')
#seconds to play and player handicaps
_PLAYTIME = 10
_HANDICAP1 = 0
_HANDICAP2 = 0
#time, score, countdown
t, s, cd = _PLAYTIME, 0, 3
#gameboard
board = tk.Canvas(root, highlightthickness=0, width=800, height=640)
board.pack()
#score adjuster
def tally(i):
global s
s += i
#gameboard elements
player1 = board.create_rectangle(0, 0, 400, 600, fill="#ff0000")
player2 = board.create_rectangle(400, 0, 800, 600, fill="#00ff00")
timer = board.create_text(200, 50, font='Helvetica 40 bold', fill='#ffffff')
score = board.create_text(600, 50, font='Helvetica 40 bold', fill='#ffffff')
button = board.create_rectangle(0, 600, 800, 640, fill="#0000ff", tag="button")
start = board.create_text(400, 620, font='Helvetica 20 bold', fill='#ffffff', text="START", tag="button")
cdown = board.create_text(400, 300, font='Helvetica 80 bold', fill='#ffffff')
#game countdown
def countdown():
global cd, p
#so you can't click start again
board.tag_unbind("button", '<1>')
if cd > 0:
board.itemconfig(cdown, text=cd)
cd-=1
root.after(800, countdown)
else:
board.itemconfig(cdown, text='GO!')
root.after(200, game)
cd = 3
#actual game
def game():
global t, s
#game stats
board.itemconfig(timer, text='Time:\t{:02d}:{:02d}'.format(*divmod(t, 60)))
board.itemconfig(score, text=f'Score:\t{s}')
board.itemconfig(start, text='PLAYING...')
if t > 0:
#game looping
t -= 1
root.after(1000, game)
board.itemconfig(cdown, text='')
else:
#reset everything
t, s = _PLAYTIME, 0
board.itemconfig(start, text='START')
board.itemconfig(cdown, text='GAME OVER')
board.tag_bind("button", '<1>', lambda e: countdown())
#mouse events
board.tag_bind(player1 , '<1>', lambda e: tally(-(1+_HANDICAP1)))
board.tag_bind(player2 , '<1>', lambda e: tally(1+_HANDICAP2))
board.tag_bind("button", '<1>', lambda e: countdown())
root.mainloop()

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

How to fix Tkinter label not appearing?

I'm making a game in Tkinter. A dynamic clicker game where you have to buy what you 'click'. I've been trying to get an inventory screen going but I've run into a problem I cant understand. When the player opens the 'Inventory' screen by clicking a button, a window appears with all the fruits they have (eg. Apples: 654 (A testing number)). But for some reason, nothing appears. At all. There is no error and no label. Why is this?
Code:
from tkinter import *
money = 0
currentfruit = "Apple"
numOfApples = 654
def clicked():
global money
global currentfruit
if currentfruit == "Apple":
money = money + 1
moneystringvar.set("You have $" + str(money))
if money < 10:
moneylabel.place(x="327", y="0")
if money < 100 and money > 9:
moneylabel.place(x="320", y="0")
if money < 1000 and money > 99:
moneylabel.place(x="315", y="0")
def inventoryOnClose():
root.deiconify()
inventorywindow.destroy()
def marketOnClose():
root.deiconify()
marketwindow.destroy()
def upgradesOnClose():
root.deiconify()
upgradeswindow.destroy()
def inventory():
global inventorywindow
global numOfApples
root.withdraw()
inventorywindow = Tk()
inventorywindow.title("Fruit Clicker - Inventory")
inventorywindow.geometry("400x350+300+100")
inventorywindow.protocol("WM_DELETE_WINDOW", inventoryOnClose)
applesinventory = StringVar()
applesinventory.set("Apples: " + str(numOfApples))
applesinvlabel = Label(inventorywindow, textvariable=applesinventory)
applesinvlabel.place(x="0", y="0")
inventorywindow.mainloop()
def market():
global marketwindow
root.withdraw()
marketwindow = Tk()
marketwindow.title("Fruit Clicker - Market")
marketwindow.geometry("400x350+300+100")
marketwindow.protocol("WM_DELETE_WINDOW", marketOnClose)
marketwindow.mainloop()
def upgrades():
global upgradeswindow
root.withdraw()
upgradeswindow = Tk()
upgradeswindow.title("Fruit Clicker - Upgrades")
upgradeswindow.geometry("400x350+300+100")
upgradeswindow.protocol("WM_DELETE_WINDOW", upgradesOnClose)
upgradeswindow.mainloop()
root = Tk()
root.title("Fruit Clicker")
root.geometry("400x350+300+100")
inventorybutton = Button(root, text="Inventory", fg="White", bg="Black", width="6", command=inventory)
inventorybutton.grid(column="0", row="0")
marketbutton = Button(root, text="Market", fg="White", bg="Black", width="6", command=market)
marketbutton.grid(column="0", row="1")
upgradesbutton = Button(root, text="Upgrades", fg="White", bg="Black", width="6", command=upgrades)
upgradesbutton.grid(column="0", row="2")
leftfruitbutton = Button(root, text="<")
leftfruitbutton.place(x="100", y="285")
currentfruitstringvar = StringVar()
if currentfruit == "Apple":
currentfruitstringvar.set("Apple x" + str(numOfApples))
currentfruitlabel = Label(root, textvariable=currentfruitstringvar, fg="Black")
if numOfApples < 10:
currentfruitlabel.place(x="180", y="290")
if numOfApples < 100 and numOfApples > 9:
currentfruitlabel.place(x="175", y="290")
if numOfApples < 1000 and numOfApples > 99:
currentfruitlabel.place(x="170", y="290")
rightfruitbutton = Button(root, text=">")
rightfruitbutton.place(x="287", y="285")
moneystringvar = StringVar()
moneystringvar.set("You have $" + str(money))
moneylabel = Label(root, textvariable=moneystringvar)
if money < 10:
moneylabel.place(x="327", y="0")
if money < 100 and money > 9:
moneylabel.place(x="320", y="0")
if money < 1000 and money > 99:
moneylabel.place(x="315", y="0")
clickerphoto = PhotoImage(file = "apple.png")
clickerbutton = Button(root, text="Clicker Button", image=clickerphoto, fg="Black", command=clicked)
clickerbutton.place(x="100", y="75")
root.mainloop()
I'm not sure if you need apple.png but if you do, here is a link to my GitHub Repo: https://github.com/SeaPuppy2006/FruitClicker
Thanks!
#jizhihaoSAMA answered in the comments.
Instead of upgradeswindow = Tk() it should be upgradeswindow = Toplevel() same for all children of the original Tk() window.

Categories