自动调整文本小部件的高度以适合所有文本

时间:2017-09-06 18:11:43

标签: python text tkinter text-widget

如何自动调整文本小部件的大小以适应文本小部件的高度

  • 文本小部件不会有任何\n,而是文本将包围(整个单词)并继续向下。 wrap=WORD

如何做到这一点?

我接近问题陈述的想法:我想知道每次文本在文本小部件中被包裹时是否可以计数,并且通过该给定值以某种方式计算高度文字小部件? - 只是一个想法..我不知道它是否可能。

**为什么这不是重复**

这不是重复的,如果您这么认为,则链接到您声称它是重复的问题。他们都实施了一个解决方案来检查一个' \ n'在文本小部件中的每个击键中。我的文字小部件没有任何' \ n'在它里面。但改为包围这些词!

这不是我想要的解决方案,因为它正在寻找' \ n'并相应地改变它找到的高度。因为我不会使用任何' \ n'而是将文字换成(Text(frame, wrap=WORDS))no' \ n'不会出现使用该解决方案USELESS!"

这就是为什么这个代码,从人们声称这是一个副本的问题,WONT解决这个问题,这不是重复。

不会解决我的问题,因为它会查找' \ n':

    import Tkinter

class TkExample(Tkinter.Frame):
   def __init__(self, parent):
      Tkinter.Frame.__init__(self, parent)
      self.init_ui()

   def init_ui(self):
      self.pack()
      text_box = Tkinter.Text(self)
      text_box.pack()
      text_box.bind("<Key>", self.update_size)

   def update_size(self, event):
      widget_width = 0
      widget_height = float(event.widget.index(Tkinter.END))
      for line in event.widget.get("1.0", Tkinter.END).split("\n"):
         if len(line) > widget_width:
            widget_width = len(line)+1
      event.widget.config(width=widget_width, height=widget_height)

if __name__ == '__main__':
    root = Tkinter.Tk()
    TkExample(root)
    root.mainloop()

编辑示例

这就是我没有使用消息小部件的原因,他们没有重新排列文本以填写文本小部件。

enter image description here

1 个答案:

答案 0 :(得分:2)

tkinter文本小部件并非设计用于增大或缩小以适应其内容,如标签小部件。如果您只需要显示纯文本而无需以交互方式编辑更多文本,那么Label可能是比Text更好的选择。

话虽如此,可以在文本小部件中获取显示的行数,并且可以使用该信息调整小部件的大小。

这是一个示例,演示了在以编程方式插入文本时如何调整大小。它不会在您键入时处理调整大小,尽管可以这样做。

诀窍是要知道文本小部件内部有一个count方法,您可以调用该方法来获取显示的行数。不幸的是,这种方法没有暴露在tkinter层,因此需要了解tkinter如何在内部工作。

class ExpandoText(tk.Text):
    def insert(self, *args, **kwargs):
        result = tk.Text.insert(self, *args, **kwargs)
        self.reset_height()
        return result

    def reset_height(self):
        height = self.tk.call((self._w, "count", "-update", "-displaylines", "1.0", "end"))
        self.configure(height=height)

以下是如何使用它的示例:

root = tk.Tk()
text = ExpandoText(root, width=20, wrap="word")
text.pack(fill="both", expand=True)

root.update_idletasks()
text.insert("1.0", "This is a line of text that will initially be wrapped.")

root.after(5000, text.insert, "end", "This is more text")

root.mainloop()

运行代码时,您应该看到一个如下所示的窗口:

original screenshot

如果您没有手动调整窗口大小,等待5秒钟,窗口将会增长以显示添加的文字:

screenshot with more text

不幸的是,您必须在插入之前调用update_idletasks,以便tkinter知道窗口实际有多宽。这可能会产生视觉副作用,具体取决于其余代码的工作方式(读取:UI首次启动时可能会看到闪存)。