2

I already looked through the solution to a similar problem here

How can you mark a portion of a text widget as readonly?

but i have tried to make it a little dynamic. Scenario is that a line marked 'readonly' can be changed later in the program based on few condition. This is my code below and it is calling the READONLY Class written by Bryan Oakley.

class Example(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        global text
        text = ReadonlyText(self)
        sb = Scrollbar(self, orient="vertical", command=text.yview)
        text.configure(state=DISABLED)
        text.configure(yscrollcommand=sb.set)
        sb.pack(side="left", fill="y")
        text.pack(side="right", fill="both", expand=True)
    count = 1.0
    with open('chem_data2.txt') as f:

        for line in f:
            if count == 5.0:
                text.insert(str(count), line,'readonly')
            else:
                text.insert(str(count), line, 'readonly')
            count = count + 1.0

    f.close()
    text.bind('<Key>', self.keyrelease)

    pos = text.index('end')
    text.tag_configure("readonly", foreground="grey")



def keyrelease(self,event):
    text.configure(state=NORMAL)
    index = text.index(INSERT)
    pos = int(float(index))
    let = str(float(pos))
    word = text.get(str(float(pos)), str(pos) + '.end')
    print pos
    #pos = text.index('end')
    if float(pos) == 5.0:
        print 'i got here'
        #text.insert(str(5.0), 'line', 'read')

The above code takes a file as an input and marks each line of the file 'readonly' at the initial stage but if the user cursor is at the 5th line the line should change to edittable.

Community
  • 1
  • 1

1 Answers1

0

You just need to remove the "readonly" tag from the range of text. You will need to save a reference to the text widget:

class Example(Frame):
    def __init__(self, parent):
        ...
        self.text = ReadonlyText(...)

    def keyrelease(self,event):
        if some_condition:
            # make line 5 not readonly
            self.text.tag_remove("readonly", "5.0", "5.0 lineend")

Note: this code is wrong:

pos = int(float(index))

Text indices are not floating point numbers, they are two integers separated by a period. If you treat them as floating point numbers and try to compare them, you will get unexpected results. For example, as floating point numbers 5.2 is greater than 5.10, but the text index 5.10 is after 5.2.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thanks for the reply and the additional comment, kind of new to tkinter. I tried the tag_remove and i can delete the text in the line but cannot insert new text. So i went further by trying tag_delete, then voila, i can delete and insert. but the only drawback here is that all lines are also activated. – user3600037 Nov 18 '16 at 21:33
  • To insert you have to make sure that the index you are inserting at doesn't have that tag. The algorithm is pretty simple: if you try to insert or delete text, and the index you give it is inside a range that has the readonly tag, it won't allow it. – Bryan Oakley Nov 18 '16 at 21:54