Creating a dynamic multiplication application using scales - python

I am currently really stuck trying to make a program that dynamically multiples two numbers as a scale is moved from left to right.
# Module imports
import Tkinter as tk
# Function Definitions
class Application(tk.Frame):
def __init__(self, parent = None):
tk.Frame.__init__(self, parent)
self.parent = parent
self.setupUI()
self.createWidgets()
def setupUI(self):
self.parent.title("Multiplication Scale")
self.grid()
self.centerWindow()
def centerWindow(self):
app_width = 400
app_height = 250
sw = self.parent.winfo_screenwidth()
sh = self.parent.winfo_screenheight()
x = (sw - app_width)/2
y = (sh - app_height)/2
self.parent.geometry('%dx%d+%d+%d' % (app_width, app_height, x, y))
def quit_pressed(self):
self.parent.destroy()
def createWidgets(self):
self.value1 = tk.IntVar()
self.scaleFirstN = tk.Scale(self, from_=0, to=100,tickinterval=10,orient=tk.HORIZONTAL)
self.scaleFirstN.grid(row=0,column=0,columnspan=5,ipadx=100,padx=40,pady=10,sticky="n")
self.value1 = tk.IntVar()
self.scaleSecondN = tk.Scale(self, from_=0, to=100,tickinterval=10, orient=tk.HORIZONTAL)
self.scaleSecondN.grid(row=1,column=0,columnspan=5,ipadx=100,padx=40,pady=0,sticky="n")
self.value2 = tk.IntVar()
self.label1 = tk.Label(self,textvariable=self.value1, text=0,foreground="blue")
self.label1.grid(row=5,column=0,columnspan=5, ipadx=5, sticky="wes")
self.label2 = tk.Label(self,textvariable=self.value1, text=0,foreground="blue")
self.label2.grid(row=1,column=0,columnspan=5, ipadx=5, sticky="we")
self.label3 = tk.Label(self,textvariable=self.value1, text=0,foreground="blue")
self.label3.grid(row=1,column=0,columnspan=5, ipadx=5, sticky="we")
def onScale(self, val):
value = self.scale.get()
self.value.set(value)
# Main body
root = tk.Tk()
app = Application(root)
root.mainloop()

You were creating value1 twice and not doing anything with value2, then onScale() wasn't doing anything. You must set each Scale widget's command option to the desired callback function (onScale in this case).
def createWidgets(self):
self.value1 = tk.IntVar()
self.scaleFirstN = tk.Scale(self, from_=0, to=100,tickinterval=10,orient=tk.HORIZONTAL, command=self.onScale, var=self.value1)
self.scaleFirstN.grid(row=0,column=0,columnspan=5,ipadx=100,padx=40,pady=10,sticky="n")
self.value2 = tk.IntVar()
self.scaleSecondN = tk.Scale(self, from_=0, to=100,tickinterval=10, orient=tk.HORIZONTAL, command=self.onScale, var=self.value2)
self.scaleSecondN.grid(row=1,column=0,columnspan=5,ipadx=100,padx=40,pady=0,sticky="n")
self.label1 = tk.Label(self,textvariable=self.value1, text=0,foreground="blue")
self.label1.grid(row=5,column=0,columnspan=5, ipadx=5, sticky="wes")
self.label2 = tk.Label(self,textvariable=self.value2, text=0,foreground="blue")
self.label2.grid(row=6,column=0,columnspan=5, ipadx=5, sticky="we")
self.label3 = tk.Label(self, text=0,foreground="blue")
self.label3.grid(row=7,column=0,columnspan=5, ipadx=5, sticky="we")
def onScale(self, val):
self.label3.config(text=self.value1.get() * self.value2.get())

Related

multiple frames with tkinter - set checkbox default value

