python - Event when entry's xview changes -
i creating simple program using tkinter
. want function called every time xview
property of entry
changes. there doesn't seem event this, @ least not 1 can find.
the <configure>
event fires on resize, handled, doesn't fire when actual value i'm tracking changes in different way, such user dragging mouse see end of entry.
here code:
import tkinter tk import tkfiledialog root = tk.tk() class repositoryfolderframe(tk.frame): def __init__(self, root): tk.frame.__init__(self, root) self.build_gui() self.set_entry_text("searching...") #root.after(0, self.find_repo) self.prev_entry_index = len(self.entry.get()) root.bind("<configure>", self.on_entry_resize) #self.entry.bind(???, self.on_entry_change) #self.entry.bind("<configure>", self.on_entry_change) def on_entry_resize(self, event): cur_entry_index = self.entry.xview()[1] if cur_entry_index != self.prev_entry_index: self.entry.xview(self.prev_entry_index) def on_entry_change(self, event): # should called when xview changes... cur_entry_index = self.entry.xview()[1] self.prev_entry_index = cur_entry_index def set_entry_text(self, text): self.entry_text.set(text) self.entry.xview("end") def build_gui(self): label = tk.label(self, text = "repository folder:") label.pack(side = tk.left) self.label = label entry_text = tk.stringvar() self.entry_text = entry_text entry = tk.entry(self, width = 50, textvariable = entry_text) entry.configure(state = 'readonly') entry.pack(side = tk.left, fill = tk.x, expand = 1) self.entry = entry button = tk.button(self, text = "browse...") button.pack(side = tk.left) self.button = button repo_frame = repositoryfolderframe(root) repo_frame.pack(fill = tk.x, expand = 1) root.mainloop()
there no mechanism getting notified when xview changes. there ways modifying underlying tcl code, it's more difficult it's worth.
a simple solution write function polls xview every few hundred milliseconds. can keep track of recent xview, compare current, , if has changed can fire off custom event (eg: <<xviewchanged>>
) can bind to.
it this:
class repositoryfolderframe(tk.frame): def __init__(self, root): ... self.entry.bind("<<xviewchanged>>", self.on_entry_change) # keep cache of previous xviews. dictionary # used in case want more self._xview = {} self.watch_xview(self.entry) def watch_xview(self, widget): xview = widget.xview() prev_xview = self._xview.get(widget, "") self._xview[widget] = xview if xview != prev_xview: widget.event_generate("<<xviewchanged>>") widget.after(100, self.watch_xview, widget)
you'll need modify edge case entry widget destroyed, though can handle simple try
around code. should suitably performant, though might need verify if have literally hundreds of entry widgets.
Comments
Post a Comment