Текстовый виджет недоступен для вспомогательной функции в Python3x tkinter

Я изучаю tkiner python из справочника. Примеры закодированы в обычном стиле, т. е. не в формате класса. Я хочу изучать программирование на занятиях, потому что считаю, что это помогает справляться с длинными кодами.

Я пытаюсь сделать текстовый виджет (с именем textPad) доступным для вспомогательной функции внутри класса с именем TextEditor. Работа вспомогательной функции состоит в том, чтобы выделить весь текст, который я печатаю. Однако, как только я запускаю скрипт, я получаю глобальную ошибку, что the textPad is not defined. Даже когда я добавляю self. к textPad, то есть self.textPad, я получаю ошибку атрибута, что Class object has no attribute textPad. Код является частью упражнения по созданию полнофункционального текстового редактора. Ниже я привожу основной код, который генерирует ошибку. Что не так с этим кодом?

Не могли бы вы развеять мои сомнения: где лучше всего определять вспомогательные функции: внутри класса или вне класса? В обоих случаях, как сделать их доступными?

from tkinter import *

class TextEditor():
    def __init__(self, root):

        self.select_all() #helper function declare

        myMenu = Menu(root, tearoff=0) #Menu bar
        editMenu = Menu(root, tearoff)
        editMenu.add_command(label="Select All", accelerator="Ctrl+A", command=select_all)
        myMenu.add_cascade(label="Edit", menu=editMenu)
        root.config(menu=myMenu)

        textPad = Text(root, wrap="word", undo=True)
        textPad.pack(expand="yes", fill="both")
    def select_all(self):
        textPad.tag_add('sel', '1.0', 'end')

if __name__ == '__main__':
    root=Tk()
    app = TextEditor(root)
    root.mainloop()

Это ошибка:

Traceback (most recent call last):
File "C:\Python33\gui\tkguibook\textpad.py", line 21, in <module>
app = TextEditor(root)
File "C:\Python33\gui\tkguibook\textpad.py", line 6, in __init__
self.select_all() #helper function declare
File "C:\Python33\gui\tkguibook\textpad.py", line 17, in select_all
textPad.tag_add('sel', '1.0', 'end')
NameError: global name 'textPad' is not defined

Заранее благодарим вас за вашу любезную помощь!


person Mohammed    schedule 12.01.2015    source источник


Ответы (1)


В первую очередь советую посмотреть туториалы по объектно-ориентированной парадигме в Python без прямого использования tkinter.

Проблема с вашим кодом заключается в том, что textPad не является свойством класса, а представляет собой простую локальную переменную для метода или конструктора __init__. Чтобы сделать его свойством, вы должны использовать self для объявления, а затем ссылаться на только что объявленное свойство.

Например, предположим, что у меня есть следующий класс:

class TextEditor:
    def __init__(self):
        # stuff

и вы хотите добавить свойство, видимое во всех точках вашего класса, вы можете сделать это следующим образом:

class TextEditor:
    def __init__(self):
        self.textPad = tkinter.Text()  # using 'self' to declare a property

теперь, если вы хотите сослаться на это свойство в другом методе, вы всегда должны использовать self:

class TextEditor:
    def __init__(self):
        self.textPad = tkinter.Text()

    def set_text(self, new_text):
        self.textPad.insert(tkinter.END, "hello")  # using 'self' to refer to the property

Чтобы узнать больше о self.

person nbro    schedule 12.01.2015
comment
Большое спасибо за ваш ответ. Я согласен с вами, что я должен сначала посмотреть учебники по ООП. К сожалению, я попытался модифицировать код, как вы предложили, но это не сработало. Еще раз спасибо. - person Mohammed; 13.01.2015
comment
@Mohammed Мохаммед, я мог бы попытаться исправить ваш код, но это потребовало бы от меня некоторого времени, которого у меня не так много. Следуйте моему совету, попробуйте сначала посмотреть, как работает ООП для Python, учитесь шаг за шагом, это продуктивнее, смотрите другие примеры, и скоро вы справитесь с ООП :) - person nbro; 13.01.2015
comment
Хорошо, я сделаю это. Я согласен с вами, что нет ничего более продуктивного, чем самообучение. - person Mohammed; 13.01.2015
comment
Это часть проблемы, другая часть заключается в том, что вы вызываете self.select_all() до того, как определите self.textPad = Text(...). Итак, когда строка self.textPad.tag_add('sel', '1.0', 'end') запущена, self.textPad еще не существует. - person fhdrsdg; 13.01.2015