1

I found code on here a while ago that allows for the addition of a close button on the tab of notebooks in tkinter but I want to be able to combine a regular notebook (without the close button) with a custom notebook. When I tried to do this I get a set of tabs with the regular notebook and then below it another set of tabs with the custom notebook.

As suggested, I've included the picture below showing what currently happens but what I'm looking for is to have all of the tabs together (where the red would be inline with the orange, green, blue, etc. tabs) but would not have the x that allows it to be closed.

Not what I want

The code I've been trying to alter is:

import tkinter as tk
import tkinter.ttk as ttk

#----------------------------------------------------------

class CustomNotebook(ttk.Notebook):
    '''
    A ttk Notebook with close buttons
    on each tab
    '''
    __initialized = False

    #------------------------------------------------------
    def __init__(self, *args, **kwargs):
        if not self.__initialized:
            self.__initialize_custom_style()
            self.__inititialized = True

        kwargs['style'] = 'CustomNotebook'
        ttk.Notebook.__init__(self, *args, **kwargs)

        self._active = None

        self.bind('<ButtonPress-1>', self.on_close_press, True)
        self.bind('<ButtonRelease-1>', self.on_close_release)

    #------------------------------------------------------
    def on_close_press(self, event):
        '''
        Called when the button is pressed
        over the close button
        '''
        element = self.identify(event.x, event.y)

        if 'close' in element:
            index = self.index('@%d,%d' % (event.x, event.y))
            self.state(['pressed'])
            self._active = index

    #------------------------------------------------------
    def on_close_release(self, event):
        '''
        Called when the button is released
        over the close button
        '''
        if not self.instate(['pressed']):
            return

        element =  self.identify(event.x, event.y)
        index = self.index('@%d,%d' % (event.x, event.y))

        if 'close' in element and self._active == index:
            self.forget(index)
            self.event_generate('<<NotebookTabClosed>>')

        self.state(['!pressed'])
        self._active = None

    #------------------------------------------------------
    def __initialize_custom_style(self):
        style = ttk.Style()
        self.images = (
            tk.PhotoImage('img_close', data='''
                R0lGODlhCAAIAMIBAAAAADs7O4+Pj9nZ2Ts7Ozs7Ozs7Ozs7OyH+EUNyZWF0ZWQg
                d2l0aCBHSU1QACH5BAEKAAQALAAAAAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU
                5kEJADs=
                '''),
            tk.PhotoImage('img_closeactive', data='''
                R0lGODlhCAAIAMIEAAAAAP/SAP/bNNnZ2cbGxsbGxsbGxsbGxiH5BAEKAAQALAAA
                AAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU5kEJADs=
                '''),
            tk.PhotoImage('img_closepressed', data='''
                R0lGODlhCAAIAMIEAAAAAOUqKv9mZtnZ2Ts7Ozs7Ozs7Ozs7OyH+EUNyZWF0ZWQg
                d2l0aCBHSU1QACH5BAEKAAQALAAAAAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU
                5kEJADs=
                ''')
            )

        style.element_create('close', 'image', 'img_close',
            ('active', 'pressed', '!disabled', 'img_closepressed'),
            ('active', '!disabled', 'img_closeactive'), border=8, sticky='')
        style.layout('CustomNotebook', [('CustomNotebook.client', {'sticky': 'nswe'})])
        style.layout('CustomNotebook.Tab', [
            ('CustomNotebook.tab', {
                'sticky': 'nswe', 
                'children': [
                    ('CustomNotebook.padding', {
                        'side': 'top', 
                        'sticky': 'nswe',
                        'children': [
                            ('CustomNotebook.focus', {
                                'side': 'top', 
                                'sticky': 'nswe',
                                'children': [
                                    ('CustomNotebook.label', {'side': 'left', 'sticky': ''}),
                                    ('CustomNotebook.close', {'side': 'left', 'sticky': ''}),
                                ]
                            })
                        ]
                    })
                ]
            })
        ])

#----------------------------------------------------------

if __name__ == '__main__':
    root = tk.Tk()

    note = ttk.Notebook(width=200, height=200)
    note.pack(side='top', fill='both', expand=True)
    notebook = CustomNotebook(width=200, height=200)
    notebook.pack(side='top', fill='both', expand=True)

    for color in ('red', 'orange', 'green', 'blue', 'violet'):
        if color == 'red':
            frame = tk.Frame(note, background=color)
            note.add(frame, text=color)
        else:
            frame = tk.Frame(notebook, background=color)
            notebook.add(frame, text=color)

    root.mainloop()

I'm guessing that I have to use the custom notebook and cause one of the tabs to not use the close features but I don't know how to implement that. Any help is greatly appreciated.

I'd also like to say thanks to Bryan Oakley for providing the CustomNotebook class which I found on the following post: Is there a way to add close buttons to tabs in tkinter.ttk.Notebook?

stovfl
  • 14,998
  • 7
  • 24
  • 51
blaufer
  • 117
  • 1
  • 3
  • 11
  • ***"so that all the tabs are on one level"***: [Edit] your question and show a image that explains this **not** behavior. – stovfl Dec 04 '19 at 08:55
  • ***"where the `[red]` would be inline with the `[orange x]`"***: You create **two** `Notebook` how do you expect to have these *inline*? Do you want to use `CustomNotebook`, but want to config **every** tab different, e.g. with and without `X`? – stovfl Dec 05 '19 at 08:47
  • 1
    Yes, that's exactly what I'm looking for. I know that creating two notebooks doesn't work but I don't know how to use the customNotebook to create a tab without the x. – blaufer Dec 06 '19 at 00:55
  • Far as i understand, `CustomNotebook` uses `Style` and that's **all** or **nothing**. @Bryan Oakley could answer this question. I can imagin, using **overlayed** widgets, are a possible solution. The core is to get the `bbox` of a `tab`. Another approach to use a [`image`](https://stackoverflow.com/questions/16514617/python-tkinter-notebook-widget). – stovfl Dec 06 '19 at 08:49

0 Answers0