Найти - Пользователи
Полная версия: Tkinter как создать флажки и перебрать их циклом, а не if(ами).
Начало » GUI » Tkinter как создать флажки и перебрать их циклом, а не if(ами).
1
grand
Подскажите, решаю задачу из книги, нужно создать меню ресторана, где блюда будут выбираться флажками и сразу подсчитываться сумма выбранных блюд в текстовом поле. Задачу как просили я сделал вот код:
 from tkinter import *
class Application(Frame):
	"""GUI для ресторана."""
	def __init__(self, master):
		super(Application, self).__init__(master)
		self.grid()
		self.widgets()
		self.results_txt()
	def widgets(self):
		Label(self, text='Выбирите блюда которые хотите заказать:', bg='blue').grid(row=0, column=0, sticky=W)
		# Суп
		self.sup_klichky = BooleanVar()
		Checkbutton(self,
					text='Суп с клёцками \t --240 руб.',
					variable=self.sup_klichky,
					command=self.schet_txt,
					).grid(row=1, column=0, sticky=W)
		# Сметана
		self.sup_smetana = BooleanVar()
		Checkbutton(self,
					text='Сметана \t --30 руб.',
					variable=self.sup_smetana,
					command=self.schet_txt,
					).grid(row=2, column=0, padx=20, sticky=W)
		# Зелень
		self.sup_zelen = BooleanVar()
		Checkbutton(self,
					text='Зеленью \t --15 руб.',
					variable=self.sup_zelen,
					command=self.schet_txt,
					).grid(row=3, column=0, padx=20, sticky=W)
		# Майонез
		self.sup_maionez = BooleanVar()
		Checkbutton(self,
					text='Майонезом \t --20 руб.',
					variable=self.sup_maionez,
					command=self.schet_txt,
					).grid(row=4, column=0, padx=20, sticky=W)
		# Пицца
		self.pizza = BooleanVar()
		Checkbutton(self,
					text='Пицца.',
					variable=self.pizza,
					command=self.schet_txt,
					).grid(row=5, column=0, sticky=W)
		# Пипирони
		self.pizza_pipirony = BooleanVar()
		Checkbutton(self,
					text='Пипирони \t --550 руб.',
					variable=self.pizza_pipirony,
					command=self.schet_txt,
					).grid(row=6, column=0, padx=20, sticky=W)
		# Анчеусы
		self.pizza_anchous = BooleanVar()
		Checkbutton(self,
					text='С анчеусоми \t --480 руб.',
					variable=self.pizza_anchous,
					command=self.schet_txt,
					).grid(row=7, column=0, padx=20, sticky=W)
		# С сыром
		self.pizza_cheese = BooleanVar()
		Checkbutton(self,
					text='С сыром \t --640 руб.',
					variable=self.pizza_cheese,
					command=self.schet_txt,
					).grid(row=8, column=0, padx=20, sticky=W)
	def results_txt(self):
		self.results_txt = Text(self, width=40, height=5, wrap=WORD)
		self.results_txt.grid()
	def schet_txt(self):
		summs = 0
		if self.sup_klichky.get():
			summs += 240
		if self.sup_smetana.get():
			summs += 30
		if self.sup_zelen.get():
			summs += 15
		if self.sup_maionez.get():
			summs += 20
		if self.pizza.get():
			summs += 0
		if self.pizza_pipirony.get():
			summs += 550
		if self.pizza_anchous.get():
			summs += 480
		if self.pizza_cheese.get():
			summs += 640
		self.results_txt.delete(0.0, END)
		self.results_txt.insert(0.0, str(summs) + ' руб.')
root = Tk()
root.title('Меню ресторана')
#root.geometry('500x300')
app = Application(root)
root.mainloop()
Задался вопросом как сделать тоже самое, только метод schet_txt изменить так, чтобы в нем не было if(ов), ведь в меню может быть очень много блюд и каждое перебирать if(ом) не удобно, можно как нибудь это сделать циклом, у меня ни как не получается вот код который я пытался написать:
 from tkinter import *
menu = [{
		'Суп с клёцками' : ['sup_klichky', '240'],
		'Сметана' : ['sup_smetana', '30'],
		'Зелень' : ['sup_zelen', '15'],
		'Майонез' : ['sup_maionez', '20'],
		},
		{
		'Пицца' : ['pizza', '0'],
		'Пипирони' : ['pizza_pipirony', '550'],
		'С анчоусоми' : ['pizza_anchous', '480'],
		'С сыром' : ['pizza_cheese', '640'],
		}
		]
class Application(Frame):
	"""GUI для ресторана."""
	def __init__(self, master):
		super(Application, self).__init__(master)
		self.grid()
		self.widgets()
		self.results_txt()
		
	def results_txt(self):
		self.results_txt = Text(self, width=40, height=5, wrap=WORD)
		self.results_txt.grid()
	def schet_txt(self, names, texts, cenas, checks):
		self.names = names
		self.texts = texts
		self.cenas = cenas
		self.checks = checks
		for i in range(len(self.checks)):
			check = self.checks[i]
			name = self.names[i]
			cena = self.cenas[i]
			text = self.texts[i]
			summs = 0
			if self.check.get():
				summs += cena
				self.results_txt.delete(0.0, END)
				self.results_txt.insert(0.0, str(summs) + ' руб.')
	def widgets(self):
		row=0
		texts = []
		cenas = []
		names = []
		checks = []
		Label(self, text='Выбирите блюда которые хотите заказать:', bg='blue').grid(row=row, column=0, sticky=W)
		for category in menu:
			for name, info in category.items():
				tex = info[0]
				cen = info[1]
				check = tex
				self.check = BooleanVar()
				names.append(name)
				texts.append(tex)
				cenas.append(cen)
				checks.append(self.check)
				row+=1
				Checkbutton(self, text=name+'\t--'+cen, variable=tex, command=self.schet_txt(names, texts, cenas, checks)).grid(row=row, column=0, sticky=W)
				
root = Tk()
root.title('Меню ресторана')
#root.geometry('500x300')
app = Application(root)
root.mainloop()
строка if self.check.get(): в методе schet_txt выдает постоянно False.
Знающие люди объясните начинающему.
PEHDOM
grand
строка if self.check.get(): в методе schet_txt выдает постоянно False.
Это естественно потому что у вас :
Checkbutton(self, text=name+'\t–'+cen, variable=tex, command=self.schet_txt(names, texts, cenas, checks)).grid(row=row, column=0, sticky=W)
вы передаете в чекбаттон не комманду а результат ее выполнения,
И чет мне кажеться вы не с той стороны начали, тут вообще можно обойтись без цикла и перебора , создайте свой класс ЧекБаттон наследуемый от ткинтеровского чекбаттона, добавте туда чтобы оно само хранило свое состояние, а не ссылалось на левую переменную. Добавте туда же цену, и добавте туды же каллбек функцию которая будет суммировать в переменную общую сумму, и соответвенно в command дергайте каллбек функцию в которую вы будете передавать сумму с знаком + или минус в зависимости от того поставили вы галку или сняли. Или можно в калбек функцию передавать самого себя, а уже она будет проверять если галка стоит до добавлять цену, если нет - отнимать…
Соответвенно вам не нужно будет перебирать все элементы, а только добавлять-отнимать цену элемента по которому кликнули

Если не получиться завтра могу на коленке написать небольшой пример.
grand
PEHDOM
Если не получиться завтра могу на коленке написать небольшой пример.
Спасибо за разъяснение, я недавно начал учиться программировать, так, очень многое еще не понимаю, попробую завтра написать сам, если не получится обращусь к Вам за помощью, если Вы не против.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB