首页 文章

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

提问于
浏览
6

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

关键是 suppress only the ability to change/add/delete text 但不要阉割其他功能 . 也许NoEdit Text widged可能是一个更好的名字 .

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

But on MacIntosh everything is broken. No highlights, no select/copy,... UGH

由于Tkinter几乎没有Python文档,我搜索并找到了一些TCL建议,派生一个新类并抑制 insertdelete 函数 .

所以,我试过这样:

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)

不幸的是它没有用 . 显然 tkinter does not use those insert and delete functions when end user enters/deletes code. 也许那些TCL插入/删除是其他的东西,我在TCL和斯瓦希里语的翻译中丢失了一些东西 . tkinter.Text用于最终用户编辑文本的功能是什么?希望他们不是内部的......

So, is there a way to modify the Text widget to suppress only end user editing? 有没有办法在没有潜入内部并覆盖内部Tkinter代码的情况下执行此操作,因此下一版本的Tkinter不会破坏这些东西?

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

3 回答

  • 2

    很抱歉碰到一个老问题,但我也在寻找这个问题的答案,最后找到了解决方案 . 我发现的解决方案涉及在文本小部件具有焦点时重写键绑定并且非常简单 . 找到here .

    要覆盖窗口小部件的绑定,有一个绑定函数,您可以在其中传递要覆盖的字符串以及要调用的新函数 .

    self.txtBox.bind("<Key>", self.empty)
    

    在类的其他地方,您需要定义处理事件的函数 .

    def empty(self, event):
            return "break"
    

    通过返回字符串“break”,事件处理程序知道在您的函数之后停止,而不是继续默认操作 .

    我希望这回答了你的问题 . 干杯 .

  • 3

    disabled 状态没有出现的原因 . 如果将状态设置为 disabled 但是然后将绑定分配给 <ButtonPress-1> 以将焦点显式设置为禁用的文本小部件,则可以选择并复制文本并突出显示 .

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

    要回答有关窗口小部件是否实际使用 insertdelete 方法的问题:实际基础窗口小部件上的方法是默认绑定使用的方法,因此在子类中覆盖它们无效 . 您需要重做所有默认绑定才能工作 . 这是可行的,但很多工作 .

    不幸的是,这是Tcl编程真正发光的一个领域,因为您可以简单地禁用小部件的 insertdelete 命令 . 当然,你也可以直接在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()
    
  • -1

    @BryanOakley我花了一段时间测试你的建议,因为我没有Mac . 不幸的是,Mac的Python实现是错误的 . 我添加了焦点,即我在创建窗口并插入文本后调用的禁用功能,现在先调用:

    self.txt['state'] = 'disabled'
    

    然后

    self.txt.focus_set()
    

    这是我认为你建议的 .

    它"kind of"工作 . 即:在选择文本时(单击并拖动或双击),突出显示在大多数时间都有效 . Python必须有一些不良内存引用或此类错误:有时突出显示最初不起作用,然后在更多单击后开始工作(在同一窗口中) . 有时,当调用程序时,它对蝙蝠起作用 . 有时使用Shift-rightArrow键进行选择会有效,但用鼠标选择则不行 . 然后再开始工作 . 或者它可以在一个窗口中正常工作但不能在另一个窗口中工作(两个都是同一个类),然后开始在所有窗口中工作......等等......

    好处是增加焦点并不会影响Windows(即所有工作都没有焦点 . 我想在这一点上我只希望Python for Mac的未来/下一版本能解决这些问题..

    顺便说一句,似乎Mac对于Python来说是一个孤儿 . 对于Windows来说,实现起来更加丑陋 . 我的意思是字体看起来更糟糕,按钮等等 . 或者它可能是由于不同的屏幕分辨率和Python端口不能很好地解释这些 . 不确定

    无论如何 . 感谢您的帮助和建议,将焦点用于Mac .

相关问题