I have a Text
widget, textbox
, where the user can type, and another Text
widget, linenumbers
, directly to the left of it which displays line numbers. I have it working, but with one problem: the more lines I create, the more the two Text
widgets get out of sync when scrolled.
Here's a gif showing what happens.
And here's my code (scroll_both
and update_scroll
came from another StackOverflow thread):
class MainGUI:
def scroll_both(self, action, position, type=None):
self.textbox.yview_moveto(position)
self.linenumbers.yview_moveto(position)
def update_scroll(self, first, last, type=None):
self.textbox.yview_moveto(first)
self.linenumbers.yview_moveto(first)
self.scrollbar_y.set(first, last)
def on_textbox_update(self, event):
modified = self.textbox.edit_modified()
if modified:
#If the number of lines in the textbox has changed:
if self.linecount != self.textbox.index("end").split('.')[0]:
#Update textbox's linecount
self.linecount = self.textbox.index("end").split('.')[0]
# Clear the line count sidebar
self.linenumbers.config(state="normal")
self.linenumbers.delete(0.0, "end")
# Fill it up again
for LineNum in range(1, int(self.linecount)):
self.linenumbers.insert(self.linenumbers.index("end"), str(LineNum)+"\n", "justifyright")
if len(str(LineNum)) == 1:
self.linenumbers.config(width=2)
else:
self.linenumbers.config(width=len(str(LineNum)))
self.linenumbers.config(state="disabled")
def __init__(self, master):
self.master = master
Grid.rowconfigure(master, 1, weight=1)
Grid.columnconfigure(master, 2, weight=1)
self.linenumbers = Text(master, width=2, borderwidth=0, takefocus=0, padx=6, fg="gray")
self.linenumbers.config(font="TkTextFont")
self.linenumbers.tag_configure("justifyright", justify="right")
self.linenumbers.grid(row=0, column=1, rowspan=2, sticky=NSEW)
self.textbox = Text(master, padx=6, borderwidth=0, wrap=NONE)
self.textbox.config(font="TkTextFont")
self.textbox.grid(row=0, column=2, rowspan=2, sticky=NSEW)
self.textbox.bind("<<Modified>>", self.on_textbox_update)
self.scrollbar_y = ttk.Scrollbar(master)
self.scrollbar_y.grid(row=0, column=3, rowspan=2, sticky=NSEW)
self.scrollbar_y.config(command=self.scroll_both)
self.textbox.config(yscrollcommand=self.update_scroll)
self.linenumbers.config(yscrollcommand=self.update_scroll)
root = Tk()
MainGUI = MainGUI(root)
root.mainloop()