Question
I am trying to make a text editor in Tkinter. If a large single-line file is opened, it lags massively and stops responding. Is there a way to set a wrap length for a text widget? I have scroll bars and I don't want to have the characters wrap at the end of the text box. I want it to wrap after a certain number of characters.
Is this possible? If so, how can I do it?
I am using Python 3.9.6 on 64-bit Windows 10.
What I have tried
I have tried using wraplength= in the function, but that doesn't work. I have also searched for this question and found nothing.
Code
from tkinter import *
root = Tk()
root.title('Notpad [new file]')
root.geometry('1225x720')
txt = Text(root,width=150,height=40,wrap=NONE)
txt.place(x=0,y=0)
#Buttons here
scr = Scrollbar(root)
scr.pack(side='right',fill='y',expand=False)
txt.config(yscrollcommand=scr.set)
scr.config(command=txt.yview)
scr1 = Scrollbar(root,orient='horizontal')
scr1.pack(side='bottom',fill='x',expand=False)
txt.config(xscrollcommand=scr1.set)
scr1.config(command=txt.xview)
root.mainloop()
There is no wraplength
option in tkinter Text
widget. However you can simulate the effect using rmargin
option of tag_configure()
.
Below is an example with a custom text widget using rmargin
option:
import tkinter as tk
from tkinter import font
class MyText(tk.Text):
def __init__(self, master=None, **kw):
self.wraplength = kw.pop('wraplength', 80)
# create an instance variable of type font.Font
# it is required because Font.measure() is used later
self.font = font.Font(master, font=kw.pop('font', ('Consolas',12)))
super().__init__(master, font=self.font, **kw)
self.update_rmargin() # keep monitor and update "rmargin"
def update_rmargin(self):
# determine width of a character of current font
char_w = self.font.measure('W')
# calculate the "rmargin" in pixel
rmargin = self.winfo_width() - char_w * self.wraplength
# set up a tag with the "rmargin" option set to above value
self.tag_config('rmargin', rmargin=rmargin, rmargincolor='#eeeeee')
# apply the tag to all the content
self.tag_add('rmargin', '1.0', 'end')
# keep updating the "rmargin"
self.after(10, self.update_rmargin)
root = tk.Tk()
textbox = MyText(root, width=100, font=('Consolas',12), wrap='word', wraplength=90)
textbox.pack(fill='both', expand=1)
# load current file
with open(__file__) as f:
textbox.insert('end', f.read())
root.mainloop()
Note that I have used after()
so that even there are changes on the content, the rmargin
option is applied to updated content.
Note also that it may not be an efficient way, but it shows a possible way.