Наследование от Frame и mainloop в приложении Tkinter - PullRequest
0 голосов
/ 04 ноября 2019

В официальной документации Python (Python 3.7) есть следующий пример, и я пытаюсь понять, как работает код. Из исходного кода я добавил несколько комментариев.

import tkinter as tk


class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)  # Initialize the tk.Frame class
        self.master = master  # Is it necessary?
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        self.hi_there = tk.Button(self)
        self.hi_there["text"] = "Hello World\n(click me)"
        self.hi_there["command"] = self.say_hi
        self.hi_there.pack(side="top")

        self.quit = tk.Button(self, text="QUIT", fg="red", command=self.master.destroy)
        self.quit.pack(side="bottom")

    def say_hi(self):
        print("hi there, everyone!")


def main():
    # Instance of the root window
    root = tk.Tk()
    # Instance of the main frame
    app = Application(master=root)
    # Infinite loop used to run the application
    app.mainloop()  # mainloop() on tk.Tk() instance (root) or tk.Frame() instance (app)?


if __name__ == '__main__':
    main()

У меня есть два вопроса об этом коде:

  • После инициализации tk.Frame класса с super().__init__(master) в Приложение класс, который наследует tk.Frame , self.master уже содержит ссылку на корневое окно. Я подтвердил это, напечатав id(self.master) до и после. Итак, self.master = master необходим? Почему он был добавлен?
  • Метод mainloop () добавлен в app экземпляр класса Application , который наследует tk. Рамка . Но я мог бы добавить метод mainloop () к root экземпляру класса tk.Tk . Приложение работает в обоих случаях. В чем разница?

1 Ответ

0 голосов
/ 04 ноября 2019

self.master = master не является обязательным для наследования от классов tkinter. Это избыточно в этом случае. Также вам не нужен мастер в супер. Просто сделайте super().__init__(), здесь будет работать.

Вы не должны использовать диспетчер геометрии внутри фрейма, чтобы поместить себя в родительский контейнер. Вместо этого назовите это снаружи класса. Скажем, вам нужно изменить его с pack() на grid(), вам нужно изменить его в классе, а не просто обновить его размещение в основном коде.

Ваш основной цикл должен ссылаться на корневой экземпляр.

Я бы передал все начальные параметры при создании кнопки. Это просто добавление дополнительных строк кода для обновления каждого параметра в отдельности.

И последнее. Если вы собираетесь редактировать переменную / виджет позже в своем коде, используйте префикс self., чтобы сделать его атрибутом класса, но если нет, то нет смысла использовать self., поэтому мы можем удалить их из кнопок.

Переработанный код:

import tkinter as tk


class Application(tk.Frame):
    def __init__(self):
        super().__init__()
        tk.Button(self, text="Hello World\n(click me)", command=self.say_hi).pack(side="top")
        tk.Button(self, text="QUIT", fg="red", command=self.master.destroy).pack(side="bottom")

    def say_hi(self):
        print("hi there, everyone!")


def main():
    root = tk.Tk()
    Application().pack()
    # app = MaxiTeam(root) # not sure what this is unless you meant Application?
    root.mainloop()


if __name__ == '__main__':
    main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...