有没有办法在 Tkinter 上使用具有可滚动选项卡的垂直笔记本?

Is there a way to use a Vertical Notebook that has Scrollable Tabs on Tkinter?

我正在开发一个 tkinter 应用程序,我将以下代码用于垂直笔记本。

self.style = ttk.Style(self.window)
self.style.configure('lefttab.TNotebook', tabposition='wn')

但是,我希望能够垂直滚动这些笔记本。我希望能够像使用任何普通笔记本一样使用笔记本,只是您能够使用滚动条向下滚动不同的菜单选项。我做过研究,但找不到任何垂直滚动条,也没有成功尝试自己制作滚动条。

谢谢。

我们的想法是创建一个 VertNotebook class,它是一个包含滚动条和选项卡列表框的框架。您可以将 '<<ListboxSelect>>' 事件绑定到显示与选项卡关联的小部件的函数,以模仿 ttk.Notebook 的行为。这是代码:

import tkinter as tk
from tkinter import ttk


class VertNotebook(ttk.Frame):
    def __init__(self, *args, **kw):
        ttk.Frame.__init__(self, *args, **kw)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(2, weight=1)
        # scrollable tabs
        self._listbox = tk.Listbox(self, width=1, background='lightgrey', 
                                   highlightthickness=0, relief='raised')
        scroll = ttk.Scrollbar(self, orient='vertical', command=self._listbox.yview)
        self._listbox.configure(yscrollcommand=scroll.set)

        # list of widgets associated with the tabs
        self._tabs = []
        self._current_tab = None  # currently displayed tab

        scroll.grid(row=0, column=0, sticky='ns')
        self._listbox.grid(row=0, column=1, sticky='ns')
        # binding to display the selected tab
        self._listbox.bind('<<ListboxSelect>>', self.show_tab)

    def add(self, widget, label): # add tab
        self._listbox.insert('end', label)  # add label listbox
        # resize listbox to be large enough to show all tab labels
        self._listbox.configure(width=max(self._listbox.cget('width'), len(label)))
        if self._current_tab is not None:
            self._current_tab.grid_remove()
        self._tabs.append(widget)
        widget.grid(in_=self, column=2, row=0, sticky='ewns')
        self._current_tab = widget
        self._listbox.selection_clear(0, 'end')
        self._listbox.selection_set('end')
        self._listbox.see('end')

    def show_tab(self, event):
        print(event, self._listbox.curselection(), )
        try:
            widget = self._tabs[self._listbox.curselection()[0]]
            print(widget)
        except IndexError:
            return
        if self._current_tab is not None:
            self._current_tab.grid_remove()
        self._current_tab = widget
        widget.grid(in_=self, column=2, row=0, sticky='ewns')


root = tk.Tk()
nb = VertNotebook(root)
for i in range(50):
    nb.add(ttk.Label(nb, text='Label %i' % i), 'Tab %i' % i)
nb.pack(expand=True, fill='both')
root.mainloop()