5

I am making a basic text editor and I am saving the scroll position in a file on closing the program. Then when opening the program it will read the scroll position from the file and update it so you can continue where you left off.

I can get the position fine from scrolledtext.yview() which returns a tuple with e.g. (0.42, 0.75)

But I cannot figure out how to change the scroll position. I have tried scrolledtext.vbar.set(0.42, 0.75) to try and update it but that doesn't work as in it doesn't do anything and gives no errors. I have also tried scrolledtext.yview(0.42, 0.75) but it says TclError: bad option "0.42": must be moveto or scroll so if anyone knows how to update it that would be greatly appreciated, cheers.

Edit(Code):

import tkinter as tk

root = tk.Tk()
Frame = frame(root)
Frame.pack()
textbox = ScrolledText(Frame)
textbox.pack()
textbox.yview()  #this is saved to file, produces tuple of e.g. (0.42, 0.75)
textbox.vbar.set(0.3, 0.7)  #this doesn't produce any errors but doesn't change the scroll position 
textbox.yview(0.3, 0.7)  #this is also something i have tried but produces the error _tkinter.TclError: bad option "0.4243827160493827": must be moveto or scroll

root.mainloop()
JohnT
  • 151
  • 1
  • 16
  • If you could please provide a code example of what you have tried we can better assist. Please provide [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Mike - SMT Nov 05 '18 at 16:26

2 Answers2

7

You can't expect the saved yview to work in all cases. If the file has been edited, the proportions could be all wrong.

The tuple you get from yview represents the fraction visible at the top and the fraction visible at the bottom. You can call yview_moveto to set the position at the top, and then let tkinter take care of the fraction at the bottom.

For example, if the yview you've saved is (0.42, 0.75), then you just need to call yview_moveto('0.42'). This will cause the view to be adjusted so that the given offset is at the top of the window.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thank you! It saves the last `yview` before closing the program so it should always open back up the correct position, right? Also, is there any chance you have a link to a page explaining this in more detail? – JohnT Nov 05 '18 at 16:47
  • @JohnT: there's no document that explains this in more detail. However,several tkinter documentation sites mention the `yview_moveto` command and its arguments. – Bryan Oakley Nov 05 '18 at 16:54
0

In case of widgets update with change bbox sizes, i use a followed snippet to keep scroll position:

#before repaint store vsb position caclulated in pixels from top
bbox = canvas.bbox(ALL)
self.mem_vsb_pos = canvas.yview()[0] * (bbox[3] - bbox[1])

#after repaint (back calculation):
bbox = canvas.bbox(ALL)
canvas.yview_moveto(self.do_vsb_pos / (bbox[3]-bbox[1]))

#before repaint - if need repaint from top
self.mem_vsb_pos = 0.0
  • [@Valeriy Chepelev](https://stackoverflow.com/users/15368340/valeriy-chepelev) What does `bbox[3]-bbox(https://stackoverflow.com/users/15368340/valeriy-chepelev)` mean? Why can't just `bbox[3]` be used? – Александр М Jul 18 '22 at 13:50
  • @АлександрМ , at "before repaint" we store relative scroll position, so on "after repaint" we recalculate position for a new bbox size. – Valeriy Chepelev Dec 30 '22 at 12:29