How do I create a +1 button in tkinter - python

**I am writing a baseball counting program. I have a label for walks and strikeouts. To the side of those labels I have buttons with the text "+1". I want the buttons to be able to change and print the number of walks and strikeouts every time I click the +1 buttons. I just need some ideas to help get started. Here is my code for clarification: **
import tkinter as tk
from tkinter.constants import COMMAND, X
global walk_counter
walk_counter = 0
global strikeout_counter
strikeout_counter = 0
def main(): # This is the main function
root = tk.Tk()
frame = tk.Frame(root)
frame.master.title("Random Title")
frame.pack(padx=4, pady=3, fill=tk.BOTH, expand=1)
populate_boxes(frame)
root.mainloop()
def populate_boxes(frame):
walks_label = tk.Label(frame, text="BB:")
walks_entry = tk.Label(frame, width=4)
walks_button = tk.Button(frame,text="+1")
strikeouts_label = tk.Label(frame,text="Strikeouts:")
strikeouts_entry = tk.Label(frame,width=4)
strikeouts_button = tk.Button(frame,text="+1")
walks_label.place(x=200,y=500)
walks_entry.place(x=250,y=500)
walks_button.place(x=300,y=500)
strikeouts_label.place(x=400,y=500)
strikeouts_entry.place(x=450,y=500)
strikeouts_button.place(x=500,y=500)
def add_more_walks():
global walk_counter
walk_counter += 1
walks_entry.config(text = walk_counter)
add_more_walks()
main()

Related

How to make a button create a label and shortly after that hide in tkinter

My code:
def Click():
global output
output = StringVar()
output = random.randint(1, 6)
global outputL
outputL = Label(root, text = f"The number is... {output}")
outputL.pack()
output = 0
How do I make it hide the label after that?
Use after method and config method
(TIP) Don't create a widgets(Labels, Buttons, etc...) inside a function. Use config method to update your widgets
from tkinter import *
import random
root = Tk()
def Remove_Output():
outputL.pack_forget()
def click():
global output
output = StringVar()
output = random.randint(1, 6)
outputL.config(text=f"The number is... {output}")
outputL.pack()
output = 0
root.after(1000, Remove_Output)
btn = Button(root, text="Click",command=click)
btn.pack()
outputL = Label(root, text = "")
root.mainloop()

use a while true loop while the code below is still running (python)

Im making this game called:
IDLE PEN ,(MAKE PENS)
and every 1 second i get a bonus pen
how i get a bonus pen is doing this
Import time
While true
make a pen()
time.sleep(1)
but i have some code under the while true loop.
the code under the while true loop is like buttons to
upgrade the pens or make a pen
So how do i make the code under the while true loop work?
This is my game im happy for anyone to copy it
its not ready yet
import functools
import tkinter
import tkinter.messagebox
import time
from random import seed
from random import randint
# eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
window = tkinter.Tk()
window.title('Idle Pen')
def print_pen(number: int):
return f"Pens: {number}"
class pencount:
def __init__(self):
self.pencount = 0
self.text = tkinter.Text(height=1, width=30)
self.text.insert("1.0", print_pen(0))
self.text['state'] = 'disabled'
self.text.pack()
def changepencount(self, count):
if self.pencount + count < 0:
return
self.pencount = self.pencount + count
self.text['state'] = 'normal'
self.text.delete("1.0", "end")
self.text.insert("1.0", print_pen(self.pencount))
self.text['state'] = 'disabled'
self.text.pack()
pen = pencount()
changepenup = functools.partial(pen.changepencount, 1)
B = tkinter.Button(window, text="Make Pen", command=changepenup)
changependown = functools.partial(pen.changepencount, -100)
A = tkinter.Button(window, text='Penmaker', command=changependown)
Q = tkinter.Button(window, text="Quit", command=window.destroy)
U = tkinter.Button
# eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
B.pack()
A.pack()
Q.pack()
window.mainloop()
You could use threading to run your loop in separated thread and then main thread may run tkitner
OR you can use tkinter function after() (instead of while True) to run function with delay and this function should use again after() to run itself.
import tkinter as tk
# --- functions ---
def update():
global value
value += 1
text = f'make penny: {value}'
print(text)
label['text'] = text
# run again after 1s (1000ms)
root.after(1000, update)
# --- main ---
value = 0
root = tk.Tk()
label = tk.Label(root, text="make penny: 0")
label.pack()
button = tk.Button(root, text="Exit", command=root.destroy)
button.pack()
# run first time after 1s (1000ms)
root.after(1000, update)
root.mainloop()

problem with GUI Buttons calling functions that prompt user input within the GUI and then display Output

