Dictionary within a function passing values to another function - python

I am having an issue with my code. I am relatively new at coding. My issue is that I am trying to take the dictionary SeatingOrder populated in the Waitlist.GuestList function and then pass those values, if there are any, to the Staff function so that I can display them in a drop-down and modify them. I can't seem to find a way to do it and any help or even a point in the right direction would be helpful.
import math
from tkinter import *
import time
#initializes time based on system time
count= int(0)
t= time.localtime()
current_Time = float(time.strftime("%H%M%S", t))
SeatingOrder = {''}
root=Tk()
root.title("Main Screen")
root.geometry("1920x1080")
def WaitList():
#tnikter screen setup
root=Tk()
root.title("Seating List")
root.geometry("1920x1080")
#creates label and entry box
PartyName = Entry(root)
PartyName.grid(row=0, column=1)
Label(root,text="Enter the party name: ").grid(row=0, column=0)
#creates label and entry box
PartySize = Entry(root)
PartySize.grid(row=0, column=3)
Label(root, text="How many are in your party? ").grid(row=0, column=2)
#creates a dictionary with an array inside of it so information can be search by the key value
SeatingOrder = {PartyName : [PartySize, current_Time]}
#defintion to populate array
def GuestList():
x = str(PartyName.get())
y = int(PartySize.get())
SeatingOrder = {x : [y, current_Time]}
#Prints statement and displays the result
Label(root, text="Your spot has been saved!").grid(row=3, column=1)
Label(root, text=SeatingOrder).grid(row=3, column=2)
#creates a button the runs the command.
Button(root, text="Save", command=GuestList).grid(row=1, column=1)
Button(root, text="x", command=root.destroy).grid(row=1, column=10)
root.mainloop()
return SeatingOrder
def Staff():
Dictionary = WaitList()
root=Tk()
root.title("Administration")
root.geometry("1920x1080")
def show():
Label(root, Text=clicked.get()).grid(row=1, column=1)
clicked = StringVar()
clicked.set("Please select a party")
SeatingDropDown = OptionMenu(root, clicked, )
SeatingDropDown.grid(row=0, column=1)
Button(root, text="select", command=show).grid(row=0, column=2)
Button(root, text="x", command=root.destroy).grid(row=1, column=10)
exit
Button(root, text="Waitlist", command=WaitList).grid(row=5, column=1)
Button(root, text="Staff", command=Staff).grid(row=5, column=2)
root.mainloop()

