Перекрытие разных фреймов в Tkinter

Я пытаюсь сделать калькулятор, и у него разные кадры, например, базовый, статистический, ... и т. д. Однако у меня возникают проблемы с отображением каждого кадра.

Это контейнер для всех фреймов (в качестве примера я взял код из предыдущего поста)

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, но она тоже не сработала. Я немного застрял, буду очень признателен за вашу помощь, заранее спасибо.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
415
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Простым решением было бы добавить команду к вашей функции 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()

Вы устанавливаете варианты BasicMode и CalculusMode, а затем сразу устанавливаете значение по умолчанию как недопустимое значение Basic_Mode. Кроме того, ваше утверждение о необходимости переименовать классы трудно понять. Ваш ответ был бы лучше, если бы вы объяснили почему; "из-за того, как работает аргумент команды" очень расплывчато. Я считать, потому что варианты выбора и имена классов должны быть идентичными, но я не уверен.

Bryan Oakley 04.10.2018 14:02

@BryanOakley: Да, аргументация заключалась в том, что варианты выбора и имена классов были идентичны. Проблема заключалась в том, что варианты выбора содержали пробел и не соответствовали именам классов. Я дополню свой ответ некоторыми подробностями. Basic_Mode был ошибкой, которую я пропустил при редактировании кода.

Mike - SMT 04.10.2018 14:16

Извините, что ответил так поздно. Большое тебе спасибо. Я сделал то, что вы мне сказали, и это сработало отлично!

Amendo 05.10.2018 17:02

@duvanmendoza Рад помочь.

Mike - SMT 05.10.2018 17:13

Другие вопросы по теме