Python 有没有办法使Tkinter文本小部件成为只读的?

Python 有没有办法使Tkinter文本小部件成为只读的?,python,text,tkinter,Python,Text,Tkinter,它看起来没有那个属性,但对我来说真的很有用 输入Text.insert()或Text.bind()后,您必须将Text小部件从NORMAL更改为DISABLED: 详细描述了此问题,并列出了三种可能的解决方案: 其他答案中描述的禁用/启用技巧 替换插入/删除事件的绑定 与(2)相同,但将其包装在单独的小部件中 (2) 或者(3)更可取,但是,解决方案并不明显。然而: 插入之前和之后,请更改状态,否则不会更新 text.configure(state='normal') text.insert('

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

输入
Text.insert()
Text.bind()
后,您必须将
Text
小部件从
NORMAL
更改为
DISABLED

详细描述了此问题,并列出了三种可能的解决方案:

  • 其他答案中描述的禁用/启用技巧
  • 替换插入/删除事件的绑定
  • 与(2)相同,但将其包装在单独的小部件中
  • (2) 或者(3)更可取,但是,解决方案并不明显。然而:

    插入之前和之后,请更改状态,否则不会更新

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

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

    导入Tkinter
    root=Tkinter.Tk()
    readonly=Tkinter.Text(根)
    readonly.bind(“,lambda e:“break”)
    
    我没有50%的声誉,因此无法对答案添加评论。尽管如此,这就是答案所在

    如果您的用例非常简单,text.bind(“”,lambda event:text.focus_set())代码可以解决在OS X上看到但其他人在Windows和Linux上看不到的交互性问题


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

    如果要禁用用户编辑并允许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))
    
    def txtEvent(事件):
    如果(event.state==12,event.keysym==c'):
    返回
    其他:
    返回“中断”
    txt.bind(“,lambda e:txtEvent(e))
    
    如果不需要选择文本,禁用状态是最简单的方法。为了支持复制,您可以使用外部实体(一个
    按钮
    )来执行该工作。每当用户按下按钮时,
    文本的内容将被复制到剪贴板
    Tk
    具有处理剪贴板的内置支持(请参阅),因此模拟
    Ctrl-C
    的行为很容易。如果您正在构建一个用于写入日志消息的控制台,您可以进一步添加一个
    条目
    ,用户可以在其中指定要复制的日志消息的数量。

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

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

    你可以用标签代替。标签可以通过编程方式编辑,用户无法编辑。

    许多人提到,当状态被禁用时,无法从文本小部件复制标签。对我来说,在Ubuntu Python 3.8.5上,复制问题原来是由于小部件没有关注Ubuntu(在Windows上工作)而引起的

    我一直在使用解决方案,将状态设置为禁用,然后切换状态,当我需要使用1)text.config(state=tkinter.NORMAL)2)编辑文本和3)text.config(state=tkinter.disabled)以编程方式编辑它时。 在windows上,我可以正常地从小部件复制文本,但在Ubuntu上,它看起来像是我选择了文本,但我无法复制它

    经过一些测试,结果证明,只要文本小部件有焦点,我就可以复制它。在Windows上,无论处于何种状态,单击文本小部件似乎都会获得焦点,但在Ubuntu上,单击文本小部件不会获得焦点

    因此,我通过将text.focus_set()绑定到鼠标单击事件“”,解决了这个问题:

    导入tkinter
    root=tkinter.Tk()
    Text 0=tkinter.Text(根,状态=tkinter.DISABLED)
    text0.config(state=tkinter.NORMAL)
    text0.insert(1.0,“您不能复制或编辑此文本”。)
    text0.config(state=tkinter.DISABLED)
    text0.pack()
    Text 1=tkinter.Text(根,状态=tkinter.DISABLED)
    text1.config(state=tkinter.NORMAL)
    text1.insert(1.0,“您可以复制,但不能编辑此文本”。)
    text1.config(state=tkinter.DISABLED)
    text1.bind(“,lambda事件:text1.focus\u set())
    text1.pack()
    

    至少对我来说,这是一个简单但有效的解决方案,希望其他人觉得它有用。

    禁用文本小部件并不理想,因为您需要重新启用它才能更新它。一种更简单的方法是捕捉鼠标按钮和任何按键。因此:

        textWidget.bind("<Button-1>", lambda e: "break")
        textWidget.bind("<Key>", lambda e: "break")
    
    textWidget.bind(“,lambda e:“break”)
    textWidget.bind(“,lambda e:“break”)
    

    看起来很有意思。这就是我在文本编辑器中禁用“行号”文本小部件的方式。第一行是更有力的一行。我不确定是否需要第二个,但它让我在那里感觉更好。:)

    然后您就不能选择文本并复制它。选择和复制(在Windows中通过CTRL-C并在Linux中自动)对我来说似乎很好。@CraigMcQueen您实际上可以通过绑定
    来完成这一操作,该函数设置文本小部件的焦点:
    text.bind(“,lambda事件:text.focus\u set())
    @nbro但是在Python3.6中,您需要使用
    state=“readonly”
    not
    state=DISABLED
    @szmoore
    state=“readonly”
    不被文本小部件接受。它被Ttk小部件使用;您正在考虑Ttk条目小部件吗?Tkinter
    Entry
    小部件允许
    Entry.config(state='readonly')
    。不幸的是,这似乎对f不起作用
    text.configure(state='normal')
    text.insert('end', 'Some Text')
    text.configure(state='disabled')
    
    import Tkinter
    
    root = Tkinter.Tk() 
    
    readonly = Tkinter.Text(root)
    readonly.bind("<Key>", lambda e: "break")
    
    def txtEvent(event):
        if(event.state==12 and event.keysym=='c' ):
            return
        else:
            return "break"
    
    txt.bind("<Key>", lambda e: txtEvent(e))
    
    from tkinter import *
    text=Text(root)
    text.pack()
    text.config(state="normal")
    text.insert(END, "Text goes here")
    text.config(state="disabled")
    
    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()
    
    
        textWidget.bind("<Button-1>", lambda e: "break")
        textWidget.bind("<Key>", lambda e: "break")