只读 tkinter 文本小部件
我想使用 tkinter text widget
作为 readonly
小部件.它应该作为 transcript
区域.我的想法是将这个成绩单保存在 file
中,每当用户写任何东西时,只需删除小部件的所有内容,然后重新编写.
I want to use tkinter text widget
as a readonly
widget. It should act as a transcript
area. My idea is to keep this transcript in a file
and whenever the user writes anything, just remove all the contents of the widget, and rewrite it again.
代码如下:
transcript_entry = SimpleEditor() # SimpleEditor is inherited from ScrolledText
transcript_entry.text.delete("1.0", END)
# this is just a test string, it should be the contents of the transcript file
transcript_entry.text.insert("1.0", "This is test transcript")
transcript_entry.text.bind("<KeyPress>", transcript_entry.readonly)
和 readonly
函数看起来像:
def readonly(self, event):
self.text.delete("1.0", END)
# this is just a test string, it should be the contents of the transcript file
self.text.insert("1.0", "This is test transcript")
这里的错误是用户输入的最后一个字符被添加到脚本中.我怀疑原因是 readonly 函数被调用,then
用户输入被写入小部件.如何颠倒这个顺序&让 readonly 函数在 用户输入写入小部件后调用?
The bug here is that the last character entered by the user is added to the transcript. I suspect the reason is that the readonly function is called, then
the user input is wrote to the widget. How to reverse this order & let the readonly function be called after
the user input is wrote to the widget?
有什么提示吗?
插入最后一个字符的原因是默认绑定(导致插入)发生在自定义绑定之后小部件.所以你的绑定首先触发,然后然后默认绑定插入字符.这里还有其他问题和答案可以更深入地讨论这个问题.例如,请参阅 https://stackoverflow.com/a/11542200/
The reason that the last character is inserted is because the default bindings (which causes the insert) happens after custom bindings you put on the widget. So your bindings fire first and then the default binding inserts the characters. There are other questions and answers here that discuss this in more depth. For example, see https://stackoverflow.com/a/11542200/
但是,有一种更好的方法可以完成您正在尝试做的事情.如果要创建只读文本小部件,可以将 state
属性设置为 "disabled"
.这将阻止所有的插入和删除(这意味着你需要在你想以编程方式输入数据时恢复状态).
However, there is a better way to accomplish what you are trying to do. If you want to create a readonly text widget, you can set the state
attribute to "disabled"
. This will prevent all inserts and deletes (and means you need to revert the state whenever you want to programmatically enter data).
在某些平台上,您似乎无法突出显示和复制文本,但这只是因为默认情况下小部件不会将焦点放在鼠标单击上.通过添加绑定来设置焦点,用户可以突出显示和复制文本,但他们将无法剪切或插入.
On some platforms it will seem like you can't highlight and copy text, but that is only because the widget won't by default get focus on a mouse click. By adding a binding to set the focus, the user can highlight and copy text but they won't be able to cut or insert.
这是一个使用 python 2.x 的例子;对于 3.x,您只需更改导入:
Here's an example using python 2.x; for 3.x you just have to change the imports:
import Tkinter as tk
from ScrolledText import ScrolledText
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
t = ScrolledText(self, wrap="word")
t.insert("end", "Hello\nworld")
t.configure(state="disabled")
t.pack(side="top", fill="both", expand=True)
# make sure the widget gets focus when clicked
# on, to enable highlighting and copying to the
# clipboard.
t.bind("<1>", lambda event: t.focus_set())
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()