Python Tkinter Button not appearing with grid - python-3.x

I'm trying to program a little calculator in python3 with Tkinter. When I try to organize my buttons and the input filed with grid(), my buttons are not appearing. I am sure I forgot something but hopefully someone can find my issue.
from tkinter import *
gleichung = ""
def zahl_gedrückt(num):
global gleichung
gleichung = gleichung + str(num)
gleichung_text.set(gleichung)
if __name__ == "__main__":
app = Tk()
app.title("Taschenrechner")
app.geometry("400x600")
gleichung_text = StringVar()
gleichung_text.set('Gleichung...')
gleichung_textbox = Entry(app, font=("Calibri 25"), state='disabled', width=400, justify='center', textvariable=gleichung_text)
gleichung_textbox.grid(row=0, columnspan=4)
button1 = Button(app, text=' 1 ', font=("Calibri 40"), command=lambda: zahl_gedrückt(1)).grid(row=2, column=0)
button2 = Button(app, text=' 2 ', font=("Calibri 40"), command=lambda: zahl_gedrückt(2)).grid(row=2, column=1)
app.mainloop()

Related

name 'main_window' is not defined

from tkinter import *
def create_main_window():
global main_window
main_window = Toplevel()
main_window.update()
entrance_window = Tk()
first_text_label = Label(entrance_window, text="you are in:").grid(row=0, column=0)
place_entry = Entry(entrance_window).grid(row=0, column=1)
submit_button = Button(entrance_window, text="Submit", command=create_main_window).grid(row=1, column=0, columnspan=2)
Label(main_window, text=f"{place_entry}").pack()
entrance_window.mainloop()
the program should open a new window with the text from the entry box from the first window but it either shows None if I write
Label(main_window, text=f"{place_entry}").pack()
in the create_main_window or it gives me an error saying that main_window is not defined if I write it after the button code.
Can someone help with this?
Try this:
from tkinter import *
def create_main_window():
global main_window
main_window = Toplevel(main_window)
label = Label(main_window, text=f"{place_entry.get()}")
label.pack()
# main_window.update() # This is useless
entrance_window = Tk()
first_text_label = Label(entrance_window, text="You are in:")
first_text_label.grid(row=0, column=0)
place_entry = Entry(entrance_window)
place_entry.grid(row=0, column=1)
submit_button = Button(entrance_window, text="Submit", command=create_main_window)
submit_button.grid(row=1, column=0, columnspan=2)
entrance_window.mainloop()
I moved the label creation inside create_main_window. Also please note that using var = a().b(), saves what ever b() returns inside var. That is why when you use var = Entry(...).pack(...), var is always None.
This is because you are trying to add a Label to an object that doesn't exist. Move the Label function to the create_main_window() function, like below:
from tkinter import *
def create_main_window():
global main_window, entrance_window
main_window = Toplevel()
place_entry = Entry(entrance_window).grid(row=0, column=1)
Label(main_window, text=f"{place_entry}").pack()
main_window.update()
entrance_window = Tk()
first_text_label = Label(entrance_window, text="you are in:").grid(row=0, column=0)
submit_button = Button(entrance_window, text="Submit", command=create_main_window).grid(row=1, column=0, columnspan=2)
entrance_window.mainloop()

Python 3 - Tkinter, MessageBox popsup when program is run not on button press [duplicate]

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 2 years ago.
I have a small issue for which I can`t find the reason.
I have the following GUI, and it pops the message box when I run it, even though it is inside a procedure which is triggered only on button press.
Tried even creating a secondary function which will show only the message box and still did not fix the issue.
Thank you for your help... I am quite sure that there is an easy fix which I just do not see...
import tkinter as tk
from tkinter import ttk
import tkinter.messagebox
import jl_generator
def run():
jl_generator.run_process()
tkinter.messagebox.showerror('Done','Done')
def show():
temp_list = user_input_list
for i in range(0, len(user_input_list[0])):
listBox.insert("", "end", values = (user_input_list[0][i],user_input_list[1][i],user_input_list[2][i],user_input_list[3][i],user_input_list[4][i],user_input_list[6][i],user_input_list[8][i]))
# Column Names for the TreeView
cols = ('Entity', 'Customer Nr', 'Account Code', 'Profit Centre', 'Partner Profit Centre', 'Amount', 'Nr Of Journal Lines')
# Input data for the tree view
user_input_list, journal_code = jl_generator.get_user_input()
#Creating the
root = tk.Tk()
root.title('JL Generator')
#Create the treeview
listBox = ttk.Treeview(root, columns=cols, show='headings')
for col in cols:
listBox.heading(col, text=col)
listBox.grid(row=1, column=0, columnspan=3)
#-------------LABELS--------------
#Title Label
label = tk.Label(root, text="Journal Lines Generator", font=("Arial",30)).grid(row=0, columnspan=3)
#Journal Code Label
show_journal_code = tk.Label(root, text = 'Journal Code = ' + journal_code).grid(row=6, column=1)
#Number of Journal Lines Label
show_number_of_journal_lines = tk.Label(root, text = 'Number of Journal Lines = ' + str(sum(user_input_list[8][i] for i in range(0, len(user_input_list[0]))))).grid(row=5, column=1)
#------------BUTTONS-----------
#Run the Generation
run_process = tk.Button(root, text="Generate JLs", width=15, command=run()).grid(row=4, column=1)
#Show the input data
showScores = tk.Button(root, text="Show Input", width=15, command=show).grid(row=4, column=0)
#Close the window
closeButton = tk.Button(root, text="Exit", width=15, command=exit).grid(row=4, column=2)
root.mainloop()
run_process = tk.Button(root, text="Generate JLs", width=15, command=run()).grid(row=4, column=1)
this is incorrect.
I used to feel confused about this.
You should use:
run_process = tk.Button(root, text="Generate JLs", width=15, command=run).grid(row=4, column=1)
In python,function is an object,call function should use function()
If you debug this code,you will find that after debug this code
run_process = tk.Button(root, text="Generate JLs", width=15, command=run()).grid(row=4, column=1)
you will find it will call run function and run it.
And Finally,run_process["command"] will be the returned value ofrun()

Using Tkinter to disable entry with specified input

I would like to use Tkinter to be able to disable one entry if 'no' is selected from a drop down menu.
from tkinter import *
def disableEntry(entry):
entry.config(state='disable')
def allowEntry(entry):
entry.config(state='normal')
def main():
print("test")
root = Tk() #create a TK root window
root.title("Lunch and Learn") #Title of the window
L1 = Label(root, text = "Label 1").grid(row=0, column=0, padx=30, pady=(20,5))
L2 = Label(root, text = "Label 2").grid(row=1, column=0, pady=5)
var = StringVar()
E1 = Entry(root,bd =3)
E1.grid(row=0, column=1)
D1 = OptionMenu(root,var,"yes","no")
D1.grid(row=1,column=1)
if var.get() == 'no':
disableEntry(E1)
elif var.get() == 'yes':
allowEntry(E1)
B2 = Button(text = "Submit", command=main).grid(row=4, column=2)
root.mainloop()
the above code is a simple example of what i have tried. I have created two functions called 'disableEntry' and 'allowEntry' which should change the state of the entry box but they don't appear to do anything when i change the input of the drop down menu.
i dont know if i am approaching this the wrong way or if there is a standardized way to do this.
any help would be appreciated.
You need a way to check the state of the selection after it is changed. That can be achieved with adding a callback command to the OptionMenu widget.
You were checking the correct variable, but the point you were checking it at was before the screen window had even displayed.
from tkinter import Label, StringVar, OptionMenu, Entry, Tk, Button
# change the state of the Entry widget
def change_state(state='normal'):
E1.config(state=state)
def main():
print("test")
# callback function triggered by selecting from OptionMenu widget
def callback(*args):
if var.get() == 'no':
change_state(state='disable')
elif var.get() == 'yes':
change_state(state='normal')
root = Tk() #create a TK root window
root.title("Lunch and Learn") #Title of the window
L1 = Label(root, text="Label 1").grid(row=0, column=0, padx=30, pady=(20, 5))
L2 = Label(root, text="Label 2").grid(row=1, column=0, pady=5)
var = StringVar()
E1 = Entry(root, bd=3)
E1.grid(row=0, column=1)
D1 = OptionMenu(root, var, "yes", "no", command=callback)
D1.grid(row=1, column=1)
B2 = Button(text = "Submit", command=main).grid(row=4, column=2)
root.mainloop()

How can i edit this code i've made so far so that when i click the button 'signup' it closes that gui and opens the next one

i am using tkinter to make a gui and have made various different buttons and now i have made all this i am unsure how to correctly make the first gui box close as the second one opens (sign_in function)
from tkinter import *
class login:
def __init__(self, master):
frame = Frame(master)
frame.grid()
self.button1 = Button(frame, text="signup", fg="green",command=self.sign_in)
self.button2 = Button(frame, text="sign in", fg="black",)
self.button3 = Button(frame, text="quit", fg="red", command=frame.master.destroy)
self.button1.grid(stick=W)
self.button2.grid(stick=W)
self.button3.grid(stick=W)
def sign_in(self):
frame = Frame()
frame.grid()
name = Label(root, text="Name: ")
password = Label(root, text="password: ")
entry1 = Entry(root)
entry2 = Entry(root)
name.grid(row=0, sticky=E)
password.grid(row=1, sticky=E)
entry1.grid(row=0, column=1)
entry2.grid(row=1, column=1)
c = Checkbutton(root, text="keep me logged in")
c.grid(columnspan=2, sticky="w")
root = Tk()
account=login(root)
root.mainloop()
Your code contains some indentation errors so I'll just go by your question.
when i click the button 'signup' it closes that gui and opens the next one
You can do so by first withdrawing your root window like this: root.withdraw() which will hide your original window. Then create a Toplevel window like this: newWindow = tk.Toplevel(root) to create a new window. You will just need to place these lines in the button command call.
Here's what you can change in the sign_in note that I changed all the masters to frame and not root:
def sign_in(self):
root.withdraw()
frame = Toplevel(root)
name = Label(frame, text="Name: ")
password = Label(frame, text="password: ")
entry1 = Entry(frame)
entry2 = Entry(frame)
name.grid(row=0, sticky=E)
password.grid(row=1, sticky=E)
entry1.grid(row=0, column=1)
entry2.grid(row=1, column=1)
c = Checkbutton(frame, text="keep me logged in")
c.grid(columnspan=2, sticky="w")

Updating or reseting a tkinter display

I'm working on a small Tkinter program where once started it prompts you to input a name then after clicking submit it will display "Welcome to my world". I'm having issues with either retrieving the input and displaying it in a new window or updating the window with the new information but it displays Py_Var1 as the entry name. What am I doing wrong, is it because I'm trying to display information in a new window or am I using the functions wrong?
Here is my code
from tkinter import *
root = Tk()
#Functions
def info():
a= entry_1.get()
def close_window(root):
root.destroy()
def comb(event=None):
info()
close_window(root)
#Display
input_1 = Label(root, text=" Name: ", bg= "light grey", fg="blue", font=("Arial", 16))
entry_1 = Entry(root, bg= "white", fg= "black", bd= 5, relief= SUNKEN, font=("Arial", 12))
button = Button(root, text="Submit", command=comb, bd= 6, relief= RAISED, fg='blue', font=("Arial", 12))
root.bind("<Return>", comb)
aVar = StringVar(entry_1.get())
aVar.set(aVar)
#entry display
input_1.grid(row=1, sticky=E)
entry_1.grid(row=1, column=1)
button.grid(row=3, column=1)
root.mainloop()
##Second Window
root = Tk()
Var = StringVar()
Var.set(info)
t1 = Label(root, text="Welcome")
t2 = Label(root, text= Var)
t3 = Label(root, text="to my world")
#Display
t1.grid(row=1, column=1)
t2.grid(row=1, column=2)
t3.grid(row=1, column=3)
root.mainloop()
I think the problem was that you were trying to access a variable which you assigned before you destroyed the window after it was destroyed which Tkinter can't do. Needed a global variable. Your code should work now.
from tkinter import *
root = Tk()
#Functions
def info():
global a
a= entry_1.get()
def close_window(root):
root.destroy()
def comb(event=None):
info()
close_window(root)
#Display
input_1 = Label(root, text=" Name: ", bg= "light grey", fg="blue", font=("Arial", 16))
entry_1 = Entry(root, bg= "white", fg= "black", bd= 5, relief= SUNKEN, font=("Arial", 12))
button = Button(root, text="Submit", command=comb, bd= 6, relief= RAISED, fg='blue', font=("Arial", 12))
root.bind("<Return>", comb)
#entry display
input_1.grid(row=1, sticky=E)
entry_1.grid(row=1, column=1)
button.grid(row=3, column=1)
root.mainloop()
##Second Window
root = Tk()
t1 = Label(root, text="Welcome "+str(a)+" to my world")
##t2 = Label(root, text= Var)
##t3 = Label(root, text="to my world") # cleaner this way
#Display
t1.grid(row=1, column=1)
#t2.grid(row=1, column=2)
#t3.grid(row=1, column=3)
root.mainloop()
It is not running because there are many errors and no logic.
You use many functions whithout reason and none of them returns values.
Also, you destroy the Entry widget closing the root window and after that
you are asking to get the text from the Entry you just destroyed using a function which don't return anything. Even if you don't destroy the root window and use a toplevel window, still this program will not work because your function don't return anything.
It looks like you don't understand the basic usage of functions. Consider to play with functions with simple programs before try something more complicated.

Resources