【发布时间】:2011-04-20 00:29:58
【问题描述】:
它看起来没有那个属性,但它对我来说真的很有用。
【问题讨论】:
-
一个 Tkinter
Entry小部件允许entry.config(state='readonly')。不幸的是,这似乎不适用于Text小部件。
它看起来没有那个属性,但它对我来说真的很有用。
【问题讨论】:
Entry 小部件允许 entry.config(state='readonly')。不幸的是,这似乎不适用于 Text 小部件。
您必须将Text 小部件的the state 从NORMAL 更改为DISABLED 在 输入text.insert() 或text.bind() 之后:
text.config(state=DISABLED)
【讨论】:
<1> 与将焦点设置在文本小部件上的函数绑定来做到这一点:text.bind("<1>", lambda event: text.focus_set())。
state="readonly" 而不是 state=DISABLED
state="readonly" 不被文本小部件接受。它被 Ttk 小部件使用;你在想 Ttk Entry 小部件吗?
text = Text(app, state='disabled', width=44, height=5)
插入前后改变状态,否则不会更新
text.configure(state='normal')
text.insert('end', 'Some Text')
text.configure(state='disabled')
【讨论】:
非常简单的解决方案是将任何按键绑定到返回“break”的函数,如下所示:
import Tkinter
root = Tkinter.Tk()
readonly = Tkinter.Text(root)
readonly.bind("<Key>", lambda e: "break")
【讨论】:
tcl wiki 详细描述了这个问题,并列出了三种可能的解决方案:
(2) 或 (3) 会更好,但是,解决方案并不明显。但是,a worked solution is available on the unpythonic wiki:
from Tkinter import Text
from idlelib.WidgetRedirector import WidgetRedirector
class ReadOnlyText(Text):
def __init__(self, *args, **kwargs):
Text.__init__(self, *args, **kwargs)
self.redirector = WidgetRedirector(self)
self.insert = self.redirector.register("insert", lambda *args, **kw: "break")
self.delete = self.redirector.register("delete", lambda *args, **kw: "break")
【讨论】:
idlelib,它来自哪里?最好有一个不需要idlelib 依赖的解决方案。
sudo apt-get install idle-python2.7 获得idlelib
idlelib 是 Python 标准库的一部分。然而,出于某种原因,Ubuntu 似乎喜欢将 Python 打包成许多小部分。
我没有 50 名声望,所以我无法在 nbro's 答案上添加评论。尽管如此,这就是这个答案的归属。
如果你的用例真的很简单,nbro'stext.bind('', lambda event: text.focus_set()) 代码解决了Craig McQueen 看到的交互问题在 OS X 上,但其他人在 Windows 和 Linux 上看不到。
OTOH,如果您的只读数据具有任何上下文结构,那么您可能最终会使用 Tkinter.Text.insert(position, text , taglist) 将其添加到标签下的只读文本框窗口中。您将这样做是因为您希望部分数据根据上下文脱颖而出。使用标签标记的文本可以通过调用 .Text.tag_config() 来更改字体或颜色等来强调。同样,使用标签标记的文本可以使用 .Text.tag_bind()。有一个使用these functions here 的好例子。如果 mark_for_paste() 函数很好,那么理解数据上下文的 mark_for_paste() 函数可能会更好。
【讨论】:
from Tkinter import *
root = Tk()
text = Text(root)
text.insert(END,"Some Text")
text.configure(state='disabled')
【讨论】:
我就是这样做的。最后将状态设为禁用会禁止用户编辑文本框,但在编辑文本框之前使状态正常是插入文本所必需的。
from tkinter import *
text=Text(root)
text.pack()
text.config(state="normal")
text.insert(END, "Text goes here")
text.config(state="disabled")
【讨论】:
如果您想禁用用户编辑并允许 Ctrl+C 在屏幕上复制文本,请在 Windows 中使用此代码:
def txtEvent(event):
if(event.state==12 and event.keysym=='c' ):
return
else:
return "break"
txt.bind("<Key>", lambda e: txtEvent(e))
【讨论】:
如果不需要选择文本,则禁用状态是最简单的方法。为了支持复制,您可以使用外部实体 - Button - 来完成这项工作。每当用户按下按钮时,Text 的内容将被复制到剪贴板。 Tk 具有处理剪贴板的内置支持(请参阅here),因此模拟Ctrl-C 的行为是一项简单的任务。如果您正在构建一个写入日志消息的控制台,您可以进一步添加Entry,用户可以在其中指定他想要复制的日志消息的数量。
【讨论】:
许多人提到当状态被禁用时,您无法从文本小部件中复制。对于 Ubuntu Python 3.8.5 上的我来说,复制问题原来是由于小部件没有关注 Ubuntu(适用于 Windows)引起的。
我一直在使用将状态设置为禁用然后切换状态的解决方案,当我需要使用 1) text.config(state=tkinter.NORMAL) 2) 编辑文本和 3) 文本以编程方式编辑它时.config(状态=tkinter.DISABLED)。 在 Windows 上,我能够正常地从小部件中复制文本,但在 Ubuntu 上,看起来我已经选择了文本,但我无法复制它。
经过一些测试,结果证明,只要文本小部件有焦点,我就可以复制它。在 Windows 上,无论状态如何,当您单击文本小部件时,它似乎都会获得焦点,但在 Ubuntu 上,单击文本小部件不会获得焦点。
所以我通过将 text.focus_set() 绑定到鼠标单击事件“
import tkinter
root = tkinter.Tk()
text0 = tkinter.Text(root, state=tkinter.DISABLED)
text0.config(state=tkinter.NORMAL)
text0.insert(1.0, 'You can not copy or edit this text.')
text0.config(state=tkinter.DISABLED)
text0.pack()
text1 = tkinter.Text(root, state=tkinter.DISABLED)
text1.config(state=tkinter.NORMAL)
text1.insert(1.0, 'You can copy, but not edit this text.')
text1.config(state=tkinter.DISABLED)
text1.bind("<Button>", lambda event: text1.focus_set())
text1.pack()
至少对我来说,这是一个简单但有效的解决方案,希望其他人觉得它有用。
【讨论】:
禁用 Text 小部件并不理想,因为您需要重新启用它才能对其进行更新。一种更简单的方法是捕捉鼠标按钮和任何击键。所以:
textWidget.bind("<Button-1>", lambda e: "break")
textWidget.bind("<Key>", lambda e: "break")
似乎可以解决问题。这就是我在文本编辑器中禁用“行号”文本小部件的方式。第一行是更强大的行。我不确定是否需要第二个,但它让我感觉更好。 :)
【讨论】:
您可以改用标签。标签可以通过编程方式进行编辑,并且用户不能进行编辑。
【讨论】: