My goal is to create a Tkinter GUI with a Scale that-when updated-will change the number of scales underneath the original scale. Currently my slider will work with only the highest 2 values in its range, and I cannot figure out why.
I have tried to use grid_remove() and grid_forget() to no success.
I have also used these posts as references to get as far as I am now:
- grid_remove not removing widgets
- grid()/grid_remove() functions don't do i would expect
- Python grid_remove
- Tkinter Grid Dynamic Layout
- tkinter grid_forget method
- grid_forget() not working for dynamic checkbox in tkinter
flowchart of code: create slider > on slider update read value of slider > if slider value = x then remove or add sliders
My current code is:
import tkinter as tk
from tkinter import *
# root window
root = tk.Tk()
root.geometry()
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
def makeslider(sliderval):
print(str(sliderval))
global slider2, slider3, slider4
if int(sliderval) == 1:
slider2 = tk.Scale(root, from_=1, to=5)
slider2.grid(column=0, row=1, sticky=tk.E, padx=5, pady=5)
slider3.grid_remove()
slider4.grid_remove()
if int(sliderval) == 2:
slider2 = tk.Scale(root, from_=1, to=5)
slider2.grid(column=0, row=1, sticky=tk.E, padx=5, pady=5)
slider3 = tk.Scale(root, from_=1, to=5)
slider3.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5)
slider4.grid_remove()
if int(sliderval) == 3:
slider2 = tk.Scale(root, from_=1, to=5)
slider2.grid(column=0, row=1, sticky=tk.E, padx=5, pady=5)
slider3 = tk.Scale(root, from_=1, to=5)
slider3.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5)
slider4 = tk.Scale(root, from_=1, to=5)
slider4.grid(column=2, row=1, sticky=tk.E, padx=5, pady=5)
# slider
slider1 = tk.Scale(root, from_=1, to=3, command=makeslider)
slider1.grid(column=0, row=0, sticky=tk.E, padx=5, pady=5)
root.mainloop()
CodePudding user response:
My error was in the way I called my command and how I structured my command. I used this tutorial Remove Widgets from grid in Tkinter
- Define your widgets outside of the def and instead only assign them a grid space within the def.
- Use lambda x: instead of lambda: because it has a positional argument (use lambda: if button and lambda x: if scale)
- use widget names as variables in the command
I was able to change my code to:
import tkinter as tk
from tkinter import *
# root window
root = tk.Tk()
root.geometry()
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
def makeslider(slider2,slider3,slider4):
sliderval=int(slider1.get())
print(str(int(sliderval)))
if int(sliderval) == 1:
slider2.grid(column=0, row=1, sticky=tk.E, padx=5, pady=5)
slider3.grid_remove()
slider4.grid_remove()
if int(sliderval) == 2:
slider2.grid(column=0, row=1, sticky=tk.E, padx=5, pady=5)
slider3.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5)
slider4.grid_remove()
if int(sliderval) == 3:
slider2.grid(column=0, row=1, sticky=tk.E, padx=5, pady=5)
slider3.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5)
slider4.grid(column=2, row=1, sticky=tk.E, padx=5, pady=5)
slider2 = tk.Scale(root, from_=1, to=5)
slider3 = tk.Scale(root, from_=1, to=5)
slider4 = tk.Scale(root, from_=1, to=5)
slider1 = tk.Scale(root, from_=1, to=3, command=lambda x: makeslider(slider2, slider3, slider4))
slider1.grid(column=0, row=0, sticky=tk.E, padx=5, pady=5)
root.mainloop()