I want to move my one window tkinter GUI to a step by step with multiple windows. I am trying to set the default value of the checkbox named checkb_ult_tubo to 1 (checked) but although I set the variable to 1, the checkbox is still off by default.
I even tried to decleare a new variable (tk.IntVar) inside the Page5X class block and to set it to 1 but the checkbox still shows off.
This is my code
class Keep(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.shared_data ={
"rvo": tk.StringVar(),
'num_racks': tk.StringVar(),
'num_falcons': tk.StringVar(),
'first_tip': tk.StringVar(),
'ot_2_ip': tk.StringVar(),
'last_tube': tk.StringVar(),
'rack_completo_check' : tk.IntVar()
}
self.frames = {
'StartPage': StartPage(self, self),
'5x': Page5X(self, self),
'40x': Page40X(self, self),
'nfw': PageNFW(self, self),
'pc': PagePC(self, self),
}
self.current_frame = None
self.show_frame('StartPage')
def show_frame(self, name):
if self.current_frame:
self.current_frame.forget()
self.current_frame = self.frames[name]
self.current_frame.pack()
self.current_frame.update_widgets() # <-- update data in widgets
class StartPage(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
label_rvo = tk.Label(self, text='Reactivo a alicuotar:')
label_rvo.pack()
rvo = self.controller.shared_data["rvo"]
rb_rvo1 = tk.Radiobutton(
master=self,
text='Master Mix 5x',
value='5x',
variable=rvo)
rb_rvo1.pack(padx=3, pady=2)
rb_rvo2 = tk.Radiobutton(
master=self,
text='RT Mix 40x',
value='40x',
variable=rvo)
rb_rvo2.pack(padx=3, pady=2)
rb_rvo3 = tk.Radiobutton(
master=self,
text='Nuclease Free Water',
value='nfw',
variable=rvo)
rb_rvo3.pack(padx=3, pady=2)
rb_rvo4 = tk.Radiobutton(
master=self,
text='Positive Control',
value='pc',
variable=rvo)
rb_rvo4.pack(padx=3, pady=2)
button = tk.Button(self, text="Siguiente", command=self.next_page)
button.pack()
def update_widgets(self):
rvo = self.controller.shared_data["rvo"].get()
def next_page(self):
rvo = self.controller.shared_data["rvo"].get()
self.controller.show_frame(rvo)
class Page5X(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
################## SELECCION DEL ULTIMO TUBO ##################
sub_frame2 = tk.Frame(self)
def disable_enable_button():
if boton_ult_tubo["state"] == "normal":
boton_ult_tubo["state"] = "disabled"
else:
boton_ult_tubo["state"] = "normal"
def popup_select_tube():
last_tube = self.controller.shared_data["last_tube"]
def guardar_seleccion_tubo():
entry_ult_tubo.configure(state='normal')
entry_ult_tubo.delete(0, tk.END)
entry_ult_tubo.insert(0, last_tube.get())
entry_ult_tubo.configure(state='readonly')
popup.destroy()
popup = tk.Toplevel(self)
popup.wm_title("Seleccion del ultimo tubo")
label_tips = tk.Label(popup, text='Seleccione el ultimo tubo disponible:')
label_tips.grid(row=1, column=1, columnspan=12, padx=10, pady=10)
for i in range(8):
label_tips = tk.Label(popup, text=str(i + 1))
label_tips.grid(row=2, column=2 + i, padx=10, pady=10)
for j in range(5):
label_tips = tk.Label(popup, text=string.ascii_uppercase[j])
label_tips.grid(row=3 + j, column=1, padx=10, pady=10)
tips_list = []
for i in range(8):
for j in range(5):
tip = tk.Radiobutton(
master=popup,
value=string.ascii_uppercase[j] + str(i + 1),
variable=last_tube)
tips_list.append(tip)
tip.grid(row=3 + j, column=2 + i, padx=10, pady=10)
B1 = ttk.Button(popup, text="Guardar seleccion", command=guardar_seleccion_tubo)
B1.grid(row=11, column=1, columnspan=12, padx=10, pady=10)
popup.resizable(False, False)
popup.mainloop()
checkb_ult_tubo = tk.Checkbutton(sub_frame2,
text="Ultimo rack completo",
variable=self.controller.shared_data['rack_completo_check'],
height=1,
width=15,
command=disable_enable_button,
onvalue=0, offvalue=1)
self.controller.shared_data['rack_completo_check'].set(1)
checkb_ult_tubo.grid(row=1, column=1, columnspan=2, padx=3, pady=3)
label_ult_tubo2 = tk.Label(sub_frame2, text='Ultimo tubo:')
label_ult_tubo2.grid(row=2, column=1, columnspan=2, padx=3, pady=3)
entry_ult_tubo = tk.Entry(sub_frame2, width=4)
entry_ult_tubo.insert(0, 'E8')
entry_ult_tubo.configure(state='readonly')
entry_ult_tubo.grid(row=3, column=1, padx=3, pady=3)
boton_ult_tubo = tk.Button(sub_frame2, text="Seleccionar", state='disable', command=popup_select_tube)
boton_ult_tubo.grid(row=3, column=2, columnspan=1, padx=10, pady=3)
sub_frame2.pack()
def guardar(self):
self.controller.shared_data["num_racks"] = menu_num_racks.get()
self.controller.shared_data["num_falcons"] = menu_num_racks.get()
def update_widgets(self):
rack_completo_check = self.controller.shared_data['rack_completo_check'].get()
class Page40X(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
self.label = tk.Label(self, text="") # <-- create empty label
self.label.pack()
def update_widgets(self):
rvo = self.controller.shared_data["rvo"].get()
self.label["text"] = rvo
class PageNFW(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
self.label = tk.Label(self, text="") # <-- create empty label
self.label.pack()
def update_widgets(self):
rvo = self.controller.shared_data["rvo"].get()
self.label["text"] = rvo
class PagePC(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
self.label = tk.Label(self, text="") # <-- create empty label
self.label.pack()
def update_widgets(self):
rvo = self.controller.shared_data["rvo"].get()
self.label["text"] = rvo
if __name__ == "__main__":
keep = Keep()
keep.mainloop()
So I noticed that the onvalue inside of checkb_ult_tubo is 0, and the offvalue is 1. I think that when you set the value of the checkbox to 1, it remained off because the offvalue is 1. Try this:
checkb_ult_tubo = tk.Checkbutton(sub_frame2,
text="Ultimo rack completo",
variable=self.controller.shared_data['rack_completo_check'],
height=1,
width=15,
command=disable_enable_button,
onvalue=1, offvalue=0)

CLASS MATH -- Need Help getting an Int Value from XY -- Super Lost

Okay, so I am been learning python for 2 weeks and implementing TkInter now, I am trying to make an project where the user can set an Alarm and when the alarm rings the user will hit stop then the program will ask the user some random math questions, I been messing around and got everything up to the Math problem to work, I have a lot of placeholders in place and I am stuck with getting the answer of x and y to return to an INT, I have it made where it will show what x+y will equal and what the user enter but when I run the while loop my program just freezes. I assume its because the answer returns as a Label and that's not an INT, so all my issues are in my Math Class and have been trying for 3 days and cant figure it out. Please anything will be helpful, I tried using the .get method but that also gives me errors.
import tkinter as tk
import time
import datetime
from tkinter import *
from winsound import PlaySound, SND_FILENAME, SND_LOOP, SND_ASYNC
import random
class WakeUpApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side='top', fill='both', expand='true',)
container.grid_rowconfigure(0, minsize=400, weight=1)
container.grid_columnconfigure(0, minsize=250, weight=2)
self.frames = {}
for F in (Alarm, Chooser, Difficulty, Math):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky='nsew')
self.show_frame(Alarm)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
present = datetime.datetime.now()
now = present.strftime("%H:%M:%S")
class Alarm(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
Alarm.hour = tk.StringVar()
Alarm.min = tk.StringVar()
Alarm.sec = tk.StringVar()
hour_a = tk.Entry(self, text=Alarm.hour, width=4).place(x=50, y=50)
min_a = tk.Entry(self, text=Alarm.min, width=4).place(x=70, y=50)
sec_a = tk.Entry(self, text=Alarm.sec, width=4).place(x=90, y=50)
current_time = tk.Label(self, text=f'Current Time: {now}').place(x=0, y=30)
set_time = tk.Label(self, text='Set Time').place(x=0, y=50)
'''
VERY IMPORTANT -- THIS CODE STARTS THE ALARM
setalarm = tk.Button(self, text='Set Alarm', command=lambda: wake())
setalarm.place(x=90, y=90)
'''
setalarm = tk.Button(self, text='Set Alarm', command=lambda: controller.show_frame(Chooser))
setalarm.place(x=90, y=90)
def wake():
alarm_time = f'{Alarm.hour.get()}:{Alarm.min.get()}:{Alarm.sec.get()}'
alarm_clock(alarm_time)
def play_sound(self,):
PlaySound('Sound.wav', SND_FILENAME|SND_LOOP|SND_ASYNC)
def stop_sound(self):
PlaySound(None, SND_FILENAME)
def alarm_clock(alarm_time):
while True:
time.sleep(1)
present = datetime.datetime.now()
now = present.strftime("%H:%M:%S")
print(now)
if now == alarm_time:
break
if now == alarm_time:
play_sound(self)
testbutton = Button(self, text='pls work', command=lambda: stop_sound(self))
testbutton.pack()
class Chooser(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='Please Choose Your Wake Up Game')
label.pack(pady=50, padx=50)
math = tk.Button(self, text='Math Game',
height=5, width=15,
command=lambda: controller.show_frame(Difficulty))
math.place(x=125, y=75)
guesser = tk.Button(self, text='Guessing Game',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
guesser.place(x=125, y=175)
class Difficulty(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='Please Choose Your Difficulty for the Questions')
label.pack(pady=50, padx=50)
level1 = tk.Button(self, text='Level 1 \n ie: 12+17',
height=5, width=15,
command=lambda: controller.show_frame(Math))
level1.place(x=125, y=75)
level2 = tk.Button(self, text='Level 2 \n ie: 12*9',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
level2.place(x=125, y=175)
level3 = tk.Button(self, text='Level 3 \n ie: 6*7+21',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
level3.place(x=125, y=275)
class Math(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
x = tk.IntVar()
y = tk.IntVar()
z = tk.IntVar()
ab = tk.IntVar()
x = random.randint(1, 10)
y = random.randint(1, 10)
xy = int(x + y)
problem = tk.Label(self, text=f'{x} + {y}').place(x=0, y=30)
goal = tk.Label(self, text=xy).place(x=0, y=90)
solution = tk.Entry(self, text=z).place(x=0, y=50)
new = tk.Entry(self, text=ab).place(x=0, y=70)
def answer2(self):
py_guess = tk.Label(self, text=ab.get()).place(x=125, y=120)
button2 = tk.Button(self, text='GIVE ME Z PLS', command=lambda: answer())
button2.pack()
button2 = tk.Button(self, text='The Problem', command=lambda: answer2(self))
button2.pack()
def answer():
user_guess = tk.Label(self, text=z.get()).place(x=125, y=100)
level1(user_guess)
def level1(user_guess):
keepGoing = True
while keepGoing:
if (z == xy):
good = tk.Label(self, text='good job').pack()
keepGoing = False
else:
bad = tk.Label(self, text='nope go again').pack()
string_solution = solution.get()
int_solution = int(string_solution)
app = WakeUpApp()
app.mainloop()

How to access individual Button tkinter?

Goal : dynamically create label and button (represents a task) and when I click this button it should destroy the label and button.
Problem : Unable to access buttons individually
Here is my code :
class Gui:
# constructor
def __init__(self, root):
self.root = root
self.root.title("TASKS")
self.root.geometry("300x700")
self.root.resizable(width=False, height=False)
self.clock = Label(self.root, fg="blue")
self.clock.grid(row = 0,column = 0,padx = 80,pady = 40)
self.update_clock()
self.new_button = Button(self.root, text="New",command = self.newwindow).grid(row = 0, column =1)
self.r =0
# clock
def update_clock(self):
now = strftime("%H:%M:%S")
self.clock.configure(text=now)
self.clock.after(1000, self.update_clock)
# label creator
def label(self, txt):
self.l = Label(self.root, text=txt, fg="red",pady =15)
self.l.grid(row = self.r, column =0)
# button creator
def donebutton(self):
self.b = Button(self.root, text="Done",command = lambda : self.del_task())
self.b.grid(row = self.r,column = 1)
# create a task
def task(self,txt):
self.r +=1
self.label(txt)
self.donebutton()
# delete task
def del_task(self):
self.l.destroy()
self.b.destroy()
# display gui method
def display(self):
self.root.mainloop()
# new window
def newwindow(self):
self.newwindow = Toplevel(self.root)
self.newwindow.title("NEW TASK")
self.newwindow.geometry("300x200")
self.newwindow.resizable(width=False, height=False)
Label(self.newwindow,text="Task").grid()
self.t1 = Text(self.newwindow,height = 2,width = 36)
self.t2 = Text(self.newwindow,height = 2,width = 10)
self.t1.grid()
Label(self.newwindow, text="Time").grid()
self.t2.grid()
self.c_b=Button(self.newwindow,text = "CREATE",command = lambda : self.task(self.t1.get("1.0",END)))
self.c_b.grid()
if __name__ == '__main__':
a = Gui(Tk())
a.display()
Requesting help with the code and I do not mind changing the whole code.
You keep overwriting the button. You said you don't care if the code is written completely different so, I changed a bunch.
Windows, Clock and Tasks are separated into classes
no targetable references to windows or buttons are held
the command for the "New Button" creates the NewTasks window
the command for the "Done Button" destroys its parent
the command for the "Create Button" creates a Task in the main window
a scrollable frame was added so tasks can never vertically overflow the main window
start, pause, done and remove Buttons were included
a scrollable output panel was included
ability to reposition tasks in the display is included
task labels can be clicked to show their content in the output panel
start, pause and done report to the output, and done includes elapsed time
once a task is started it cannot be removed
a task can only be "done" if it is running
a modicum of widget/grid formatting was applied to stop the display from jumping around as tasks were created/removed
I got bored and built your app ... probably.
from tkinter import Tk, Button, Label, Toplevel, Text, Frame, Canvas, Scrollbar
from time import strftime, time
class Task(Frame):
def __init__(self, master, text, output, move, **kwargs):
Frame.__init__(self, master, **kwargs)
self.grid_columnconfigure(0, weight=1)
self.stored = []
self.starttime = 0
self.send_output= output
self.lbl = Label(self, text=text, height=1, anchor='nw', fg='blue', font='calibri 14')
self.lbl.grid(row=0, column=0, sticky='nswe')
self.lbl.bind('<1>', self.output)
font = 'consolas 10 bold'
self.b1 = Button(self, font=font, text=chr(9654), command=self.start)
self.b2 = Button(self, font=font, text=chr(10073)+chr(10073), state='disabled', command=self.pause)
self.b3 = Button(self, font=font, text=chr(10006), state='disabled', command=self.done)
self.b4 = Button(self, font=font, text=chr(9866), command=self.destroy)
self.b5 = Button(self, font=font, text=chr(9650), command=lambda: move(self, -1))
self.b6 = Button(self, font=font, text=chr(9660), command=lambda: move(self, 1))
self.b1.grid(row=0, column=1) #start
self.b2.grid(row=0, column=2) #pause
self.b3.grid(row=0, column=3) #done
self.b4.grid(row=0, column=4) #remove
self.b5.grid(row=0, column=5) #move up
self.b6.grid(row=0, column=6) #move down
def start(self):
self.b1['state'] = 'disabled'
self.b2['state'] = 'normal'
self.b3['state'] = 'normal'
self.b4['state'] = 'disabled'
self.starttime = time()
self.send_output(f"{self.lbl['text']}", f"{strftime('%I:%M:%S')} STARTED: ")
def pause(self):
self.b1['state'] = 'normal'
self.b2['state'] = 'disabled'
self.b3['state'] = 'disabled'
self.stored.append(time() - self.starttime)
self.send_output(f"{self.lbl['text']}", f"{strftime('%I:%M:%S')} PAUSED: ")
def done(self):
self.stored.append(time() - self.starttime)
t = sum(self.stored)
self.send_output(f"{self.lbl['text']}\telapsed time: {self.etime(t)}\n", f"{strftime('%I:%M:%S')} FINISHED: ")
self.destroy()
def etime(self, s):
h = int(s//3600)
s -= 3600*h
m = int(s//60)
s -= 60*m
return f'{h:02}:{m:02}:{int(s):02}'
def output(self, event):
self.send_output(self.lbl['text'], 'Task: ')
class NewTasks(Toplevel):
WIDTH = 416
HEIGHT = 50
def __init__(self, master, slave, output, move, **kwargs):
Toplevel.__init__(self, master, **kwargs)
self.title("New Task")
self.geometry(f'{NewTasks.WIDTH}x{NewTasks.HEIGHT}')
self.resizable(width=False, height=False)
Label(self, text="Task").grid(row=0, column=0)
txt = Text(self, height=2, width=36, font='consolas 12')
txt.grid(row=0, column=1)
Button(self, text="CREATE", command=lambda: self.create(slave, output, move, txt)).grid(row=0, column=2, sticky='e', padx=4, pady=12)
def create(self, target, output, move, txt):
t = Task(target.frame, txt.get("1.0",'end'), output, move)
t.grid(column=0, sticky='nswe')
target.update(t)
class ScrollFrame(Canvas):
def __init__(self, master, **kwargs):
Canvas.__init__(self, master, **kwargs)
vsb = Scrollbar(self, orient='vertical', command=self.yview)
vsb.pack(side='right', fill='y')
self.configure(yscrollcommand=vsb.set)
self.frame = Frame(self, height=0)
self.frame.grid_columnconfigure(0, weight=1)
self.frame.bind('<Configure>', lambda e:self.configure(scrollregion=self.bbox("all")))
self.create_window((0,0), width=App.WIDTH-20, window=self.frame, anchor="nw")
self.movelist = []
def update(self, target):
self.movelist.append(target)
def move_item(self, elem, dir=1):
c = self.frame.winfo_children()
i = self.movelist.index(elem)
if i+dir in range(0, len(self.movelist)):
e = self.movelist.pop(i)
self.movelist.insert(i+dir, e)
for n in range(len(self.movelist)):
while n < len(self.movelist) and self.movelist[n] not in c:
self.movelist.pop(n)
if n < len(self.movelist):
self.movelist[n].grid(row=n, column=0, sticky='nswe')
continue
break
class Clock(Label):
def __init__(self, master, **kwargs):
Label.__init__(self, master, **kwargs)
self.update()
def update(self):
self['text'] = strftime('%I:%M:%S')
self.after(1000, self.update)
class App(Tk):
WIDTH = 600
HEIGHT = 447
def __init__(self, **kwargs):
Tk.__init__(self, **kwargs)
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(0, weight=1)
Clock(self, fg="blue", font='calibri 18').grid(row=0, column=0, ipady=10, sticky='nswe')
sf = ScrollFrame(self, highlightthickness=0)
sf.grid(row=1, column=0, columnspan=3, sticky='nswe')
command = lambda: NewTasks(self, sf, self.output, sf.move_item)
Button(self, text="New", font='calibri 12', command=command).grid(row=0, column=1, columnspan=2)
self.out = Text(self, height=8, font="calibri 14")
self.out.grid(row=2, column=0, columnspan=2)
self.out.tag_configure("bold", font="calibri 12 bold")
vsb = Scrollbar(self, orient='vertical', command=self.out.yview)
vsb.grid(row=2, column=2, sticky='ns')
self.out.configure(yscrollcommand=vsb.set)
def output(self, text, btext=''):
self.out.insert('end', btext, 'bold')
self.out.insert('end', text)
if __name__ == '__main__':
app = App()
app.title("Task Scheduler")
app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
app.resizable(width=False, height=False)
app.mainloop()

How do I remove a checkbutton when it is checked

I have built a simple to-do list and I am trying to get the checkbox to remove itself when it is checked(to signify that the task has been completed)
I am not sure how I need to be implementing the function in order to remove itself. Can anyone help me out with this. I've combed through a list of pages and none of them have really indicated how you do this.
class App(object):
def __init__(self, master):
self.master = master
self.frame = Frame(master)
self.frame.grid()
self.addFrame = Frame(master)
self.addFrame.grid(row=0, column=0, columnspan=2, sticky='N')
self.listFrame = Frame(master)
self.listFrame.grid(row=1, column=0, columnspan=2, sticky='NW')
self.todoList = []
self.initUI()
def initUI(self):
self.entryBox = Entry(self.frame, width = 15)
self.entryBox.grid(row=0, column=0, sticky='N')
self.addButton = Button(self.frame, text="<-ADD->", command=self.add)
self.addButton.grid(row=0, column=1, sticky='N')
def removeCheckButton(self):
# - CONFUSED HOW TO REMOVE THE SPECIFIC CHECKBUTTON
pass
def add(self):
entry = self.entryBox.get()
self.entryBox.delete(0, END)
self.todoList.append(entry)
print self.todoList
var1 = IntVar()
self.buttonList = []
for n in range(len(self.todoList)):
lx = Checkbutton(self.listFrame, text=self.todoList[n], variable=self.todoList[n], command=removeCheckButton)
lx.grid(row=n, column=0, sticky='NW')
self.buttonList.append(lx)
print self.buttonList
Have a look at this. your add is a bit strangely designed (and incorrectly IMO), so I modified it slightly as well as other parts.
from tkinter import *
class App(object):
def __init__(self, master):
self.master = master
self.frame = Frame(master)
self.frame.grid()
self.addFrame = Frame(master)
self.addFrame.grid(row=0, column=0, columnspan=2, sticky='N')
self.listFrame = Frame(master)
self.listFrame.grid(row=1, column=0, columnspan=2, sticky='NW')
self.todoList = []
self.buttonList = [] #<--- button list is here now
self.initUI()
def initUI(self):
self.entryBox = Entry(self.frame, width = 15)
self.entryBox.grid(row=0, column=0, sticky='N')
self.addButton = Button(self.frame, text="<-ADD->", command=self.add)
self.addButton.grid(row=0, column=1, sticky='N')
def removeCheckButton(self, button_no):
# - CONFUSED HOW TO REMOVE THE SPECIFIC CHECKBUTTON
# print(button_no, self.buttonList[button_no])
#self.buttonList[button_no].grid_forget()
self.buttonList[button_no].destroy()
# del self.buttonList[button_no]
# del self.todoList[button_no]
def add(self):
entry = self.entryBox.get()
self.entryBox.delete(0, END)
self.todoList.append(entry)
print(self.todoList)
var1 = IntVar()
#self.buttonList = [] #<--- not sense having this here
# for n in range(len(self.todoList)): #<-- this for also very strange here.
n = len(self.buttonList)
lx = Checkbutton(self.listFrame,
text=self.todoList[n],
variable=self.todoList[n],
command=lambda ni=n: self.removeCheckButton(ni))
lx.grid(row=n, column=0, sticky='NW')
self.buttonList.append(lx)
# print(self.buttonList)
root = Tk()
app = App(root)
root.mainloop()
P.S.
I use python 3, but except the import part, the code should execute for you. Probably it needs more fixing, but the checkboxes get destroyed now as they supposed to.

Can't put canvas side by side with other elements using grid manager

This is my code:
class Main(tk.Frame):
w = 300
h = 300
def __init__(self,parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
self.l1 = tk.Label(self, text="Iterations").grid(column=0,row=0)
self.l2 = tk.Label(self, text="angle").grid(column=0,row=1)
self.l3 = tk.Label(self, text="axiom").grid(column=0,row=2)
self.l4 = tk.Label(self, text="rule1").grid(column=0,row=3)
self.l5 = tk.Label(self, text="rule2").grid(column=0, row=4)
self.l6 = tk.Label(self, text="constants").grid(column=0, row=5)
self.e1 = tk.Entry(self, text="Iterations").grid(column=1,row=0)
self.e2 = tk.Entry(self, text="angle").grid(column=1,row=1)
self.e3 = tk.Entry(self, text="axiom").grid(column=1,row=2)
self.e4 = tk.Entry(self, text="rule1").grid(column=1,row=3)
self.e5 = tk.Entry(self, text="rule2").grid(column=1, row=4)
self.e6 = tk.Entry(self, text="constants").grid(column=1, row=5)
self.cv = tk.Canvas(width=self.w, height=self.h, bg='white')
self.cv.grid(column=2, rowspan=5)
# self.render_image()
self.grid()
I want my entry boxes and canvas stay side by side, but labels and entry boxes are drawn below the canvas for some reason. I get this;
How can I show them side by side instead?
You haven't specified a row for your Canvas:
self.cv.grid(column=2, rowspan=5)
Just update this to include the top row:
self.cv.grid(column=2, rowspan=5, row=0)
Also rowspan should likely be 6 not 5.

Categories

Resources