Различные поведения сетки из унаследованного текстового элемента Tkinter

В другом ответе здесь пользователь создал унаследованный класс TextWithVar, который предоставляет экземпляры элемента Tkinter.Text, но с текстовыми переменными, такими как Tkinter.Entry. Однако при тестировании этот новый класс ведет себя иначе, чем элемент Text, когда используется Grid-менеджер. Чтобы продемонстрировать, этот код копируется из этого ответа, с добавлением некоторых тестовых вызовов в конце:

import Tkinter as tk class TextWithVar(tk.Text): '''A text widget that accepts a 'textvariable' option''' def __init__(self, parent, *args, **kwargs): try: self._textvariable = kwargs.pop("textvariable") except KeyError: self._textvariable = None tk.Text.__init__(self, *args, **kwargs) # if the variable has data in it, use it to initialize # the widget if self._textvariable is not None: self.insert("1.0", self._textvariable.get()) # this defines an internal proxy which generates a # virtual event whenever text is inserted or deleted self.tk.eval(''' proc widget_proxy {widget widget_command args} { # call the real tk widget command with the real args set result [uplevel [linsert $args 0 $widget_command]] # if the contents changed, generate an event we can bind to if {([lindex $args 0] in {insert replace delete})} { event generate $widget <<Change>> -when tail } # return the result from the real widget command return $result } ''') # this replaces the underlying widget with the proxy self.tk.eval(''' rename {widget} _{widget} interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget} '''.format(widget=str(self))) # set up a binding to update the variable whenever # the widget changes self.bind("<<Change>>", self._on_widget_change) # set up a trace to update the text widget when the # variable changes if self._textvariable is not None: self._textvariable.trace("wu", self._on_var_change) def _on_var_change(self, *args): '''Change the text widget when the associated textvariable changes''' # only change the widget if something actually # changed, otherwise we'll get into an endless # loop text_current = self.get("1.0", "end-1c") var_current = self._textvariable.get() if text_current != var_current: self.delete("1.0", "end") self.insert("1.0", var_current) def _on_widget_change(self, event=None): '''Change the variable when the widget changes''' if self._textvariable is not None: self._textvariable.set(self.get("1.0", "end-1c")) root = tk.Tk() text_frame = TextWithVar(root) text_frame.grid(row=1, column=1) test_button = tk.Button(root, text='Test') test_button.grid(row=1, column=1, sticky='NE') root.mainloop() root2 = tk.Tk() frame = tk.Frame(root2) frame.grid(row=1, column=1) text_frame2 = TextWithVar(frame) text_frame2.grid(row=1, column=1) test_button2 = tk.Button(frame, text='Test') test_button2.grid(row=1, column=1, sticky='NE') root2.mainloop() 

В этом примере, когда элемент TextWithVar находится непосредственно внутри root, он действует так, как должен – элемент Button помещается поверх него в углу. Однако, когда оба находятся внутри рамки, элемент Button нигде не видно. Теперь измените оба вызова TextWithVar на tk.Text. Оба они работают так, как должны, с Button на простом изображении. По словам Брайана, который создал новый класс, они должны работать точно так же, как я с тобой согласен. Так почему же они работают по-другому?

One Solution collect form web for “Различные поведения сетки из унаследованного текстового элемента Tkinter”

Это ошибка в TextWithVar , в этой строке кода:

 tk.Text.__init__(self, *args, **kwargs) 

Код должен включать parent параметр:

 tk.Text.__init__(self, parent, *args, **kwargs) 
Python - лучший язык программирования в мире.