python3-tkinter中的只读文本小部件; 跨平台

Mom*_*mus 6 python text tkinter readonly python-3.x

如何抑制最终用户在文本小部件中编辑/添加/删除文本的能力?(Python v3.2 ..和tkinter)

关键是要仅抑制更改/添加/删除文本的能力,而不是强制转换其他功能.也许NoEdit Text widged可能是一个更好的名字.

我试过.text ['state'] ='禁用',它在Windows中几乎可以正常工作(它仍然允许用户选择/复制文本突出显示选择,页面向上/向下和向上/向下按钮工作.唯一的事情破碎似乎是光标变得不可见.)

但在MacIntosh上,一切都被打破了.没有亮点,没有选择/复制,... UGH

由于Tkinter几乎没有Python文档,我搜索并找到了一些TCL建议,派生一个新类并禁止插入删除函数.

所以,我试过这样:

class roText(tk.Text):
    def insert(self,*args,**kwargs):
        print(" Hey  - Im inside roText.insert")
        pass
    def delete(self,*args,**twargs):
        pass    
    def pInsert(self,*args,**twargs):
        super().insert(*args,**twargs)
Run Code Online (Sandbox Code Playgroud)

不幸的是它没有用.显然,当最终用户输入/删除代码时,tkinter不会使用这些插入和删除功能.也许那些TCL插入/删除是别的,我在TCL和斯瓦希里语的翻译中丢失了一些东西.tkinter.Text用于最终用户编辑文本的功能是什么?希望他们不是内部的......

那么,有没有办法修改Text小部件以仅抑制最终用户编辑? 有没有办法在没有潜入内部并覆盖内部Tkinter代码的情况下执行此操作,因此Tkinter的下一版本不会破坏这些东西?

查看Idle shell窗口,我看到他们已设法禁止编辑(最后一行除外).所以有一种方法.但它是什么以及成本如何?

Bry*_*ley 2

disabled状态似乎在 Mac 上不起作用的原因是它关闭了为小部件提供焦点的绑定。如果没有焦点,Mac 上的突出显示就不会显示。如果您将状态设置为disabled,然后分配绑定以<ButtonPress-1>将焦点显式设置到禁用的文本小部件,则您可以选择并复制文本,并且突出显示将显示。

至于光标消失......可以说,这就是应该发生的事情。光标告诉用户“这是文本将被插入的位置”。由于不会插入任何文本,因此视觉线索会让用户感到困惑。如果确实很重要,您可以做的就是在点击的地方插入一个小图像来模拟光标。

要回答有关小部件是否实际使用 和insert方法的问题delete:实际底层小部件上的方法是默认绑定使用的方法,因此在子类中覆盖它们没有任何效果。您需要重做所有默认绑定才能使其正常工作。这是可行的,但工作量很大。

不幸的是,这是 Tcl 编程真正大放异彩的领域,因为您可以简单地禁用小部件的insert和命令。delete当然,您也可以直接在 Tkinter 中执行此操作,因为最终它运行 tcl 代码来完成所有操作,但这将涉及编写一些 tcl 代码,从 Python 编码器的角度来看,这不是一个很好的解决方案。

我认为最好的解决方案是使用禁用状态,然后添加足够的绑定来执行您想要的操作。

下面是一个简单的示例,它通过显式地将焦点设置在鼠标按钮单击上来工作。使用此代码,我可以单击并滑动以选择区域,或者双击或三次单击以选择单词和行:

import Tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.text = tk.Text(width=40, height=20)
        self.text.bind("<1>", self.set_focus)
        self.text.insert("end", "\n".join(dir(tk.Tk)))
        self.text.configure(state="disabled")
        self.text.pack(fill="both", expand=True)

    def set_focus(self, event):
        '''Explicitly set focus, so user can select and copy text'''
        self.text.focus_set()

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()
Run Code Online (Sandbox Code Playgroud)