Python TK Notebook tab change check

Question:

Newbie programmer here. I am building a tk based desktop app and ran into an issue:

I have a main window with several stuff in it including two tabs:

    global nBook
    nBook = ttk.Notebook(self, name="book")
    nBook.place(x=300,y=400)
    frameOne = ttk.Frame(nBook, width=100, height=100)
    frameTwo = ttk.Frame(nBook, width=100, height=100)
    nBook.add(frameOne, text='T1')
    nBook.add(frameTwo, text='T2')
    frameOne.bind("<<NotebookTabChanged>>", self.routine())
    frameTwo.bind("<<NotebookTabChanged>>", self.routine())

routine() is a function that SHOULD perform a check every time T2 is selected

def routine(self):
    if str(nBook.index(nBook.select())) == "2":
        # Do stuff
    else:
        pass

Problem is that it doesn’t do anything when the tab is changed except for calling the routine function as soon as I open the app and never again. I just can’t figure out what I’m doing wrong.

Could anyone point out the mistake(s) I’m making?

EDIT: Same issue if I try

nBook.bind("<<NotebookTabChanged>>", self.xbRoutine())
Asked By: Alin Iuga

||

Answers:

The error comes from the event binding statements: when using self.routine() the callback is called when the bind statement is executed, not when the event is triggered. To get the correct behavior, the second argument of bind should be the name of a function not a call to this function, so simply remove the parentheses.

Another error: when using bind, the callback function is expected to have a first argument (traditionnaly called event) storing the event parameters. So you should define your callback as:

def routine(self, event):
    ...
Answered By: sciroccorics

I had the same problem. The answer given by @sciroccorics is not complete.
What you bind is not the tab itself, but the notebook.

So, it should be

nBook.bind("<<NotebookTabChanged>>", self.xbRoutine)
Answered By: flo metoo

Alternatively you could use lambda.
In your case this will look something like this:

frameOne.bind("<<NotebookTabChanged>>", lambda _: self.routine())

Don’t forget the _, otherwise you will get a TypeError, since the event is passed as an argument.

lamba is really helpful if your function requires one or more arguments.

Answered By: TimoGH
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.