Tkinter Notebook 通过像每个网络浏览器一样单击加号/+ 选项卡来创建新选项卡

Tkinter Notebook create new tabs by clicking on a plus/+ tab like every web browser

我正在尝试通过单击最后一个选项卡在我的导航栏笔记本中创建新选项卡。为了使任务更加复杂,我的应用程序使用 类 编写。我当前不太优雅的解决方案需要一个带有按钮的条目来创建新选项卡,并在条目小部件中输入标题。有谁知道我的问题的更优雅的解决方案?

这是我的代码:

import tkinter as tk
from tkinter import ttk

class MainApp(tk.Tk):
    """Main window class"""
    def __init__(self):
        super(MainApp, self).__init__()
        self.geometry("1000x1000")
        self.main_window = tk.Frame(self)
        self.main_window.pack(side="top", fill="both", expand=True)
        # saving all tabs & Frames to a dictionary to be able to access them later
        self.frames = {}
        self.tabs = {}
        # create a tab bar
        self.navbar = Navbar(self.main_window)
        # set the layout
        self.set_layout()

    def set_layout(self):
        """creates the default app layout"""
        self.add_tab("Settings") # first page
        self.add_tab("Case 1")

    def add_tab(self, title):
        """adds a new tab with name title to the navbar"""
        tab = ttk.Frame(self)
        self.navbar.add(tab, text=title)
        self.tabs[title] = tab
        # check if Settings or Case type Tab, to create MainInput frame with correct buttons
        if title.lower().find("setting") != -1:
            self.frames[title] = MainInput(self, tab, self.navbar, settings=True)
        else:
            self.frames[title] = MainInput(self, tab, self.navbar, case=True)
        self.navbar.pack(fill=tk.BOTH, expand=tk.YES)
        for tab in self.tabs:
            self.frames[tab].grid(sticky="nesw")

    def add_frame(self, title, frame):
        """adds the frame to frames dict with key title"""
        self.frames[title] = frame

class Navbar(ttk.Notebook):
    """returns a Notebook"""
    def __init__(self, parent):
        ttk.Notebook.__init__(self, parent)

    @staticmethod
    def delete(tab):
        """delete current tab"""
        tab.forget(tab.select())

class MainInput(tk.Frame):
    """The base frame of every tab"""
    def __init__(self, root, parent, notebook, settings=False, case=False):
        tk.Frame.__init__(self, parent)
        # Either build a settings or testcase tab
        if settings is True:
            SettingsField(root, parent)
        if case is True:
            CaseGeneral(parent, notebook)

class SettingsField(tk.Frame):
    """Creates a settings tab"""
    def __init__(self, root, parent):
        tk.Frame.__init__(self, parent)
        # add the "new tab" name entry and button
        tk.Label(parent, text="Add new Testcase:").grid(row=0, column=0, columnspan=2, sticky="w")
        tk.Label(parent, text="Name:").grid(row=1, column=0, sticky="w", padx=20)
        new_tab_title = tk.Entry(parent, textvariable=tk.StringVar(), width=30)
        new_tab_title.grid(row=1, column=1, columnspan=2, sticky="w")
        add_button = tk.Button(parent, text="add", command=lambda: [root.add_tab(new_tab_title.get())])
        add_button.grid(row=1, column=3, sticky="w", padx=5)

class CaseGeneral(tk.Frame):
    def __init__(self, parent, notebook):
        tk.Frame.__init__(self, parent)
        # create "delete current tab" buton
        tk.Label(parent, text="delete Testcase").grid(row=0, column=0)
        delete_button = tk.Button(parent, text="delete", command=lambda: [Navbar.delete(notebook)])
        delete_button.grid(row=0, column=1, sticky="w")

运行 代码的图像: Settings Tab Cases

注意:请不要烤我,因为这是我第一次 post :)

一个非常简单的解决方案是在 <<NotebookTabChanged>> 上创建一个绑定,只要选择该行的最后一个选项卡,它就会创建一个新选项卡。然后,您可以创建一个标签为“+”的标签,并确保它是最后一个标签。

这是该技术的一个简单示例。它为新选项卡提供了标签 <untitled>。每次单击最后一个选项卡时,它都会在最后一个选项卡之前创建一个新选项卡,然后选择它。

import tkinter as tk
from tkinter import ttk

def handleTabChange(event):
    if notebook.select() == notebook.tabs()[-1]:
        index = len(notebook.tabs())-1
        frame = tk.Frame(notebook)
        notebook.insert(index, frame, text="<untitled>")
        notebook.select(index)

root = tk.Tk()
notebook = ttk.Notebook(root)
notebook.bind("<<NotebookTabChanged>>", handleTabChange)

notebook.pack(fill="both", expand=True)

# add a tab that creates new tabs when selected
frame = tk.Frame()
notebook.add(frame, text="+")

root.mainloop()