Readtly tkinter text widget

I want to use tkinter text widgetas a widget readonly. He must act as an area transcript. My idea is to save this transcript in fileand whenever the user writes something, just delete the entire contents of the widget and overwrite it again.

The code will look like this:

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)

And the function readonlywill look like this:

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

The error here is that the last character entered by the user is added to the transcript. I suspect that the reason is that the readonly function is called, thenuser input is written to the widget. How to cancel this order and let the readonly function be called afteruser input is written to the widget?

Any clues?

+4
3

, , , ( ) , . , . , . , . fooobar.com/questions/1019897/...

, . , state "disabled". ( , , ).

, , , . , , .

python 2.x; 3.x :

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

, :

  • .
  • ,
  • , .
  • , Tkinter , .

, , - , .

- Widget, " ". , RO :

from Tkinter import *

# This is the list of all default command in the "Text" tag that modify the text
commandsToRemove = (
"<Control-Key-h>",
"<Meta-Key-Delete>",
"<Meta-Key-BackSpace>",
"<Meta-Key-d>",
"<Meta-Key-b>",
"<<Redo>>",
"<<Undo>>",
"<Control-Key-t>",
"<Control-Key-o>",
"<Control-Key-k>",
"<Control-Key-d>",
"<Key>",
"<Key-Insert>",
"<<PasteSelection>>",
"<<Clear>>",
"<<Paste>>",
"<<Cut>>",
"<Key-BackSpace>",
"<Key-Delete>",
"<Key-Return>",
"<Control-Key-i>",
"<Key-Tab>",
"<Shift-Key-Tab>"
)


class ROText(Text):
    tagInit = False

    def init_tag(self):
        """
        Just go through all binding for the Text widget.
        If the command is allowed, recopy it in the ROText binding table.
        """
        for key in self.bind_class("Text"):
            if key not in commandsToRemove:
                command = self.bind_class("Text", key)
                self.bind_class("ROText", key, command)
        ROText.tagInit = True


    def __init__(self, *args, **kwords):
        Text.__init__(self, *args, **kwords)
        if not ROText.tagInit:
            self.init_tag()

        # Create a new binding table list, replace the default Text binding table by the ROText one
        bindTags = tuple(tag if tag!="Text" else "ROText" for tag in self.bindtags())
        self.bindtags(bindTags)

text = ROText()

text.insert("1.0", """A long text with several
lines
in it""")


text.pack()

text.mainloop()

, . Text ( , ,...) .

+1

I recently worked with a different, slightly simpler solution. Instead of changing all the bindings, you can add a function to delete all input characters as soon as they are written:

  def read_only(self, event):
    if event.char is not '':  # delete only if the key pressed
                              # corresponds to an actual character
      self.text.delete('insert-1c')

and just bind it to any event:

  root.bind('<Key>', self.read_only)
-1
source

Source: https://habr.com/ru/post/1527658/


All Articles