Как сделать аргумент master необязательным в функции инициации виджета tkinter python?
Вопрос вроде бы простой, но я не знаю, как его решить.
Есть код:
import tkinter as tk
class MainWindow(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
class MyButton(tk.Button):
global root
def __init__(self, master=root):
tk.Button.__init__(self, master)
self.pack()
root = MainWindow()
frame1 = tk.Frame(root)
frame1.pack()
button1 = MyButton()
button2 = MyButton(master=frame1)
root.mainloop()
Хочу, чтобы работали оба варианта при вызове функции __init__ в классе MyButton:
- Если аргумент master не указан, то используется значение этого аргумента по умолчанию master=root
button1 = MyButton()
- Если указано значение аргумента master, то оно используется вместо значения по умолчанию
button2 = MyButton(master=frame1)
Происходит ошибка
NameError: name 'root' is not defined
в строке def __init__(self, master=root):
Ответы (1 шт):
Укажите None как параметр по-умолчанию. При передаче None в качестве родительского элемента tkinter считает родительским главное окно (первый созданный объект Tk, если он существует, или создает новый). Детали реализации можно посмотреть в tkinter/__init__.py (вкратце, первый созданный объект Tk записывается в глобальную переменную _default_root, потом это значение используется как родитель по умолчанию). Для передачи параметров в родительский класс можно использовать функцию super(), в этом случае не нужно будет передавать self:
import tkinter as tk
class MainWindow(tk.Tk):
def __init__(self):
super().__init__()
class MyButton(tk.Button):
def __init__(self, master=None):
super().__init__(master)
self.pack()
root = MainWindow()
frame1 = tk.Frame(root)
frame1.pack()
button1 = MyButton()
button2 = MyButton(master=frame1)
root.mainloop()