-2

I have this code (sorry not really minimal):

import tkinter as tk

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        # tk.Frame.__init__(self, parent, *args, **kwargs)
        super().__init__(parent, *args, **kwargs)
        self.reader = parent
        
        # self.reader = tk.Toplevel(self)
        self.reader.title("XXX")
        self.reader.resizable(False, True)
        self.reader.geometry("650x5")
        self.reader.minsize(650,150)
        
        self.panel = tk.Text(self.reader, wrap="word", width=12, font=('Courier',14))
        self.viewer = tk.Text(self.reader, wrap="word", font=('Courier',14))
        
        self.viewer.insert(tk.INSERT,'h\nm\nbbb\ntt\n\nbbb')
        
        self.panel.insert(tk.INSERT,'hgggg\ngggm\nbbb\n\nbbbbtt\n\nbbb')
        
        self.labelv1 = tk.IntVar()
        # self.labelv1.set(int(self.panel.index('end-1c').split('.')[0]))
        
        self.labelv2 = tk.IntVar()
        # self.labelv2.set(int(self.viewer.index('end-1c').split('.')[0]))
        
        self.pippo = tk.StringVar()
        # self.pippo.set(("Panel : "+str(self.labelv1)+" Viewer : "+str(self.labelv2)))
        
        self.label = tk.Label(self.reader, textvariable = self.pippo)
        self.label.pack(side='top')
        # self.update_labels()
        
        self.counter = tk.IntVar()
        self.counter.set(0)
                        
        # self.reader.bind_class('Text', '<Key>', self.update_labels())   #winfo_toplevel()
        # self.winfo_toplevel().bind("<Key>", self.update_labels())

        # self.reader.bind("<Key>", self.update_labels())
               
        self.reader.bind("<Key>",  lambda event: self.update_labels())
                
        self.scrollbar = tk.Scrollbar(self.reader, command=(self.on_scrollbar))
        
        self.scrollbar.pack(side="right", fill="y")
        self.panel.pack(side="left", fill="both", expand=True)
        self.viewer.pack(side="right", fill="both", expand=True)
                
        # Changing the settings to make the scrolling work
        # self.scrollbar['command'] = self.on_scrollbar
        self.panel['yscrollcommand'] = self.on_textscroll
        self.viewer['yscrollcommand'] = self.on_textscroll
        
    def update_labels(self, *args):

        print('OKK')

        self.labelv1.set(int(self.panel.index('end-1c').split('.')[0]))
        
        self.labelv2.set(int(self.viewer.index('end-1c').split('.')[0]))
        
        self.pippo.set("Panel : "+str(self.labelv1.get())+" Viewer : "+str(self.labelv2.get()))

        self.counter.set(self.counter.get() + 1)
      
        print('updating labels : ' , self.counter.get(),'   /  ', self.pippo.get())
        return
                
    def on_scrollbar(self, *args):
        """
        Scrolls both text widgets when the scrollbar is moved
        """
        self.panel.yview(*args)
        self.viewer.yview(*args)
            
    def on_textscroll(self, *args):
        '''Moves the scrollbar and scrolls text widgets when the mousewheel
        is moved on a text widget'''
        self.scrollbar.set(*args)
        self.on_scrollbar('moveto', args[0])


if __name__ == "__main__":
    master = tk.Tk()
   
    MainApplication(master)  
    master.mainloop()  

I don't understand why does:

self.reader.bind("<Key>", lambda event: self.update_labels())

that binds any pressed key inside the text windows to a function update_labels() that reports the number of line text inside the window itself

works, while

self.reader.bind("<Key>", self.update_labels())

doesn't. I read a lot of docs and examples, here on SO too, but wasn't able to figure-out why the latter doesn't work as it should.

pippo1980
  • 2,181
  • 3
  • 14
  • 30
  • 2
    I think it's because when you pass lambda to the function, you are giving the reference of the function to the self,reader.bind method. If you want to do the same, you should only pass self.update_labels and not self.update_labels(). Then, your method self.update_labels should have an argyument event and do something with it: def update_labels(event): .... – CyDevos Sep 16 '21 at 22:16
  • @CyDevos thanks dude, it does works, was getting crazy with it, I'll try to understand that better – pippo1980 Sep 16 '21 at 22:19
  • 1
    See https://stackoverflow.com/questions/5767228/why-is-the-command-bound-to-a-button-or-event-executed-when-declared – Bryan Oakley Sep 16 '21 at 22:34

1 Answers1

2

The issue you have is because you are giving the output of the function and not the reference of it. To fix your issue you should do:

self.reader.bind("<Key>", self.update_labels)

and somewhere define:

def update_labels(self, event):
    ...
CyDevos
  • 395
  • 4
  • 11