Python 有没有办法让 Tkinter 文本小部件只读?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3842155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:58:00  来源:igfitidea点击:

Is there a way to make the Tkinter text widget read only?

pythontexttkinter

提问by rectangletangle

It doesn't look like it has that attribute, but it'd be really useful to me.

它看起来没有那个属性,但它对我来说真的很有用。

采纳答案by ars

You have to change the stateof the Textwidget from NORMALto DISABLEDafterentering text.insert()or text.bind():

你必须改变状态的的Text小部件从NORMALDISABLED之后进入text.insert()text.bind()

text.config(state=DISABLED)

回答by freakboy3742

The tcl wikidescribes this problem in detail, and lists three possible solutions:

维基TCL详细描述了这一问题,并列出了三种可能的解决方案:

  1. The Disable/Enable trick described in other answers
  2. Replace the bindings for the insert/delete events
  3. Same as (2), but wrap it up in a separate widget.
  1. 其他答案中描述的禁用/启用技巧
  2. 替换插入/删除事件的绑定
  3. 与 (2) 相同,但将其包装在一个单独的小部件中。

(2) or (3) would be preferable, however, the solution isn't obvious. However, a worked solution is available on the unpythonic wiki:

(2) 或 (3) 会更可取,但是,解决方案并不明显。但是,在 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")

回答by sarbjit

from Tkinter import *
root = Tk()
text = Text(root)
text.insert(END,"Some Text")
text.configure(state='disabled')

回答by renzowesterbeek

text = Text(app, state='disabled', width=44, height=5)

Before and after inserting, change the state, otherwise it won't update

插入前后,改变状态,否则不会更新

text.configure(state='normal')
text.insert('end', 'Some Text')
text.configure(state='disabled')

回答by FoxDot

Very easy solution is just to bind any key press to a function that returns "break" like so:

非常简单的解决方案是将任何按键绑定到一个返回“break”的函数,如下所示:

import Tkinter

root = Tkinter.Tk() 

readonly = Tkinter.Text(root)
readonly.bind("<Key>", lambda e: "break")

回答by cshilton

I don't have 50 reputation so I can't add a comment on nbro'sanswer. Nonetheless, that's where this answer belongs.

我没有 50 声望,所以我无法对nbro 的回答发表评论。尽管如此,这就是这个答案的所在。

If your use case is really simple, nbro'stext.bind('<1>', lambda event: text.focus_set())code solves the interactivity problem that Craig McQueensees on OS X but that others don't see on Windows and Linux.

如果您的用例真的很简单,nbro 的text.bind('<1>', lambda event: text.focus_set())代码解决了Craig McQueen在 OS X 上看到但其他人在 Windows 和Linux。

OTOH, If your readonly data has any contextual structure, at some point you'll probably end up using Tkinter.Text.insert(position, text, taglist) to add it to your readonly Text box window under a tag. You'll do this because you want parts of the data to stand out based on context. Text that's been marked up with tags can be emphasized by calling .Text.tag_config() to change the font or colors, etc. Similarly, text that's been marked up with tags can have interactive bindings attached using .Text.tag_bind(). There's a good example of using these functions here. If a mark_for_paste() function is nice, a mark_for_paste() function that understands the context of your data is probably nicer.

OTOH,如果您的只读数据具有任何上下文结构,在某些时候您可能最终会使用Tkinter.Text.insert( position, text, taglist) 将其添加到标签下的只读文本框窗口中。您这样做是因为您希望部分数据根据上下文脱颖而出。可以通过调用.Text.tag_config() 更改字体或颜色等来强调被标记的文本。同样,被标记的文本可以使用.Text.tag_bind()附加交互式绑定。这里有一个使用这些函数的好例子. 如果 mark_for_paste() 函数很好,那么理解数据上下文的 mark_for_paste() 函数可能更好。

回答by Pal

Use this code in windows if you want to disable user edit and allow Ctrl+Cfor copy on screen text:

如果要禁用用户编辑并允许在屏幕文本上复制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))

回答by rbaleksandar

If selecting text is not something you need disabling the state is the simplest way to go. In order to support copying you can use an external entity - a Button- to do the job. Whenever the user presses the button the contents of Textwill be copied to clipboard. Tkhas an in-build support of handling the clipboard (see here) so emulating the behaviour of Ctrl-Cis an easy task. If you are building let's say a console where log messages are written you can go further and add an Entrywhere the user can specify the number of log messages he wants to copy.

如果不需要选择文本,则禁用状态是最简单的方法。为了支持复制,您可以使用外部实体 - a Button- 来完成这项工作。每当用户按下按钮时,其内容Text将被复制到剪贴板。Tk具有处理剪贴板的内置支持(请参阅此处),因此模拟 的行为Ctrl-C是一项简单的任务。如果您正在构建一个写入日志消息的控制台,您可以进一步添加一个Entry用户可以指定他想要复制的日志消息数量的地方。

回答by Xx Stef xX

This is how I did it. Making the state disabled at the end disallows the user to edit the text box but making the state normal before the text box is edited is necessary for text to be inserted.

我就是这样做的。最后禁用状态是不允许用户编辑文本框,但在编辑文本框之前使状态正常是插入文本所必需的。

from tkinter import *
text=Text(root)
text.pack()
text.config(state="normal")
text.insert(END, "Text goes here")
text.config(state="disabled")

回答by Mikeologist

You could use a Label instead. A Label can be edited programmatically and cannot be edited by the user.

您可以改用标签。标签可以通过编程方式编辑,用户不能编辑。