Updating or reseting a tkinter display - python-3.x

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.

Related

Why is the tkinter text widget screwing up my cell sizes?

All was going well as seen in the 1st pic below. all the cells are the same perfect size. its great.
But then comes the implementation of the textbox. and all hell breaks loose. as seen in the 2nd picture it completely disrupts my grid layout. i dont want the textbox adjusting cell sizes, i want it to go where i tell it to go like all the other widgets do. Ive spent hours on this and no avail!
import tkinter as tk
from tkinter import ttk, scrolledtext
root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')
for i in range(0,20):
for x in range(0,20):
root.columnconfigure(i, weight=1)
root.rowconfigure(x, weight=1)
for i in range(0, 20): # 0-19(20 is excluded) so this will loop 10x
for x in range(0, 20):
tk.Label(root, text=f"C-{i}, R-{x}", bg="green", fg="white").grid(column=i, row=x, sticky="NSEW", padx=1, pady=1)
main_frame = tk.Label(root, text="MAIN FRAME", bg="blue", fg="white", anchor="n").grid(column=1, row=1, columnspan=18, rowspan=18, sticky="NSEW")
frame1 = tk.Label(root, text="FRAME 1", bg="red", fg="white", anchor="n").grid(column=2, row=2, columnspan=3, rowspan=16, sticky="NSEW")
frame2 = tk.Label(root, text="FRAME 2", bg="green", fg="white", anchor="n").grid(column=6, row=2, columnspan=6, rowspan=16, sticky="NSEW")
frame3 = tk.Label(root, text=" FRAME 3", bg="red", fg="white", anchor="n").grid(column=13, row=2, columnspan=5, rowspan=16, sticky="NSEW")
for i in range(2, 5): # start at 2 and end after the 3rd loop.
for x in range(3, 18): # to loop 15x and for index to start at 3 so i then put (3,18), 18-3 = 15
tk.Label(root, text=f"Button-{(x-2)}", bg="white", fg="black").grid(column=i, row=x, sticky="EW", padx=5, pady=5)
frame1_header = tk.Label(root, text="User Panel", bg="black", fg="white").grid(column=2, row=2, columnspan=3, sticky="SEW", padx=5, pady=5)
frame2_header = tk.Label(root, text="Editor", bg="black", fg="white").grid(column=6, row=2, columnspan=6, sticky="SEW", padx=5, pady=5)
frame3_header = tk.Label(root, text="Info Panel", bg="black", fg="white").grid(column=13, row=2, columnspan=5, sticky="SEW", padx=5, pady=5)
frame2_text_area = tk.Label(root, text="Text Box", bg="black", fg="white", anchor="center").grid(column=6, row=3, columnspan=4, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame2_list_box = tk.Label(root, text="List Box", bg="grey", fg="white", anchor="center").grid(column=10, row=3, columnspan=2, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame3_tab_panel = ttk.Notebook(root)
frame3_tab_panel.grid(column=13, row=3, columnspan=5, rowspan=15, sticky="NSEW", padx=5, pady=5)
tab1 = ttk.Frame(root)
tab2 = ttk.Frame(root)
tab3 = ttk.Frame(root)
frame3_tab_panel.add(tab1, text ='Generic Editor')
frame3_tab_panel.add(tab2, text ='Text Compare')
frame3_tab_panel.add(tab3, text ='Script Ref')
# width and height does indeed adjust the texbox size but the textbox still isnt properly sticking to the grid that i set.
frame3_tab_panel_tab1 = tk.Text(root, relief="ridge", bd=2, undo=True, wrap="none", background='#1E1E1E', insertbackground='white')#, width=40, height=10)
frame3_tab_panel_tab1.grid(column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5)
frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
frame3_tab_panel_tab1.focus()
root.mainloop()
"""
text_area = scrolledtext.ScrolledText(tab1, wrap = tk.WORD, width=40, height=10, font=("Times New Roman", 15))
text_area.grid(column = 0, pady = 10, padx = 10)
text_area.focus()
"""
without textbox. as you can see its all perfectly even.
FYI: this is just a template im working on so i can better understand tk's positioning.
textbox ruining grid by not adjusting itself accordingly and fitting to the grid i set.
There is a lot of wrong doing in your code and you really should take a good tutorial for tkinter and you may wish to have a brief overview of tkinters geometry management.
The biggest issue is whats causes your code to work differently as you expect it, you always define the root as the master. Every widget, except for the root window, has a master and is set by the ONLY positional argument every widget requiers. Note that if None is given, the root window is set by default. This is, because tkinter is built hirachically and at the top of this hirachy stands the root window (the instance of tk.Tk()).
A master should be a container and this means either the root window, a Toplevel or a Frame. Masters can have so called children, which can be every other widget plus frames that are handled as children. The relationship between a master and a frame are various, but for the scope of this question we will just look at the geometry.
Every widget has a geometry and can be received by the universal widget method .winfo_geometry() that will give you a geometry string 'widthxheight±x_offset±y_offset' (e.g. '120x50-0+20'). The geometry string is the basement for every calculations to order your widgets, which you can affect by choosing a geometry manager and different optional keywords. With those information an output will be created and displayed on your screen.
Suggestion:
import tkinter as tk
from tkinter import ttk, scrolledtext
def populate_frame_1():
frame_1_label = tk.Label(frame_1,text='User Panel',
background = 'black',
foreground = 'white')
frame_1_label.grid(column=0,row=0,sticky='ew',columnspan=3)
frame_1.columnconfigure(0,weight=1)
frame_1.columnconfigure(1,weight=1)
frame_1.columnconfigure(2,weight=1)
for i in range(0, 3):
for x in range(1, 16):
l = tk.Button(frame_1, text=f"Button-{(x-2)}",
bg="white", fg="black")
l.grid(column=i, row=x, sticky="EW", padx=5, pady=5)
def populate_frame_2():
frame_2_label = tk.Label(frame_2,text='Editor',
background = 'black',
foreground = 'white')
textbox = tk.Text(frame_2,width=35)
listbox = tk.Listbox(frame_2,bg='yellow')
frame_2_label.grid(column=0,row=0,sticky='ew',columnspan=6)
textbox.grid(column=0,row=1,sticky='ns',columnspan=4)
listbox.grid(column=4,row=1,sticky='ns',columnspan=2)
frame_2.rowconfigure(1,weight=2)
def populate_frame_3():
frame_3_label = tk.Label(frame_3,text='Info Panel',
background = 'black',
foreground = 'white')
frame_3_label.grid(column=0,row=0,sticky='ew',columnspan=5)
control_panel = ttk.Notebook(frame_3)
tab1 = ttk.Frame(control_panel)
tab2 = ttk.Frame(control_panel)
tab3 = ttk.Frame(control_panel)
control_panel.add(tab1, text ='Generic Editor')
control_panel.add(tab2, text ='Text Compare')
control_panel.add(tab3, text ='Script Ref')
control_panel.grid(column=0,row=1,sticky='nswe')
frame3_tab_panel_tab1 = tk.Text(tab1, relief="ridge", bd=2, undo=True,
wrap="none", background='#1E1E1E',
insertbackground='white',width=40, height=10)
frame3_tab_panel_tab1.pack(fill=tk.BOTH,expand=True)
frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
frame3_tab_panel_tab1.focus()
frame_3.rowconfigure(1,weight=2)
frame_3.columnconfigure(0,weight=2)
XOFFSET = 75
YOFFSET = 50
root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')
main_frame = tk.Frame(root,background='blue')
frame_1 = tk.Frame(main_frame,background='red')
frame_2 = tk.Frame(main_frame,background='green')
frame_3 = tk.Frame(main_frame,background='red')
main_frame.pack(fill=tk.BOTH,expand=True,
padx=XOFFSET,pady=YOFFSET)
frame_1.pack(side=tk.LEFT,fill=tk.BOTH,padx=XOFFSET,pady=YOFFSET,expand=True)
frame_2.pack(side=tk.LEFT,fill=tk.Y,pady=YOFFSET,expand=True)
frame_3.pack(side=tk.LEFT,fill=tk.BOTH,padx=XOFFSET,pady=YOFFSET,expand=True)
populate_frame_1()
populate_frame_2()
populate_frame_3()
root.mainloop()
Change
frame3_tab_panel_tab1.grid(
column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5
)
to
frame3_tab_panel_tab1.grid(
column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5,
sticky="NSEW"
)
I managed to solve it by replacing the Text() widget with the scrolledtext.ScrolledText() widget. Its strange. No grid was required and if i remove height and width then it messes it up. Why does height and width have such an impact? why does it even exist when you have things like column and row configure along with sticky. Tkinter is quite confusing sometimes with its logic. But anyways, got there in the end.
Here's the code in case anyone encounters a similar issue.
import tkinter as tk
from tkinter import ttk, scrolledtext
root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')
for i in range(0,20):
for x in range(0,20):
root.columnconfigure(i, weight=1)
root.rowconfigure(x, weight=1)
for i in range(0, 20): # 0-19(20 is excluded) so this will loop 10x
for x in range(0, 20):
tk.Label(root, text=f"C-{i}, R-{x}", bg="green", fg="white").grid(column=i, row=x, sticky="NSEW", padx=1, pady=1)
main_frame = tk.Label(root, text="MAIN FRAME", bg="blue", fg="white", anchor="n").grid(column=1, row=1, columnspan=18, rowspan=18, sticky="NSEW")
frame1 = tk.Label(root, text="FRAME 1", bg="red", fg="white", anchor="n").grid(column=2, row=2, columnspan=3, rowspan=16, sticky="NSEW")
frame2 = tk.Label(root, text="FRAME 2", bg="green", fg="white", anchor="n").grid(column=6, row=2, columnspan=6, rowspan=16, sticky="NSEW")
frame3 = tk.Label(root, text=" FRAME 3", bg="red", fg="white", anchor="n").grid(column=13, row=2, columnspan=5, rowspan=16, sticky="NSEW")
for i in range(2, 5): # start at 2 and end after the 3rd loop.
for x in range(3, 18): # to loop 15x and for index to start at 3 so i then put (3,18), 18-3 = 15
tk.Label(root, text=f"Button-{(x-2)}", bg="white", fg="black").grid(column=i, row=x, sticky="EW", padx=5, pady=5)
frame1_header = tk.Label(root, text="User Panel", bg="black", fg="white").grid(column=2, row=2, columnspan=3, sticky="SEW", padx=5, pady=5)
frame2_header = tk.Label(root, text="Editor", bg="black", fg="white").grid(column=6, row=2, columnspan=6, sticky="SEW", padx=5, pady=5)
frame3_header = tk.Label(root, text="Info Panel", bg="black", fg="white").grid(column=13, row=2, columnspan=5, sticky="SEW", padx=5, pady=5)
frame2_text_area = tk.Label(root, text="Text Box", bg="black", fg="white", anchor="center").grid(column=6, row=3, columnspan=4, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame2_list_box = tk.Label(root, text="List Box", bg="grey", fg="white", anchor="center").grid(column=10, row=3, columnspan=2, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame3_tab_panel = ttk.Notebook(root)
frame3_tab_panel.grid(column=13, row=3, columnspan=5, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame3_tab_panel_tab1 = scrolledtext.ScrolledText(root, bd=2, undo=True, wrap="none", width=40, height=10, font=("Times New Roman", 15), background='#1E1E1E', insertbackground='white')
frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
frame3_tab_panel_tab1.focus()
tab2 = ttk.Frame(root)
tab3 = ttk.Frame(root)
frame3_tab_panel.add(frame3_tab_panel_tab1, text ='Generic Editor')
frame3_tab_panel.add(tab2, text ='Text Compare')
frame3_tab_panel.add(tab3, text ='Script Ref')
root.mainloop()

theard not responding while in mainloop

I'm working on a project where when a button is press in my controller a string needs to appear on the GUI. so I used threading, pyserial and tkinter for the mission but everytime I press the button in my controller it doesnt work after mainloop works, send text to the controller works, the terminal is a class I bulit with variable channel for serial
def chat_menu(terminal):
chat_window = Tk()
chat_window.geometry("650x480")
input_text = Text(chat_window, height=20, width=30)
output_text = Text(chat_window, height=20, width=30)
title = Label(chat_window, text="Chat Mode", font=("Arial",
14, "bold"))
title_in = Label(chat_window, text="Input", font=("Arial", 14,
"bold"))
title_out = Label(chat_window, text="Output", font=("Arial",
14, "bold"))
text = input_text.get("1.0", END)
submit_button = Button(chat_window, height=3, width=20,
text="Submit",
font=('Arial', 16, 'bold'),
command=lambda: send_text(terminal, chat_window, input_text))
back_button = Button(chat_window, height=3, width=20,
text='Back', font=('Arial', 16, 'bold'),
command=lambda:
terminal.close_main(chat_window, 'd'))
terminal.data = None
title.grid(row=0, column=1)
input_text.grid(row=1, column=0)
output_text.grid(row=1, column=2)
title_in.grid(row=2, column=0)
title_out.grid(row=2, column=2)
submit_button.grid(row=3, column=0)
back_button.grid(row=3, column=2)
thread = threading.Thread(target=receive_text(terminal,
output_text))
thread.start()
mainloop()
def receive_text(terminal, output):
time.sleep(2)
received = False
while True:
while terminal.channel.in_waiting > 0:
received_dataterminal.channel.read_until(expected='\n')
output.insert(END, received_data.decode("ascii"))
received = True
if received:
break

Python Tkinter Button not appearing with grid

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()

I can't use the text from my Entry widget

There is something in my code that isn't letting me use the text from my Entry widget. I want to use the text a user will enter in my Entry widget, which i've called "textentry", in another part of my code but it doesn't seem to be storing it in a way i can use. In this example i'm just trying to print what is entered into the terminal.
I can get it to print if i uncomment the "print(textentry.get())" in my function.
As it is now i get ".!entry" printed in the terminal. i'm not sure I follow that output either.
I feel like it's probably something simple but i've been struggling a while and many different approaches but still not success.
import tkinter as tk
from tkinter import *
def click():
textentry.get()
# print(textentry.get())
Text_input_window.destroy()
Text_input_window= Tk()
Label (Text_input_window,text="Enter search word:", bg="black", fg="white").grid(row=1, column=0, sticky=W)
textentry = tk.Entry(Text_input_window, width=20, bg="white")
textentry.grid(row=2, column=0, sticky=W)
Button(Text_input_window, text="SUBMIT", width=6, command=click).grid(row=3, column=0, sticky=W)
Text_input_window.mainloop()
print(textentry)
Try it:
import tkinter as tk
from tkinter import *
Text_input_window = Tk()
textentry = StringVar()
def click():
global textentry
textentry = textentry_ent.get()
# print(textentry.get())
Text_input_window.destroy()
Label(Text_input_window, text="Enter search word:",
bg="black", fg="white").grid(row=1, column=0, sticky=W)
textentry_ent = tk.Entry(Text_input_window, textvariable=textentry,width=20, bg="white")
textentry_ent.grid(row=2, column=0, sticky=W)
Button(Text_input_window, text="SUBMIT", width=6,
command=click).grid(row=3, column=0, sticky=W)
Text_input_window.mainloop()
print(textentry)

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")

Resources