Just one point is that in this code you have set up a root main screen window and for each function you have set up a new root window (note that Staff window has no mainloop call and so wouldn't have an event loop)
But I would scrap all that. The usual way with tkinter is to have a root (Main screen) and all subsequent windows are made tkinter.Toplevel with the root as master. Skeleton example for just this point:
import tkinter as tk
root - tk.Tk()
root.geometry('1920x1080+0+0') # geometry is 'widthxheight+x+y'
WaitListwindow = tk.Toplevel(root)
WaitListwindow.pack()
WaitListwindow.place(x=10,y=10) #place values are now relative to the root geometry
Staffwindow = tk.Toplevel(root)
Staffwindow.pack()
Staffwindow.place(x=70,y=10)
root.mainloop()
now root is the parent\master and WaitListWindow and StaffWindow are the children. Note that I use pack and place but grid applies just as well with the appropriate parameters.
You can then place the buttons and entry as children of the appropraite window, eg
staffselectb = tk.Button(Staffwindow)
staffselectb.pack()
staffselectb.place(x=5,y=5) # this button is now relative to Staffwindow placement
#so that x and y are inside Staffwindow at (5,5)
With the root.mainloop() you can now bind events to a widget, eg to retrieve the Entry widget contents.
There is more but I just wanted to concentrate on this point.

Related

Tkinter - Python, how do I cause a button click to assign a value to a variable?

Using Tkinter and Python. Already created a window for the buttons to be placed on. I want there to be four buttons to appear, and I want to be able to click one of the four buttons, and be able for it to set the selection variable = "whatever I clicked", so that I can then use this variable later to call an API. When I run the program and click on the "General knowledge" button and print the selection, it does correctly print "General knowledge", but then when I try to return this selection variable it just doesn't work and I don't know why.
def select1():
selection = "General Knowledge"
print(selection)
def select2():
selection = "Science"
def select3():
selection = "Entertainment"
def select4():
selection = "Miscellaneous"
button1 = tk.Button(text = "General Knowledge", command = select1)
button1.place(x=100, y=100)
button2 = tk.Button(text = "Science", command = select2)
button2.place(x=100, y=140)
button3 = tk.Button(text = "Entertainment", command = select3)
button3.place(x=100, y=180)
button4 = tk.Button(text = "Miscellaneous", command = select4)
button4.place(x=100, y=220)
There are several ways to accomplish your goal.
One way is to write a single function that will take a value to assign to your variable. This way you can have as many buttons as you like and only a single function.
Not if you are using functions you have to either pass the variable to the function or let the function know it is in the global namespace.
import tkinter as tk
root = tk.Tk()
selection = ''
def assign_value(value):
global selection
selection = value
lbl["text"] = value
print(selection)
lbl = tk.Label(root, text='Selection Goes Here')
lbl.grid(row=0, column=0)
tk.Button(text="General Knowledge", command=lambda: assign_value("General Knowledge")).grid(row=1, column=0)
tk.Button(text="Science", command=lambda: assign_value("Science")).grid(row=2, column=0)
tk.Button(text="Entertainment", command=lambda: assign_value("Entertainment")).grid(row=3, column=0)
tk.Button(text="Miscellaneous", command=lambda: assign_value("Miscellaneous")).grid(row=4, column=0)
root.mainloop()
Or you can assign the value directly from the button.
import tkinter as tk
root = tk.Tk()
selection = tk.StringVar()
selection.set('Selection Goes Here')
lbl = tk.Label(root, textvariable=selection)
lbl.grid(row=0, column=0)
tk.Button(text="General Knowledge", command=lambda: selection.set("General Knowledge")).grid(row=1, column=0)
tk.Button(text="Science", command=lambda: selection.set("Science")).grid(row=2, column=0)
tk.Button(text="Entertainment", command=lambda: selection.set("Entertainment")).grid(row=3, column=0)
tk.Button(text="Miscellaneous", command=lambda: selection.set("Miscellaneous")).grid(row=4, column=0)
root.mainloop()
I am sure if I spent more time on this I could think up something else but the idea is basically write your code in a more DRY (Don't Repeat Yourself) fashion and make sure you are assigning the value to the variable in the global namespace or else it will not work as you expect.

How to update and show in real time on label 2 what user write in ENTRY label1?

If i have this ENTRY label1 on pos1, how can i update and show "in real time" the text i write on other label 2 in position2?
label1 = Entry(root, font=('aria label', 15), fg='black')
label1.insert(0, 'enter your text here')
label1_window = my_canvas.create_window(10, 40, window=entry)
label2 = how to update and show in real time what user write on label1
If the entry and label use the same StringVar For the textvariable option, the label will automatically show whatever is in the entry. This will happen no matter whether the entry is typed in, or you programmatically modify the entry.
import tkinter as tk
root = tk.Tk()
var = tk.StringVar()
canvas = tk.Canvas(root, width=400, height=200, background="bisque")
entry = tk.Entry(root, textvariable=var)
label = tk.Label(root, textvariable=var)
canvas.pack(side="top", fill="both", expand=True)
label.pack(side="bottom", fill="x")
canvas.create_window(10, 40, window=entry, anchor="w")
root.mainloop()
Issues in your attempt: The variable names are not clear as you are creating an Entry component and then assigning it to a variable named label1 which can be confusing.
Hints: You can do one of the following to tie the label to the entry so that changing the text in the entry causes the text in the label to change:
Use a shared variable
Implement a suitable callback function. You can, for example, update the label each time the KeyRelease event occurs.
Solution 1 - Shared variable: Below is a sample solution using a shared variable:
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.title('Example')
root.geometry("300x200+10+10")
user_var = StringVar(value='Enter text here')
user_entry = Entry(root, textvariable=user_var, font=('aria label', 15), fg='black')
user_entry.pack()
echo_label = Label(root, textvariable=user_var)
echo_label.pack()
root.mainloop()
Solution 2 - Callback function: Below is a sample solution using a suitable callback function. This is useful if you wish to do something more:
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.title('Example')
root.geometry("300x200+10+10")
def user_entry_changed(e):
echo_label.config({'text': user_entry.get()})
user_entry = Entry(root, font=('aria label', 15), fg='black')
user_entry.insert(0, 'Enter your text here')
user_entry.bind("<KeyRelease>", user_entry_changed)
user_entry.pack()
echo_label = Label(root, text='<Will echo here>')
echo_label.pack()
root.mainloop()
Output: Here is the resulting output after entering 'abc' in the entry field:

How do I include a calculation function in a menu item in Tkinter?

I created a menu item and want to run a function within that menu which will run a simple calculation based on a entry. When I run the code in my terminal, I can see my window and the menu item with the entry widget. But, I don't see anything and result from my function. I don't get an error from the terminal. Below is my code. Where did I mess in my code?
from tkinter import *
root = Tk()
root.title(" My calculator")
root.geometry("400x400")
# Defining calculator 1 function
def calculator_1():
# creating an entry
frame1.pack(fill="both",expand=1)
e1 =Entry(frame1)
e1.pack(pady=5)
# Defining the formula function
def formula():
res = (int(e1.get()) + 1)
myText.set(res)
# creating a calculate button
my_button = Button(frame1, text="Click to calculate", command=formula)
my_button.pack(pady=5)
myText=StringVar()
result=Label(frame1, text=" your results is ", textvariable =myText)
result.pack(pady=5)
label_result =Label(frame1, text= "Your result is")
label_result.pack(pady=5)
# Define Main menu
my_menu = Menu(root)
root.config(menu=my_menu)
#create menu items
math_menu = Menu(my_menu)
my_menu.add_cascade(label="MathCards",menu=math_menu)
math_menu.add_command(label="Calculator 1",command=calculator_1)
math_menu.add_separator()
math_menu.add_command(label="Exit", command=root.quit)
# Creating a frame
frame1 = Frame(root, width =400, height=400)
root.mainloop()

Entry data manipulation difficulties [duplicate]

I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()

.get() not giving a value [duplicate]

I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()

Categories