python3tkinter中的只读文本小部件;跨平台

2024-10-03 04:37:38 发布

您现在位置:Python中文网/ 问答频道 /正文

如何抑制最终用户在文本小部件中编辑/添加/删除文本的能力?(Python 3.2版。。和特金特)

关键在于只抑制更改/添加/删除文本的功能,而不是阉割其他功能。也许NoEdit文本widged会是一个更好的名称。在

我试过。text['state']='disabled',它在Windows下几乎可以工作(它仍然允许用户选择/复制文本突出显示所选内容,页面上/下和上/下按钮工作。唯一坏掉的似乎是光标变得不可见。)

但在MacIntosh上,所有东西都坏了。没有突出显示,没有选择/复制,。。。呃

由于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在终端用户输入/删除代码时不使用这些insert和delete函数。也许那些TCL insert/delete是其他东西,我在TCL和Swahili的翻译中丢失了一些东西。什么功能tkinter.文本用于最终用户编辑文本?希望它们不是内在的。。。在

那么,有没有一种方法可以修改文本小部件以仅禁止最终用户编辑? 有没有一种方法可以在不深入内部并重写内部Tkinter代码的情况下完成它,这样这些东西就不会被Tkinter的下一个版本破坏了?在

查看空闲shell窗口,我发现他们已经成功地抑制了编辑(除了最后一行)。所以有办法。但这是什么,又有多贵?在


Tags: 函数文本self功能编辑部件tkinterdef
3条回答

@BryanOakley我花了一段时间来测试你的建议,因为我没有Mac。 不幸的是,Python的Mac实现有缺陷。 我添加了focus,即创建窗口并插入文本后调用的禁用函数,现在先调用:

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

然后呢

^{pr2}$

我想这是你的建议。在

它“有点”奏效了。Ie:当选择文本(点击并拖动或双击)时,高亮显示在大多数情况下起作用。Python肯定有一些不好的内存引用或者类似的错误:有时候高亮显示一开始不起作用,然后在单击更多次之后它开始工作(在同一个窗口中)。有时当程序被调用时,它会立即工作。有时使用Shift-rightArrow键选择可以工作,但用鼠标选择则不行。然后又开始工作了。或者它可以在一个窗口中正常工作,但在另一个窗口(两个都是同一个类)中工作,然后开始在所有窗口中工作…等等。。。在

好在添加焦点并不会对窗口造成严重影响(即没有焦点时一切正常)。 我想在这一点上,我只希望Python for Mac的未来/下一个版本能够修复这些错误。。在

顺便说一句,Mac似乎是Python的一个孤儿。它的实现比Windows要糟糕得多。我的意思是字体看起来更糟,按钮等等。。也可能是由于不同的屏幕分辨率和Python端口无法很好地解释这些问题。不确定

不管怎样。感谢您对使用focus for Mac的帮助和建议。在

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

为了覆盖小部件的绑定,有一个bind函数,您可以在其中传递一个字符串,其中包含要重写的内容以及您希望它调用的新函数。在

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

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

^{pr2}$

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

我希望这能回答你的问题。干杯。在

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

至于光标消失。。。可以说,这就是应该发生的。光标告诉用户“这是插入文本的地方”。因为没有文本被插入,所以有视觉线索会让用户感到困惑。如果真的很重要的话,你可以做的是在他们点击的地方插入一个小图像来模拟光标。在

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

不幸的是,这是Tcl编程的一个亮点,因为您可以简单地禁用小部件的insert和{}命令。当然,您也可以直接在Tkinter中实现这一点,因为它最终运行tcl代码来完成所有事情,但是这需要编写一些tcl代码,从Python代码编写者的角度来看,这不是一个很好的解决方案。在

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

下面是一个简单的例子,它通过显式地将焦点设置在鼠标单击上。有了这段代码,我可以点击并滑动以选择区域,或者双击或三次单击来选择单词和行:

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()

相关问题 更多 >