2015-04-21 3 views
1

Итак, у меня есть основная схема, которая создается с помощью следующего кода (написанного здесь для краткости):Добавление Tkinter ScrolledText к сетке

class ClientUI(tk.Frame): 
    def __init(self, master, client, queue, send_command): 
     self.master = master 
     self.master.grid() 
     tk.Grid.rowconfigure(self.master, 0, weight=1) 
     tk.Grid.columnconfigure(self.master, 0, weight=1) 
     self.create_widgets() 

     # This is just to figure out what's going on 
     pprint(vars(master)) 
     self.output_panel = master.children['output'] 

    def create_widgets(self): 
     output = ScrolledText(self.master, name="output", state=tk.DISABLED) 
     output.grid(row=0, column=0, sticky=tk.N+tk.S+tk.E+tk.W) 

который я надеялся бы добавить ScrolledText к сетке. Это работало, когда я использовал только виджет Text.

Однако, я получаю KeyError, потому что output нет в списке детей. Вот выход pprint заявления (опять же, вырезать, чтобы показать соответствующую часть):

'children': {'34864544': <client.clientui.ClientUI object at 0x000000000213FDA0>, 
      '46887376': <tkinter.Frame object at 0x0000000002CB71D0>, 
      '46890008': <tkinter.Menu object at 0x0000000002CB7C18>, 
      'input': <tkinter.Entry object at 0x0000000002CB76A0>} 

Как вы можете видеть, есть названный input ребенок, который был добавлен в коде не показано. Тем не менее, виджет output, по-видимому, не добавляется. Почему output.grid(row=0, column=0, sticky=tk.N+tk.S+tk.E+tk.W) не добавляете его так, как ожидали?

+1

Если 'self' является' Frame', вы не должны добавлять виджеты к 'self' вместо' master'? –

+0

Я согласен с tobias_k, почему бы вам просто не делать 'output = ScrolledText (self, ...'? –

+0

@tobias_k Несмотря на то, что это, вероятно, хорошая идея. Остается вопрос: добавление виджета 'Text' в' self.master 'работал. Есть ли что-то другое в' ScrolledText'? Может быть, потому, что оно находится в 'самом кадре'? – ToothlessRebel

ответ

0

Похоже, что создание ScrolledText фактически создает Frame оберточной фактическое ScrolledText виджет вместе с ScrollBar и name, назначаемая ScrolledText не назначается Frame, но обернутой ScrolledText.

Таким образом, master.children действительно не содержит ребенка с именем 'output', но Frame. Виджет 'output' можно найти среди детей этого Frame.

>>> pprint(master.children) 
{'140447721418704': <tkinter.Frame object at 0x7fbc888b6fd0>} 
>>> pprint([c.children for c in master.children.values()]) 
[{'140447721417696': <tkinter.Scrollbar object at 0x7fbc888b6be0>, 
    'output': <tkinter.scrolledtext.ScrolledText object at 0x7fbc888b6f98>}] 

Так что, если вы хотите, чтобы получить ссылку на ScrolledText виджета вы должны получить, если из Frame, но вместо этого он может быть гораздо проще просто привязать его к self при ее создании, т.е.

self.output = ScrolledText(self.master, name="output") 

Это действительно тот же объект, который вы получили бы от Frame «ы детей:

self.output_panel = next(c.children["output"] for c in master.children.values() if "output" in c.children) 
print(repr(self.output_panel)) 
print(self.output_panel is self.output) 

Выход:

<tkinter.scrolledtext.ScrolledText object at 0x7f3e02bf6f98> 
True 
+0

Установка свойства' self.output' в методе 'createWidgets' заставляет PyCharm скулить. Я не уверен в рассуждениях , так как сам передается в любом случае.Чтобы получить это, присваивая его 'self.output', изначально было исключено. Найдите, что' ScrolledText' завернут в 'Frame', как упоминается мой комментарий, имеет смысл. – ToothlessRebel

+0

@ToothlessRebel Вероятно, PyCharm жалуясь на добавление дополнительных 'self.something' атрибутов за пределами' __init__', но я думаю, что поиск детей по их имени намного хуже. Я предлагаю вам либо встроить содержимое 'create_widgets' в' __init__', либо заставьте его вернуть созданные виджеты. –

Смежные вопросы