I cannot get the user input within the GUI
from tkinter import *
from tkinter import ttk
import math
I create main frame with buttons Rectangle,Triangle and use pack() to show it.
I also create two frames with Entry but I don't use pack() to show it.
When I click Rectangle or Triangle then it runs function which uses pack_forget() to remove main frame from window, and it uses .pack() two show one of frame with Entry.
This frame has button Calc which uses your function to calculate result - but it gets values from Entry and it displays result in Label.
It has also button Back which removes this frame and it shows main frame again.
I use current to remember current visible frame.
from tkinter import *
from tkinter import ttk
import math
# ---
def change_frame(new_frame):
global current
# hide current frame
current.pack_forget()
# show new frame
current = new_frame
current.pack()
def show_main_frame():
change_frame(main_frame)
def show_rectangle_frame():
change_frame(rectangle_frame)
def show_triangle_frame():
change_frame(triangle_frame)
# ---
def calc_rectangle():
try:
l = float(rectangle_entry1.get())
w = float(rectangle_entry2.get())
arear=(l * w)
print(arear)
rectangle_result['text'] = str(arear)
except ValueError:
pass
def calc_triangle():
try:
b = float(triangle_entry1.get())
h = float(triangle_entry2.get())
areat=(0.5* b * h )
print(areat)
triangle_result['text'] = str(areat)
except ValueError:
pass
#-----
window = Tk()
window.title("Area Calculator")
#window.geometry("290x120")
main_frame = Frame(window)
main_frame.pack()
button = Button(main_frame, text="Rectangle", command=show_rectangle_frame)
button.pack()
button = Button(main_frame, text="Triangle", command=show_triangle_frame)
button.pack()
current = main_frame
# --- frame without .pack() ---
rectangle_frame = Frame(window)
rectangle_result = Label(rectangle_frame, text="")
rectangle_result.pack()
l = Label(rectangle_frame, text="Enter Length:")
l.pack()
rectangle_entry1 = Entry(rectangle_frame)
rectangle_entry1.pack()
l = Label(rectangle_frame, text="Enter Width:")
l.pack()
rectangle_entry2 = Entry(rectangle_frame)
rectangle_entry2.pack()
b = Button(rectangle_frame, text="Calc", command=calc_rectangle)
b.pack()
b = Button(rectangle_frame, text="BACK", command=show_main_frame)
b.pack()
# --- frame without .pack() ---
triangle_frame = Frame(window)
triangle_result = Label(triangle_frame, text="")
triangle_result.pack()
l = Label(triangle_frame, text="Enter base:")
l.pack()
triangle_entry1 = Entry(triangle_frame)
triangle_entry1.pack()
l = Label(triangle_frame, text="Enter Height:")
l.pack()
triangle_entry2 = Entry(triangle_frame)
triangle_entry2.pack()
b = Button(triangle_frame, text="Calc", command=calc_triangle)
b.pack()
b = Button(triangle_frame, text="BACK", command=show_main_frame)
b.pack()
# ---
window.mainloop()
Using lambda you can do
command=lambda:change_frame(rectanlge_frame)
and then you don't need function show_rectanlge_frame
The same with second frame.
There is more complex version created by Bryan Oakley which uses classes Page(Frame) and sometimes you can see these classes in questions on Stackoverflow.

Label with textvariable not showing up

Label "totalresults" in window "root2" is not showing up. I would like to that text label to update every time button is pressed in first window and calculate the amount of those button presses.
#create the window
root = Tk()
root2 = Tk()
#probability calculations
totalrolls = tk.StringVar()
amountofrolls = 0
#update numbers in gui
def add_num():
global amountofrolls
amountofrolls += 1
totalrolls.set("Amount of rolls made in total: " +str(amountofrolls))
#button functions
def button_press():
add_num()
#string variable
totalrolls.set("Amount of rolls made in total: " + str(amountofrolls))
#modify second window
todennäköisyys = Label(root2, text="The quantity of results:")
totalresults = Label (root2, textvariable=totalrolls)
todennäköisyys.pack()
totalresults.pack()
#kick off the event loop
root.mainloop()
root2.mainloop()
I am not getting any errors or anything the second window just dosent show the label.
You should not start more than one instance of Tk(). Use Toplevel() instead. See example:
from tkinter import *
root = Tk() # create the window
display = Toplevel(root)
#probability calculations
totalrolls = StringVar()
amountofrolls = 0
def add_num(): # update numbers in gui
global amountofrolls
amountofrolls += 1
totalrolls.set("Amount of rolls made in total: " + str(amountofrolls))
def button_press(): # button functions
add_num()
#string variable
totalrolls.set("Amount of rolls made in total: " + str(amountofrolls))
#modify second window
todennäköisyys = Label(display, text="The quantity of results:")
totalresults = Label (display, textvariable=totalrolls)
todennäköisyys.pack()
totalresults.pack()
# Create button in root window
Button(root, text='Increase number', command=add_num).pack()
#kick off the event loop
root.mainloop()

Tkinter wait function is not working

I am trying to make an animation using Tkinter Text Widget. I want it to write each frame on the Text widget every 1 second. Here is my current code:
from tkinter import *
frames = ["-o","--o","---o"]
speed = 1000
def clear():
text.delete(0.0, END)
def movie(event):
text.delete(0.0, END)
for frame in range(len(frames)):
text.insert(END, frames[frame])
root.after(speed, clear)
root = Tk()
root.title("Animation")
root.minsize(400,400)
root.maxsize(width=root.winfo_screenwidth()-20, height=root.winfo_screenheight()-20)
text = Text(root, highlightcolor="black", highlightbackground="white",width=400, insertbackground="white", height=400, foreground="white", background="black", font="Courier")
text.pack()
root.bind("<Return>", movie)
But, the output of this code is
-o--o---o
instead of:
-o[wait a second][clear]--o[wait a second][clear]---o[wait a second][clear]
How can I fix this?
I found my problem! The .after() function almost works like the return function. In that, when called the current function is stopped. This is my fixed code:
from tkinter import *
frame = 0
frames = ["-o","--o","---o"]
speed = 1000
def clear():
text.delete(0.0, END)
def movie(event=""):
global frame
if frame < len(frames):
text.delete(0.0, END)
text.insert(END,frames[frame])
frame += 1
root.after(speed, movie)
def movie1(event):
global frame
frame = 0
movie("<Return>")
root = Tk()
root.title("Animation")
root.minsize(400,400)
root.maxsize(width=root.winfo_screenwidth()-20, height=root.winfo_screenheight()-20)
text = Text(root, highlightcolor="black", highlightbackground="white",width=400, insertbackground="white", height=400, foreground="white", background="black", font="Courier")
text.pack()
root.bind("<Return>", movie)

Categories

Resources