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

标签 python tkinter

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

这是我的代码:

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

注意:请不要烤我,因为这是我在这里的第一篇文章:)

最佳答案

一个非常简单的解决方案是在 <<NotebookTabChanged>> 上创建一个绑定(bind)that creates a new tab whenever the last tab on the row is selected.然后,您可以创建一个带有“+”作为标签的选项卡,并确保它是最后一个选项卡。

这是该技术的一个简单示例。它为新选项卡提供标签 <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()

screenshot

关于python - Tkinter Notebook 通过像每个网络浏览器一样单击加号/+ 选项卡来创建新选项卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71859022/

相关文章:

python - 如何在接受用户输入的同时读取 pandas read_csv 中带有转义字符的文件路径?

python - 傅立叶空间平移

python - Numpy:为列表中的每个数组的 np.array 的每一行乘以 (1/2)^k

python - Tkinter多处理不能泡菜

python - 使用 Wand 保存单帧

python - Pixels_per_cell 的默认值 skimage.feature.hog

python - 在确定模式下使用 ttk.Progressbar

python - Tkinter PIL 图像不显示在函数内部

python - 如何从多个 Checkbutton Tkinter 获取值(value)

python - 什么是 Tkinter 的 tkapp?