使用自动换行创建可调整大小/多行Tkinter / ttk标签

时间:2010-10-25 01:30:47

标签: python windows tkinter ttk

是否可以创建一个带有自动换行的多行标签,该标签会与其父级的宽度同步调整大小?换句话说,当您更改NotePad窗口的宽度时,记事本的wordwrap行为。

用例是一个对话框,需要完整地呈现一行多行文本(指令),而不会剪切文本或使用滚动条。父容器将有足够的垂直空间来容纳窄宽度。

我一直在尝试使用Tkinter Label和Message小部件以及ttk Label小部件而没有成功。似乎我需要硬编码像素激励值,而当这些控件的文本到达其容器的右边缘时,让这些控件自动进行自动换行。当然,Tkinters几何管理器可以帮我自动调整标签大小并相应地更新它们的wraplength值吗?

我应该查看Text小部件吗?如果是这样,是否可以隐藏文本小部件的边框,以便我可以将其用作带有wordwrap的多行标签?

这是一个如何做我上面描述的原型的原型。它的灵感来自Bryan Oakley的使用Text小部件的提示以及Stackoverflow上的以下帖子: In python's tkinter, how can I make a Label such that you can select the text with the mouse?

from Tkinter import *
master = Tk()

text = """
If tkinter is 8.5 or above you'll want the selection background to appear like it does when the widget is activated. Comment this out for older versions of Tkinter.

This is even more text.

The final line of our auto-wrapping label that supports clipboard copy.
""".strip()

frameLabel = Frame( master, padx=20, pady=20 )
frameLabel.pack()
w = Text( frameLabel, wrap='word', font='Arial 12 italic' )
w.insert( 1.0, text )
w.pack()

# - have selection background appear like it does when the widget is activated (Tkinter 8.5+)
# - have label background color match its parent background color via .cget('bg')
# - set relief='flat' to hide Text control borders
# - set state='disabled' to block changes to text (while still allowing selection/clipboard copy)
w.configure( bg=master.cget('bg'), relief='flat', state='disabled' )

mainloop()

4 个答案:

答案 0 :(得分:3)

使用Message widget

  

Message小部件是Label的变体,用于显示多行消息。消息小部件可以包装文本,并调整其宽度以保持给定的宽高比。

答案 1 :(得分:2)

以下是代码:

entry = Label(self, text=text,
    anchor=NW, justify=LEFT,
    relief=RIDGE, bd=2)
def y(event, entry=entry):
  # FIXME: make this a global method, to prevent function object creation
  # for every label.
  pad = 0
  pad += int(str(entry['bd']))
  pad += int(str(entry['padx']))
  pad *= 2
  entry.configure(wraplength = event.width - pad)
entry.bind("<Configure>", y )

答案 2 :(得分:1)

不,Tk没有内置自动自动换行标签的功能。但是,它可以通过绑定到标签的<Configure>事件并调整包装长度来实现。每次调整标签窗口小部件时,都会触发此绑定。

正如您所建议的那样,另一个选项是使用文本小部件。如果您愿意,可以完全关闭边界。当我想要包装文字的教学文本时,这一直是我的选择。

答案 3 :(得分:0)

一些人建议的tkinter.Message小部件不使用TTK样式,这意味着它在TTK(主题)界面中看起来像垃圾。

您可以将TTK主题的背景色和前景色手动应用于ttk.Style()(通过实例化TLabel并从该样式对象请求活动主题的Message色背景和前景色) ),但不值得...因为古老的ttk.Label小部件比TTK的常规tkinter.Message具有零优势。

ttk.Label小部件具有“长宽比”属性,该属性定义了要换行的像素数。

wraplength=具有一个anchor=属性,该属性确定单词换行之前有多少像素。您还应该使用其justify=ttk.Label(root, text="foo", wraplength=220, anchor=tkinter.NW, justify=tkinter.LEFT)属性来根据您的实际需求对其进行自定义。使用这些属性,您可以使Label的行为与旧的Message小部件一样。

示例<Configure>。创建样式精美的标签,该标签可在220像素宽后永久包装其文本。

关于自动更新包装长度?好吧,您应该像人们所说的那样附加到df['new']=(df.set_index('Event').Number-df.query('Ref').set_index('Event').Number).to_numpy() df Event Number Ref new 0 A 1 False -4 1 A 2 False -3 2 A 3 False -2 3 A 4 False -1 4 A 5 True 0 5 B 6 False -3 6 B 7 False -2 7 B 8 False -1 8 B 9 True 0 9 B 10 False 1 事件上……但是,如果您有一个完全流畅的窗口(它会自动调整大小以适合所有内容),或者是一个流畅的并且包含以下内容的网格/框架:标签,那么您将无法以这种方式自动进行计算,因为只要标签宽度过大,父级WINDOW / CONTAINER本身就会展开。这意味着标签将始终将其大小调整为适合所有文本所需的最大宽度。因此,仅当标签本身对其增长的宽度有一些限制时(通过其父容器为固定大小/最大大小,或者其自身为固定大小/最大大小),才可以自动更新包装长度。在那种情况下,可以肯定的是,您可以使用configure来计算新的换行编号,以确保文本始终换行。但是,t7ko的示例代码已损坏并且不再有效,仅是fyi。