AttributeError: у объекта «Приложение» нет атрибута «tk» - PullRequest
0 голосов
/ 08 мая 2018

У меня есть следующий скрипт, который использует Tkinter:

import tkinter as tk

class Application(tk.Frame):    

    def __init__(self, master):
        frame = tk.Frame(master)
        frame.pack

        self.PRINT = tk.Button(frame, text = 'Print', fg = 'Red', command = self.Print())
        self.PRINT.pack(side = 'left')    

        self.QUIT = tk.Button(frame, text = 'Quit', fg = 'Red', command = self.quit())
        self.QUIT.pack(side = 'left')    

    def Print(self):
        print('at least somethings working')

root = tk.Tk()

b = Application(root)    
root.mainloop()

Когда я запускаю его, я получаю следующую ошибку:

AttributeError: у объекта «Application» нетатрибут 'tk'

Почему я получаю эту ошибку?

1 Ответ

0 голосов
/ 08 мая 2018

Я запустил ваш скрипт здесь и получил следующую трассировку стека:

Traceback (most recent call last):
  File "t.py", line 23, in <module>
    b = Application(root)    
  File "t.py", line 15, in __init__
    self.QUIT = tk.Button(frame, text = 'Quit', fg = 'Red', command = self.quit())
  File "/usr/lib/python3.6/tkinter/__init__.py", line 1283, in quit
    self.tk.quit()
AttributeError: 'Application' object has no attribute 'tk'

Сообщение об ошибке появляется в конце, но важен весь стек! Давайте проанализируем это.

Очевидно, существует объект, экземпляр класса Application, который не имеет атрибута tk. Имеет смысл: мы создали этот класс и не добавили этот атрибут.

Ну, главный цикл ожидает, что атрибут существует! Что происходит, наш класс расширяет tkinter.Frame, и фрейм нуждается в этом атрибуте tk. К счастью, нам не нужно думать, как его создать: поскольку все кадры нуждаются в этом, инициализатор кадра (его метод __init__()) знает, как установить этот атрибут.

Что нам нужно сделать, так это просто вызвать инициализатор tkinter.Frame в нашем собственном инициализаторе. Это можно легко сделать, вызвав __init__() непосредственно из tk.Frame, передав переменную self:

tk.Frame.__init__(self, master)

Весь сценарий будет таким, тогда:

import tkinter as tk

class Application(tk.Frame):    

    def __init__(self, master):
        tk.Frame.__init__(self, master)

        frame = tk.Frame(master)
        frame.pack

        self.PRINT = tk.Button(frame, text = 'Print', fg = 'Red', command = self.Print())
        self.PRINT.pack(side = 'left')    

        self.QUIT = tk.Button(frame, text = 'Quit', fg = 'Red', command = self.quit())
        self.QUIT.pack(side = 'left')    

    def Print(self):
        print('at least somethings working')

root = tk.Tk()

b = Application(root)    
root.mainloop()

Теперь в вашем скрипте будут некоторые другие ошибки, которые вы скоро найдете;) Есть также некоторые сложности, связанные с множественным наследованием, которые можно решить с помощью функции super() . Тем не менее, это решение для вашей первой ошибки.

...