Related
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()
This is the last stage of my Python file.
What I am attempting to do is have frame 5 unhidden when Textbox2 value is between 2 numeric numbers.
This an piece out of my original 100+ frames file.
I was able to complete this whole file as an Excel file.
I am stuck on the code for Deff onclick 5.
Any help would be greatly appreciated.
Thanks as always!!
from tkinter import *
from tkinter import Tk
import tkinter as tk
from tkinter import ttk
root=tk.Tk()
root.title("Dental Milling Machines")
root.geometry("1000x900")
def onclick5():
if ([textbox2], [">0" and "<10.1"]):
frame5.grid(row=0, column=2, pady=2,sticky="NW")
else:
frame5.grid_forget()
def onclick1():
textbox1.delete('1.0', 'end')
textbox1.insert('end', '2.83')
def onclick2():
textbox1.delete('1.0', 'end')
textbox1.insert('end', '5.66')
def onclick3():
textbox1.delete('1.0', 'end')
textbox1.insert('end', '8.49')
def to_float( string ):
try:
return float( string )
except ValueError:
return 0.0
def onclick4():
tot = 0.0
for box in text_boxes_to_sum:
v = box.get( '1.0', 'end' )
tot += to_float( v )
textbox2.delete( '1.0', 'end' )
textbox2.insert( 'end', str(tot) )
button_var1 = tk.IntVar()
button_var2 = tk.IntVar()
frame1 = Frame(root, height = 150, width= 150, relief= RAISED, bd=8, bg="blue")
frame2 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=8, bg="lightblue")
frame3 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=8, bg="lightblue")
frame4 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=8, bg="lightblue")
frame5 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=8, bg="lightblue")
textbox1 = Text(frame2, borderwidth=1, wrap="none", width=10, height=2)
textbox1.grid(row=5, column=0, sticky="w")
textbox2 = Text(frame3, borderwidth=1, wrap="none", width=10, height=1)
textbox2.grid(row=1, column=0, sticky="NESW")
textbox3 = Text(frame5, borderwidth=1, wrap="none", width=10, height=1)
textbox3.grid(row=0, column=0, sticky="NESW")
text_boxes_to_sum = [ textbox1 ]
frame1.grid(row=0, column=0, pady=2,sticky="NW")
frame2.grid(row=1, column=0, pady=2,sticky="NW")
label = Label(frame2, text="Select # Of Units Being Used", fg="red")
label.grid(row=0, column=0, pady= 1, padx=1, sticky= "W")
frame3.grid(row=2, column=0, pady=2,sticky="NW")
label = Label(frame3, text="Total CFM Values", fg="red")
label.grid(row=0, column=0, pady= 1, padx=1, sticky= "W")
frame4 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=0, bg="lightyellow")
frame4.grid(row=8, column=0, pady=2,padx=3, sticky="E")
frame5 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=0, bg="lightyellow")
label = Label(frame5, text="Reccommended Compressor Package", fg="red")
label.grid(row=0, column=0, pady= 1, padx=1, sticky= "W")
label = Label(frame5, text="Compressor Package 1", fg="black")
label.grid(row=2, column=0, pady= 10, padx=5, sticky= "EW")
button1=Radiobutton(frame2, text="1 Unit ", variable=button_var1, command=onclick1)
button1.grid(row=1, column=0, pady= 1, padx= 5, sticky= "W")
button2=Radiobutton(frame2, text="2 Units ", variable=button_var1, command=onclick2)
button2.grid(row=2, column=0, pady= 1, padx= 5, sticky= "W")
button3=Radiobutton(frame2, text="3 Units ", variable=button_var1, command=onclick3)
button3.grid(row=3, column=0, pady= 1, padx= 5, sticky= "W")
button4=Radiobutton(frame3, text="Show Values ", variable=button_var1, command=onclick4, value = 0 )
button4.grid(row=3, column=0, pady= 1, padx= 5, sticky= "W")
button5=Radiobutton(frame4, text="Show Reccommended Compressor Package ", variable=button_var2, command=onclick5)
button5.grid(row=0, column=0, pady= 1, padx= 5, sticky= "W")
root.mainloop()
I have researched for 3 weeks and could find no solution.
I have read numerous tags and have also tried modifying code
Most of the tags refer to Java or some other programming language other than Python
My file has upwards of 80 frame which will all have 3 buttons and 1 textbox.
I sent over 1 frame with 3 radio buttons and a textbox.
Would this work or should I go in a different direction.
Any advice would be greatly appreciated.
from tkinter import *
from tkinter import Tk
import tkinter as tk
from tkinter import ttk
root=tk.Tk()
root.title("Dental Milling Machines")
root.geometry("1000x900")
def func1(event):
insert("")
textbox1.insert('1.5')
def onclick1():
textbox1.insert('<Return>', func1)
button_var1 = tk.IntVar()
frame1 = Frame(root, height = 150, width= 150, relief= RAISED, bd=8, bg="blue")
frame1.grid(row=1, column=0, pady=2,sticky="NW")
frame2 = Frame(frame1, height = 150, width= 150, relief= RAISED, bd=8, bg="lightblue")
frame2.grid(row=1, column=0, pady=2,sticky="NW")
label = Label(frame2, text="Select # Of Units", fg="red")
label.grid(row=0, column=0, pady= 1, padx=3, sticky= "W")
textbox1 = Text(frame2, borderwidth=1, wrap="none", width=10, height=2)
textbox1.grid(row=0, column=1, sticky="w")
button1=Radiobutton(frame2, text="1 Unit ", variable=button_var1, command=onclick1)
button1.grid(row=1, column=0, pady= 1, padx= 5, sticky= "W")
root.mainloop()
If you want to insert something into the text box whenever the radio button is click, just modify your code as below:
def onclick1():
textbox1.delete('1.0', 'end') # clear the text box
textbox1.insert('end', '1.5') # insert whatever you want into text box
...
button1 = Radiobutton(frame2, text="1 Unit", variable=button_var1, command=onclick1)
...
I am trying to call a function on a button click which will call second function that updates the fill color of an oval. I am getting an error that the object doesnt have the attribute. The goal of the program will be to eventually update the the signal light colors as variables linked to each go from 0 to 1 but right now i'm just getting the back end working. I have looked at dozens of examples over the last two days and cant get this to work.
import tkinter as tk
class WaysideSimulator(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
# self.pack()
self.grid()
self.create_widgets()
def create_widgets(self):
# Draw Buttons
self.Start_Simulation_Button = tk.Button(self, text="Start Simulation", command=self.start_simulation)
self.Start_Simulation_Button.grid(row=0, column=0)
self.End_Simulation_Button = tk.Button(self, text="End Simulation", fg="red", command=self.master.destroy)
self.End_Simulation_Button.grid(row=1, column=0)
# Top Signal Buttons
self.Top_Red_Button = tk.Button(self, text="Set Top Signal Red", command=self.set_top_red)
self.Top_Red_Button.grid(row=2, column=0)
self.Top_Yellow_Button = tk.Button(self, text="Set Top Signal Yellow", command=self.set_top_yellow)
# self.Searchlight_Button.pack(side="bottom")
self.Top_Yellow_Button.grid(row=3, column=0)
self.Top_Green_Button = tk.Button(self, text="Set Top Signal Green", command=self.set_top_green)
self.Top_Green_Button.grid(row=4, column=0)
self.Top_Black_Button = tk.Button(self, text="Set Top Signal Black", command=self.set_top_off)
self.Top_Black_Button.grid(row=5, column=0)
# Middle Signal Buttons
self.Middle_Red_Button = tk.Button(self, text="Set Middle Signal Red", command=self.set_middle_red)
self.Middle_Red_Button.grid(row=2, column=1)
self.Middle_Yellow_Button = tk.Button(self, text="Set Middle Signal Yellow", command=self.set_middle_yellow)
self.Middle_Yellow_Button.grid(row=3, column=1)
self.Middle_Green_Button = tk.Button(self, text="Set Middle Signal Green", command=self.set_middle_green)
self.Middle_Green_Button.grid(row=4, column=1)
self.Middle_Black_Button = tk.Button(self, text="Set Middle Signal Black", command=self.set_middle_black)
self.Middle_Black_Button.grid(row=5, column=1)
# Bottom Signal Buttons
self.Bottom_Red_Button = tk.Button(self, text="Set Bottom Signal Red", command=self.set_bottom_red)
self.Bottom_Red_Button.grid(row=2, column=2)
self.Bottom_Yellow_Button = tk.Button(self, text="Set Bottom Signal Yellow", command=self.set_bottom_yellow)
self.Bottom_Yellow_Button.grid(row=3, column=2)
self.Bottom_Green_Button = tk.Button(self, text="Set Bottom Signal Green", command=self.set_bottom_green)
self.Bottom_Green_Button.grid(row=4, column=2)
self.Bottom_Black_Button = tk.Button(self, text="Set Bottom Signal Black", command=self.set_bottom_black)
self.Bottom_Black_Button.grid(row=5, column=2)
# Draw the Canvas
self.canvas = tk.Canvas(self, width=500, height=500, bg="white")
self.canvas.grid()
# Draw the Searchlight Signal Heads
self.signal_pole = self.canvas.create_rectangle(245, 20, 255, 500, fill="grey")
self.top_signal_head = self.canvas.create_oval(200, 10, 300, 110, fill="black")
self.middle_signal_head = self.canvas.create_oval(200, 160, 300, 260, fill="black")
self.bottom_signal_head = self.canvas.create_oval(200, 310, 300, 410, fill="black")
self.top_signal_light = self.canvas.create_oval(240, 50, 260, 70, fill="red", tags="top_light")
self.top_signal_light_ON = True
self.middle_signal_light_ON = self.canvas.create_oval(240, 200, 260, 220, fill="yellow", tags="middle_light")
self.middle_light_ON = True
self.bottom_signal_light = self.canvas.create_oval(240, 350, 260, 370, fill="green", tags="bottom_light")
self.bottom_signal_light_ON = True
# Function Definitions
def set_top_red(self):
self.canvas.itemconfig("top_light", fill="Red")
self.top_signal_light_ON = True
print("Top signal is RED")
def set_top_yellow(self):
self.canvas.itemconfig("top_light", fill="yellow")
self.top_signal_light_ON = True
print("Top signal is YELLOW")
def set_top_green(self):
self.canvas.itemconfig("top_light", fill="green")
self.top_signal_light_ON = True
print("Top signal is GREEN.")
def set_top_off(self):
self.canvas.itemconfig("top_light", fill="black")
self.top_signal_light_ON = False
print("Top signal is OFF.")
def set_middle_red(self):
self.canvas.itemconfig("middle_light", fill="Red")
self.middle_light_ON = True
print("Middle signal is RED")
def set_middle_yellow(self):
self.canvas.itemconfig("middle_light", fill="yellow")
self.middle_light_ON = True
print("middle signal is YELLOW")
def set_middle_green(self):
self.canvas.itemconfig("middle_light", fill="green")
self.middle_light_ON = True
print("Middle signal is GREEN.")
def set_middle_black(self):
self.canvas.itemconfig("middle_light", fill="black")
self.middle_light_ON = False
print("Middle signal is OFF.")
def set_bottom_red(self):
self.canvas.itemconfig("bottom_light", fill="Red")
self.middle_light_ON = True
print("Bottom signal is RED")
def set_bottom_yellow(self):
self.canvas.itemconfig("bottom_light", fill="yellow")
self.middle_light_ON = True
print("Bottom signal is YELLOW")
def set_bottom_green(self):
self.canvas.itemconfig("bottom_light", fill="green")
self.middle_light_ON = True
print("Bottom signal is GREEN.")
def set_bottom_black(self):
self.canvas.itemconfig("bottom_light", fill="black")
self.middle_light_ON = False
print("Bottom signal is OFF.")
# Simulation Functions
def start_simulation(self):
print("Searchlight Simulation Started")
self.canvas.itemconfig("top_light", fill="black")
self.canvas.itemconfig("middle_light", fill="black")
self.canvas.itemconfig("bottom_light", fill="black")
self.top_signal_light_ON = False
self.middle_signal_light_ON = False
self.bottom_signal_light_ON = False
print("All signals are OFF")
def main():
root = tk.Tk()
root.title("Searchlight Simulator")
root.geometry("500x650")
# root.resizable(0, 0)
s1 = WaysideSimulator(master=root)
s1.mainloop()
if __name__ == '__main__':
main()
I have a GUI where I have created a canvas and I have two frames created inside it and using canvas.create_window.One on the top with four push buttons.On click of a button I should create a frame with some widgets down to the first frame. So, now I want previous frame to be detroyed(or refreshed or cleared or deleted) while i am switching between the buttons.Now the frames are getting stacked on top of each other.so below is my code,
from tkinter import *
#Creating root window
root = Tk()
root.geometry("1000x1000")
#Still don't know how it works but some how made it work :P :P
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=0)
#Creaed canvas for setting up a scroll bar
canv=Canvas(root,width=850, height=650, background='blue')
vsb = Scrollbar(root, orient="vertical", command=canv.yview)
canv.config(yscrollcommand=vsb.set)
vsb.grid(row=1,column=1,sticky="ns")
canv.config(scrollregion=(0, 0,600,1000))
canv.grid(row=1, column=0)
canv.bind('<Configure>',canv.config(scrollregion=canv.bbox('all')))
#Frame for the top push buttons
mainframe1 = Frame(root, height = 20,width= 250,bg = 'white')
canvas_frame = canv.create_window((4, 4),window=mainframe1,anchor="nw")
b1 = Button(mainframe1,text = "butt 1",width = 24, height = 1,command=lambda: buttonClick(1))
b2 = Button(mainframe1,text = "butt 2",width = 24, height = 1,command=lambda: buttonClick(2))
b3 = Button(mainframe1,text = "butt 3",width = 24, height = 1,command=lambda: buttonClick(3))
b4 = Button(mainframe1,text = "Butt 4",width = 24, height = 1,command=lambda: buttonClick(4))
b1.grid(row=0, column=0, padx=15, pady=10)
b2.grid(row=0, column=1, padx=15, pady=10)
b3.grid(row=0, column=2, padx=15, pady=10)
b4.grid(row=0, column=3, padx=15, pady=10)
#Method to work based on Button click
def buttonClick(num):
if num == 1:
#Creating Frame inside Canvas
mainframe2 = Frame(root, height = 200,width= 250,bg = 'white')
canvas_frame = canv.create_window((80,100),window = mainframe2,anchor="nw")
label = Label(mainframe2,text="frame for butt 1",font=('Courier',-20,'bold'))
#label.grid_rowconfigure(1,weight=1)
#label.columnconfigure(1,weight=1)
label.grid(row=0,column=3)
#Create a Tkinter variable
varmonth = StringVar()
varyear = StringVar()
varmonth.set('January') # set the default option
varyear.set('2017')
#Option Menu for Dropdown list boxes
#For Month
popupMenu = OptionMenu(mainframe2, varmonth, 'January', 'February', 'March', 'April', 'May','June','July','August','Septempber','October','November','December')
Label(mainframe2, text="Select Month",font=('Courier',-15,'bold')).grid(row=2, column=1,sticky='e',padx=15,pady=15)
popupMenu.grid(row=2, column=2,padx=20,sticky="ew")
#For year
popupMenu = OptionMenu(mainframe2, varyear, '2017','2018','2019')
Label(mainframe2, text="Select Year",font=('Courier',-15,'bold')).grid(row=2, column=7,padx=20,pady=25)
popupMenu.grid(row=2, column=8,padx=15,pady=20)
#For Generate Report Button
buttongreport = Button(mainframe2,text = 'Generate Sales report',width = 24, height = 1,command=lambda: buttonClick(gr))
buttongreport.grid(row=8, column=3,columnspan=2, padx=10, pady=10)
elif(num==2):
mainframe3 = Frame(root, height=200, width=250, bg='white')
canvas_frame = canv.create_window((80, 100), window=mainframe3, anchor="nw")
label = Label(mainframe3, text="Frame for butt 2", font=('Courier', -20, 'bold'))
# label.grid_rowconfigure(1,weight=1)
# label.columnconfigure(1,weight=1)
label.grid(row=0, column=3)
# Create a Tkinter variable
varmonth = StringVar()
varyear = StringVar()
varmonth.set('January') # set the default option
varyear.set('2017')
popupMenu = OptionMenu(mainframe3, varmonth, 'January', 'February', 'March', 'April', 'May', 'June', 'July',
'August', 'Septempber', 'October', 'November', 'December')
Label(mainframe3, text="Select Month", font=('Courier', -15, 'bold')).grid(row=2, column=1, sticky='e', padx=15,
pady=15)
popupMenu.grid(row=2, column=2, padx=20, sticky="ew")
popupMenu = OptionMenu(mainframe3, varyear, '2017', '2018', '2019')
Label(mainframe3, text="Select Year", font=('Courier', -15, 'bold')).grid(row=2, column=7, padx=20, pady=25)
popupMenu.grid(row=2, column=8, padx=15, pady=20)
buttongreport = Button(mainframe3, text='Generate Sales report', width=24, height=1,
command=lambda: buttonClick(gr))
buttongreport.grid(row=8, column=3, columnspan=2, padx=10, pady=10)
elif(num==3):
mainframe4 = Frame(root, height=200, width=250, bg='white')
canvas_frame = canv.create_window((80, 100), window=mainframe4, anchor="nw")
label = Label(mainframe4, text=" Frame for Butt 4", font=('Courier', -20, 'bold'))
# label.grid_rowconfigure(1,weight=1)
# label.columnconfigure(1,weight=1)
label.grid(row=0, column=2)
# Create a Tkinter variable
varmonth = StringVar()
varyear = StringVar()
varmonth.set('1: January to April') # set the default option
varyear.set('2017')
popupMenu = OptionMenu(mainframe4, varmonth, '1: January to April', '2: May to August', '3: Septempber to December')
Label(mainframe4, text="Select Quarter", font=('Courier', -15, 'bold')).grid(row=2, column=1, sticky='e', padx=15,
pady=15)
popupMenu.grid(row=2, column=2, padx=20, sticky="ew")
popupMenu = OptionMenu(mainframe4, varyear, '2017', '2018', '2019')
Label(mainframe4, text="Select Year", font=('Courier', -15, 'bold')).grid(row=2, column=7, padx=20, pady=25)
popupMenu.grid(row=2, column=8, padx=15, pady=20)
buttongreport = Button(mainframe4, text='Generate Sales report', width=24, height=1,
command=lambda: buttonClick(gr))
buttongreport.grid(row=8, column=2, padx=10, pady=10)
root.mainloop()
I have written the code in procedural way.Sorry for the long code.
You can use canvas.delete(...) to remove the currently displayed frame whenever a button is clicked. But you need to declare a global variable to hold the current frame displayed:
open_frame = None
Then modify buttonClick(...):
def buttonClick(num):
global open_frame
if open_frame:
canv.delete(open_frame)
if num == 1:
...
open_frame = canv.create_window(...)
...
elif num == 2:
...
open_frame = canv.create_window(...)
...
elif num == 3:
...
open_frame = canv.create_window(...)
...
You can use frame.destroy().
destroy() method will delete the frame and all of its children will also be destroyed.