0

I found a very elegant version of tab creation here : Tkinter Notebook create new tabs by clicking on a plus/+ tab like every web browser

Unfortunately, as I am trying this solution, I get an 'IndexError: tuple index out of range'

Don't make fun of me please, it's my first post here, and I just started learned Python a few months ago :)

This script is supposed to create a new tab based on a custom frame each time I click on the "+" tab, but the app window doesn't appear, and instead I get this "IndexError"

import tkinter as tk
from tkinter import ttk

class MainWindow(tk.Tk):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        notebook = ttk.Notebook(self)
        notebook.bind("<<NotebookTabChanged>>", self.add_tab(notebook))

        notebook.grid(sticky="NSEW")

        frame = ttk.Frame(self)
        notebook.add(frame, text="+")

    def add_tab(event, notebook):
        if notebook.select() == notebook.tabs()[-1]:
            index = len(notebook.tabs())-1
            frame = CustomFrame(notebook)
            notebook.insert(index, frame, text=f"Frame {index +1}")
            notebook.select(index)
    
class CustomFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

root = MainWindow()
root.mainloop()
RVB
  • 3
  • 2
  • Please [edit] your question to include the full error traceback - that will help us see more precisely where the problem is coming from! – JRiggles Aug 17 '23 at 15:10

2 Answers2

0

Your notebook does not have any tabs upon creation. When you do self.add_tab(notebook) for the first time you are trying to get a first tab by doing notebook.tabs()[-1], which gives you IndexError. What you could try to do is to add a "plus" tab before you bind notebook tab change. Like this:

import tkinter as tk
from tkinter import ttk

class MainWindow(tk.Tk):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        notebook = ttk.Notebook()
        frame = ttk.Frame(self)
        notebook.add(frame, text="+")
        notebook.bind("<<NotebookTabChanged", self.add_tab(notebook))
        notebook.grid(sticky="NSEW")

    def add_tab(event, notebook):
        if notebook.select() == notebook.tabs()[-1]:
            index = len(notebook.tabs())-1
            frame = CustomFrame(notebook)
            notebook.insert(index, frame, text=f"Frame {index +1}")
            notebook.select(index)
    
class CustomFrame(ttk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

root = MainWindow()
root.mainloop()
kirya_607
  • 1
  • 1
  • 1
    This solution works, except, that then, the "+" tab does not work as a tab creator anymore. – RVB Aug 17 '23 at 15:28
0

Note that notebook.bind("<<NotebookTabChanged>>", self.add_tab(notebook)) will execute self.add_tab(notebook) immediately.

It should be

notebook.bind("<<NotebookTabChanged>>", lambda e: self.add_tab(notebook))
acw1668
  • 40,144
  • 5
  • 22
  • 34