【问题标题】:Adding tkinter ScrolledText to a grid将 tkinter ScrolledText 添加到网格
【发布时间】:2015-04-21 04:59:09
【问题描述】:

所以,我有一个使用以下代码创建的基本布局(为简洁起见,写在这里):

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)没有按预期添加?

【问题讨论】:

  • 如果selfFrame,你不应该将小部件添加到self 而不是master吗?
  • 我同意 tobias_k 你为什么不直接做output = ScrolledText(self, ...
  • @tobias_k 尽管这可能是个好主意。问题仍然是向self.master 添加Text 小部件确实有效。 ScrolledText 有什么不同吗?也许是因为它本身就在 Frame 中?

标签: python tkinter python-3.3


【解决方案1】:

似乎创建ScrolledText 实际上创建了一个Frame 将实际的ScrolledText 小部件与ScrollBar 包装在一起,而您分配给namename 没有分配给@987654328 @,但要包裹的ScrolledText

因此,master.children 确实不包含名为 'output' 的孩子,而是包含 Frame。然后可以在该Frame 的子级中找到'output' 小部件。

>>> 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 获取 if,但是在创建它时将其绑定到 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

【讨论】:

  • createWidgets 方法中设置属性 self.output 会导致 PyCharm 发牢骚。我不确定原因,因为 self 无论如何都会被传递。为此,最初避免将其分配给self.output。发现 ScrolledText 被包裹在 Frame 中,就像我提到的评论非常有意义。
  • @ToothlessRebel PyCharm 可能抱怨在self.something 之外添加更多self.something 属性,但我想通过他们的名字查找孩子要糟糕得多。我建议要么将create_widgets 的内容“内联”到__init__ 中,要么让它返回已创建的小部件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多