Я пытаюсь сделать калькулятор, и у него разные кадры, например, базовый, статистический, ... и т. д. Однако у меня возникают проблемы с отображением каждого кадра.
Это контейнер для всех фреймов (в качестве примера я взял код из предыдущего поста)
import tkinter as tk
class calculatorframe(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
#----------------CONTAINER FOR ALL THE FRAMES----------
container = tk.Frame(self)
container.pack()
#--------------------- DROPDOWN MENU------------------
tkvar = tk.StringVar()
choices = {'Basic Mode','Calculus Mode'} #Options of the dropdown menu
tkvar.set('Basic Mode') #default frame
dropdownmenu =tk.OptionMenu(container, tkvar, *choices)
dropdownmenu.grid(row=2,column=3) #position of the dropdown menu
self.frames = {}
for F in (Basic, Calculus):
page_name = F.__name__
frame = F(parent= container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky= "nsew")
self.show_frame('Basic')
#-------FUNCTION TO SHOW THE CURRENT FRAME
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
Это классы, которые я создал для базового калькулятора.
class Basic(tk.Frame):
def __init__(self, parent, controller):
#--------------- SCREEN ---------------
tk.Frame.__init__(self, parent)
screen = tk.Entry(self, width=80)
screen.grid(row=3, column=1,columnspan=7) #position of the screen
#------------ BUTTON ---------------------
button7=tk.Button(self, text = "7", width=8) #button
button7.grid(row=4,column=1)
#---------------------frame for calculus -------------------------
class Calculus(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
#-----------------------------SCREEN------------
screen=tk.Entry(self, width=50)
screen.pack()
screen.grid(row=3, column=1, pady=20, columnspan=7) #position of the screen
#------------------------BUTTON---------------
go=tk.Button(self, height=1, text = "Go") #button
go.grid(row=1, column=8)
if __name__ == "__main__":
app = calculatorframe()
app.mainloop()
Я знаю, что мне нужно отслеживать значение tkvar и что мне нужно делать это с помощью trace () и передавать это значение в show_frame, однако я не знаю, где его разместить в моем коде. Я попытался поместить его под раскрывающимся меню, но получил сообщение об ошибке, попытался выполнить после функции show_frame, но она тоже не сработала. Я немного застрял, буду очень признателен за вашу помощь, заранее спасибо.






Простым решением было бы добавить команду к вашей функции OptionsMenu(). Нам также нужно будет изменить имена ваших классов и варианты выбора из-за того, как здесь работает аргумент команды.
Для аргумента команды OptionsMenu(), когда вы указываете ему вызвать метод, он автоматически передает значение выбранного элемента в раскрывающемся списке. Поэтому из-за этого нам нужно убедиться, что наш выбор отражает имена классов. Вы можете изменить варианты выбора / классы на все, что захотите. Я просто использовал BasicMode и CalculusMode в качестве примера.
Команда автоматически передаст выбранное значение, чтобы мы могли использовать его для вызова каждого кадра с помощью вашего метода show_frame.
Взгляните на приведенный ниже код и дайте мне знать, если у вас возникнут вопросы.
import tkinter as tk
class calculatorframe(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack()
tkvar = tk.StringVar()
choices = {'BasicMode', 'CalculusMode'}
tkvar.set('BasicMode')
dropdownmenu = tk.OptionMenu(container, tkvar, *choices, command=self.show_frame)
dropdownmenu.grid(row=2, column=3)
self.frames = {}
for F in (BasicMode, CalculusMode):
page_name = F.__name__
frame = F(parent= container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky = "nsew")
self.show_frame('BasicMode')
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class BasicMode(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
screen = tk.Entry(self, width=80)
screen.grid(row=3, column=1, columnspan=7)
button7 = tk.Button(self, text = "7", width=8)
button7.grid(row=4,column=1)
class CalculusMode(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
screen = tk.Entry(self, width=50)
screen.pack()
screen.grid(row=3, column=1, pady=20, columnspan=7)
go = tk.Button(self, height=1, text = "Go")
go.grid(row=1, column=8)
if __name__ == "__main__":
app = calculatorframe()
app.mainloop()
@BryanOakley: Да, аргументация заключалась в том, что варианты выбора и имена классов были идентичны. Проблема заключалась в том, что варианты выбора содержали пробел и не соответствовали именам классов. Я дополню свой ответ некоторыми подробностями. Basic_Mode был ошибкой, которую я пропустил при редактировании кода.
Извините, что ответил так поздно. Большое тебе спасибо. Я сделал то, что вы мне сказали, и это сработало отлично!
@duvanmendoza Рад помочь.
Вы устанавливаете варианты BasicMode и CalculusMode, а затем сразу устанавливаете значение по умолчанию как недопустимое значение Basic_Mode. Кроме того, ваше утверждение о необходимости переименовать классы трудно понять. Ваш ответ был бы лучше, если бы вы объяснили почему; "из-за того, как работает аргумент команды" очень расплывчато. Я считать, потому что варианты выбора и имена классов должны быть идентичными, но я не уверен.