Python tkinter checkbox. Обновление списка через onvalue, offvalue
Не могу понять как можно к checkbox можно привязать команду. Мне нужно чтобы когда checkbox был активен, то он добавлял бы в список свою переменную, а когда он выключен, то соответственно удалял эту переменную из списка, но не у меня так и не получилось изменить список. Ниже код программы, она не закончена, т.к столкнулся с проблемой
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import *
from tkinter import messagebox
# Команды
def show_graphic():
if k:
x = list(range(0,len(test)))
plt.plot(x, test)
plt.show()
print(test)
def addbutton():
a = box_1.get()
if a:
try:
a = int(a)
k.append(a)
except ValueError:
messagebox.showwarning("Внимание!", "Вы ввели буквы")
else:
messagebox.showwarning("Внимание!","Пустое поле")
# После проверки идет создание checkbutton (Максимум будет 10 checkbutton)
for i in range(len(k)):
print(k[i])
for j in range(i+1):
if j == 0:
check1 = k[j]
print("check1", check1)
Checkbutton(win, text=check1, variable=check1,
onvalue=lambda check2, test: test.append(check2),
offvalue=lambda check2, test: test.remove(check2)
).place(x=200 + j * 60, y=50)
elif j == 1:
check2 = k[j]
print("check2", check2)
Checkbutton(win, text=check2, variable=check2,
onvalue=lambda check2, test: test.append(check2),
offvalue=lambda check2, test: test.remove(check2)
).place(x=200 + j * 60, y=50)
elif j == 2:
check3 = k[j]
print("check3", check3)
Checkbutton(win, text=check3, variable=check3,
onvalue=lambda check3, test: test.append(check3),
offvalue=lambda check3, test: test.remove(check3)
).place(x=200 + j * 60, y=50)
# Основное окно
win = Tk()
win.geometry("800x400+500+50")
win.resizable(False, False)
win.title("Test")
# k - список для сбора данных из tk.Entry и последующего добавления его в checkbutton
# test - список который по идее должен изменяться в зависимости от положения checkbutt(On или Off)
k = []
test = []
# Заранее создал переменные для того чтобы добавлять их в список test
check1 = check2 = check3 = check4 = check5 = check6 = check7 = check8 = check9 = check10 = tk.IntVar()
tk.Label(win, text="Введите данные").place(x=10, y=10)
tk.Label(win, text="Введите процент").place(x=10, y=60)
# Поля для ввода данных
box_1 = tk.Entry(win, width=10)
box_1.place(x=10, y=30)
box_2 = tk.Entry(win, width=10)
box_2.place(x=10, y=80)
tk.Button(win, text="Добавить", command=addbutton).place(x=80, y=30)
tk.Button(win, text="Проверить график(Тест)", command=show_graphic).place(x=80, y=80)
win.mainloop()
Ответы (1 шт):
Автор решения: GrAnd
→ Ссылка
Чего-то у вас в коде с этими Checkbutton полная неразбериха.
- Во-первых,
onvalueиoffvalue- это значения, которые идут вvariableкогда ставят или снимают галочку. - Во-вторых, процедура, которая вызывается при смене состояния
Checkbutton, должна передаваться через параметрcommand. - В-третьих, вроде бы у вас есть проверки на некорректный ввод, но после сообщений об ошибке ввода функция продолжает своё выполнение как ни в чём не бывало.
- В-четвёртых, у вас образуется лютое наслоение из
Checkbutton, т.к. их новый набор каждый раз создаётся при вызовеaddbutton(). А предыдущие наборы никуда не деваются. Честно говоря, я не понял предназначения этих вложенных циклов для создания checkbutton'ов.
И ещё, ваш список test зависит от того в какой последовательность отмечались чекбоксы. Но не знаю, может так было задумано.
Ну, и, в общем, поправленный код:
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import *
from tkinter import messagebox
# Команды
def show_graphic():
if k:
x = range(len(test))
plt.plot(x, test)
plt.show()
print(test)
def checkbutton_changed(index):
if check_vars[index].get():
test.append(k[index])
else:
test.remove(k[index])
def addbutton():
a = box_1.get()
if a:
try:
a = int(a)
if a in k:
messagebox.showwarning("Внимание!", f"{a} уже было")
return
if len(k) < 10:
k.append(a)
box_1.delete(0, END)
else:
messagebox.showwarning("Внимание!", "Лимит достигнут")
return
except ValueError:
messagebox.showwarning("Внимание!", "Вы ввели буквы")
return
else:
messagebox.showwarning("Внимание!", "Пустое поле")
return
# После проверки идет создание checkbutton (Максимум будет 10 checkbutton)
index = len(k) - 1
Checkbutton(win, text=k[index], variable=check_vars[index],
onvalue=1, offvalue=0,
command=lambda index=index: checkbutton_changed(index)
).place(x=200 + index * 60, y=50)
# Основное окно
win = Tk()
win.geometry("800x400+500+50")
win.resizable(False, False)
win.title("Test")
# k - список для сбора данных из tk.Entry и последующего добавления его в checkbutton
k = []
# test - список который по идее должен изменяться в зависимости от положения checkbutt(On или Off)
test = []
# Переменные хранящие состояние checkbutton'ов
check_vars = [tk.IntVar() for _ in range(10)]
tk.Label(win, text="Введите данные").place(x=10, y=10)
tk.Label(win, text="Введите процент").place(x=10, y=60)
# Поля для ввода данных
box_1 = tk.Entry(win, width=10)
box_1.place(x=10, y=30)
box_2 = tk.Entry(win, width=10)
box_2.place(x=10, y=80)
tk.Button(win, text="Добавить", command=addbutton).place(x=80, y=30)
tk.Button(win, text="Проверить график(Тест)", command=show_graphic).place(x=80, y=80)
win.mainloop()