tkinter Text() 小部件上的 4096 个单行字符限制?

Posted

技术标签:

【中文标题】tkinter Text() 小部件上的 4096 个单行字符限制?【英文标题】:4096 single line character limit on tkinter Text() widget? 【发布时间】:2015-05-08 12:03:55 【问题描述】:

我在 Tkinter 中遇到了一个关于 Text 小部件的有趣问题,我似乎无法理解。谷歌也没有提供任何答案。当禁用文本换行时,似乎 Tkinter 对 Text() 小部件的单行字符限制为 4096 个字符。有没有办法改变这个限制或在 4095 个字符后强制换行?我在其他小部件上看到了 wraplength 参数,但在 Text 小部件上没有看到任何参数。

示例代码:

import Tkinter as tk

if __name__ == "__main__":
    root = tk.Tk()
    text = tk.Text(root)
    sb = tk.Scrollbar(root, orient="horizontal", command=text.xview)
    text.configure(xscrollcommand=sb.set)
    text.configure(wrap=tk.NONE)
    text.pack(fill="both", expand=True)
    sb.pack(side="bottom", fill="x")

    text.insert("end","a"*4095)
    text.insert("end","\n")
    text.insert("end","b"*4096)
    text.insert("end","\n")
    text.insert("end","c"*4095)

    root.mainloop()

真正奇怪的是,如果您单击或突出显示“b”应该打印的位置,它们会突然出现?为什么他们一开始就消失了?

Python 版本:2.7.5

操作系统:Windows 7

更新:

这似乎是 Windows 7 的平台问题。仍然不确定它发生的原因或是否可以轻松解决。

截图:

这是应用程序首次启动时的样子。 'b' 不见了:

一旦我把焦点放在'b'上,它们就会突然出现:

一旦我从 'b's 移开焦点,它们就会消失。

【问题讨论】:

你在什么平台上运行这个?当我在 OSX 上运行代码时,我看到了额外的“b”。 这似乎是一个 Windows 平台问题:您的代码在我的 Fedora Linux 系统上运行(而另一个人说它在 Mac 上运行)。您可能希望这样标记它? 无法在 Vista (Python 2.7.5) 和 Windows 7 Enterprise (Python 2.7.6) 上重现 - 在两台机器上我都看到了额外的“b”。 4096 没问题,但是当我将 5000 bs 放入该行时,最后几百个 bs 覆盖了第一个(即它们既不被截断也不被包装,而是覆盖前几个bs 在同一行,使它们看起来模糊而粗体)。在 Ubuntu 14.04 上测试 @Matt 我看到了和你一样的东西,Windows 7 x64 上的 Python 2.7.8,但是当我向右滚动至少两个字符时,b 会正常显示 【参考方案1】:

我在另一个网站上找到了部分解决方案: here

它通过子类化文本小部件来观察行长并在达到限制时插入一个额外的换行符

import Tkinter as tk

class WrapText(tk.Text):
    def __init__(self, master, wraplength=100, **kw):
        tk.Text.__init__(self, master, **kw)
        self.bind("<Any-Key>", self.check)
        self.wraplength = wraplength-1 

    def check(self, event=None):
        line, column = self.index(tk.INSERT).split('.')
        if event and event.keysym in ["BackSpace","Return"]: pass
        elif int(column) > self.wraplength: 
            self.insert("%s.%s" % (line,column),"\n")

    def wrap_insert(self, index, text):
        for char in text:
            self.check()
            self.insert(index, char)

if __name__ == "__main__":
    root = tk.Tk()
    text = WrapText(root, wraplength=4000)
    sb = tk.Scrollbar(root, orient="horizontal", command=text.xview)
    text.configure(xscrollcommand=sb.set)
    text.configure(wrap=tk.NONE)
    text.pack(fill="both", expand=True)
    sb.pack(side="bottom", fill="x")

##    text.tag_config("mystyle", background="yellow", foreground="red", wrap="char")

    text.wrap_insert("end","a"*4095)#,"mystyle")
    text.wrap_insert("end","\n")
    text.wrap_insert("end","b"*4095)
    text.wrap_insert("end","\n")
    text.wrap_insert("end","c"*4095)

    root.mainloop()

这种方法有几个明显的限制,首先它实际上是在正在输入的数据中添加字符(这可能是不可取的),其次它只是按字符换行,所以它可以在一个单词的中间换行,但是也有一些方法可以实现。

【讨论】:

以上是关于tkinter Text() 小部件上的 4096 个单行字符限制?的主要内容,如果未能解决你的问题,请参考以下文章

如何清除/删除 Tkinter Text 小部件的内容?

从 Tkinter Text 小部件中获取所有内容 [重复]

如何在 tkinter Text 小部件中突出显示文本

如何从Tkinter,Python中的Text小部件中移除焦点

如何将Tkinter Text小部件的撤消/重做历史记录复制到另一个小部件中

Tkinter 小部件上的垂直和水平滚动条