Assuming MCVE is as follows:
import tkinter as tk def create_text(text_len): _text = list() for _ in range(text_len): _text.append("{}\n".format(_)) _text = "".join(_text) return _text if __name__ == '__main__': root = tk.Tk() txt = tk.Text(root) txt.text = create_text(10000) txt.insert('end', txt.text) txt.pack() root.mainloop()
Analysis
Based on this I don't think this is a rendering problem. I think this is a problem with the <KeyPress> fixed signup speed. This means that the number of events recorded per second is fixed, although the hardware can be recorded faster. A similar regulation should be true for the mouse scroll event.
Rendering solutions
It is possible to cut the text for part of the txt['height'] buffer. But isn't that the way TK should be rendering?
Solutions for rendering an unrelated problem
If the step is defined as moving the cursor to the previous or next line, for each registered event, Up or Down ; then scrolling_speed = step * event_register_frequency .
Increasing step size
An easy workaround would be to simply increase the step size, as with increasing the number of lines to jump, for each key binding registration.
But this is already the default behavior, assuming the page length is> 1 line, Page Up or Page Down has the page step size. This increases the scroll speed, even if the speed of event logging remains unchanged.
Alternatively, a new large-step event handler can be defined to invoke several cursor movements for each Up and Down registration, for example:
import tkinter as tk def create_text(text_len): _text = list() for _ in range(text_len): _text.append("{}\n".format(_)) _text = "".join(_text) return _text def step(event): if txt._step_size != 1: _no_of_lines_to_jump = txt._step_size if event.keysym == 'Up': _no_of_lines_to_jump *= -1 _position = root.tk.call('tk::TextUpDownLine', txt, _no_of_lines_to_jump) root.tk.call('tk::TextSetCursor', txt, _position) return "break" if __name__ == '__main__': root = tk.Tk() txt = tk.Text(root) txt.text = create_text(10000) txt.insert('end', txt.text) txt._step_size = 12 txt.bind("<Up>", step) txt.bind("<Down>", step) txt.pack() root.mainloop()
By comparing the speed of registration of keypress events :
As mentioned in, the actual change in registration speed in keypress is beyond the scope of Tk. Instead, it can be emulated:
import tkinter as tk def create_text(text_len): _text = list() for _ in range(text_len): _text.append("{}\n".format(_)) _text = "".join(_text) return _text def step_up(*event): _position = root.tk.call('tk::TextUpDownLine', txt, -1) root.tk.call('tk::TextSetCursor', txt, _position) if txt._repeat_on: root.after(txt._repeat_freq, step_up) return "break" def step_down(*event): _position = root.tk.call('tk::TextUpDownLine', txt, 1) root.tk.call('tk::TextSetCursor', txt, _position) if txt._repeat_on: root.after(txt._repeat_freq, step_down) return "break" def stop(*event): if txt._repeat_on: txt._repeat_on = False root.after(txt._repeat_freq + 1, stop) else: txt._repeat_on = True if __name__ == '__main__': root = tk.Tk() txt = tk.Text(root) txt.text = create_text(10000) txt.insert('end', txt.text) txt._repeat_freq = 100 txt._repeat_on = True txt.bind("<KeyPress-Up>", step_up) txt.bind("<KeyRelease-Up>", stop) txt.bind("<KeyPress-Down>", step_down) txt.bind("<KeyRelease-Down>", stop) txt.pack() root.mainloop()
Increasing step size and increasing registry registration speed
import tkinter as tk def create_text(text_len): _text = list() for _ in range(text_len): _text.append("{}\n".format(_)) _text = "".join(_text) return _text def step_up(*event): _no_of_lines_to_jump = -txt._step_size _position = root.tk.call('tk::TextUpDownLine', txt, _no_of_lines_to_jump) root.tk.call('tk::TextSetCursor', txt, _position) if txt._repeat_on: root.after(txt._repeat_freq, step_up) return "break" def step_down(*event): _no_of_lines_to_jump = txt._step_size _position = root.tk.call('tk::TextUpDownLine', txt, _no_of_lines_to_jump) root.tk.call('tk::TextSetCursor', txt, _position) if txt._repeat_on: root.after(txt._repeat_freq, step_down) return "break" def stop(*event): if txt._repeat_on: txt._repeat_on = False root.after(txt._repeat_freq + 1, stop) else: txt._repeat_on = True if __name__ == '__main__': root = tk.Tk() txt = tk.Text(root) txt.text = create_text(10000) txt.insert('end', txt.text) txt._step_size = 1 txt._repeat_freq = 100 txt._repeat_on = True txt.bind("<KeyPress-Up>", step_up) txt.bind("<KeyRelease-Up>", stop) txt.bind("<KeyPress-Down>", step_down) txt.bind("<KeyRelease-Down>", stop) txt.pack() root.mainloop()