[wxPython] Notebook Tabs

Does anyone know how to change the background colors of individual notebook
tabs? I have looked everywhere and tried everything I can think of, but have
had no success. Is it possible? Have I missed something obvious? (I have
wxStyledTextCtrl's as notebook pages, and want to change tab colors based on
certain conditions).

Thanks in advance.

-Ron

···

___________________________________________
Ron Clarke
Digital Printing Technologies
Hewlett-Packard Co.
ron_clarke@hp.com
ecard - https://ecardfile.com/id/ron_clarke

Ron

What I do is to add a panel to each tab, and I add the controls I want
for each page to the corresponding panel instead and I set the
background color for each panel.

A crude example would be ...
    
  #Where nb is a nootebook
  self.generalPanel = wxMyGeneralPanel(self.nb, parameters)
  self.propPanel = wxMyPropPanel(self.nb, parameters)
  self.phasesPanel = wxMyPhasesPanel(self.nb, parameters)

        self.generalPanel.SetBackgroundColour(wxColour(0, 0, 255))
        self.propPanel.SetBackgroundColour(wxColour(0, 255, 0))
        self.phasesPanel.SetBackgroundColour(wxColour(255, 0, 0))

        self.nb.AddPage(self.generalPanel, "General")
        self.nb.AddPage(self.propPanel, "Properties")
        self.nb.AddPage(self.phasesPanel, "Phases")
        self.nb.SetSelection(0)
  self.nb.Refresh

So you are not really setting the background color of the pages in the
notebook, but it looks like if you were actually doing it

Hope it helps

Raul Cota

"CLARKE,RON (HP-Vancouver,ex1)" wrote:

···

Does anyone know how to change the background colors of individual notebook
tabs? I have looked everywhere and tried everything I can think of, but have
had no success. Is it possible? Have I missed something obvious? (I have
wxStyledTextCtrl's as notebook pages, and want to change tab colors based on
certain conditions).

Thanks in advance.

-Ron

___________________________________________
Ron Clarke
Digital Printing Technologies
Hewlett-Packard Co.
ron_clarke@hp.com
ecard - https://ecardfile.com/id/ron_clarke

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwindows.org
http://lists.wxwindows.org/mailman/listinfo/wxpython-users

Does anyone know how to change the background colors of individual

notebook

tabs? I have looked everywhere and tried everything I can think of, but

have

had no success. Is it possible? Have I missed something obvious? (I have
wxStyledTextCtrl's as notebook pages, and want to change tab colors based

on

certain conditions).

There's nothing like that exposed in the wxNotebook API, and even if it was
I'm not sure it is possible on all the platforms.

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

25 years after the initial post… can we now do this somehow? the AuiNotebook supports association with AuiSimpleTabArt which has the method SetActiveColour but that just highlights the active tab. Like the original poster, I am trying to highlight tabs based on conditions like warnings/errors that can be solved by editing data on those tabs. Specifically I have a notebook that holds Grids that represent XLSX data, and based on my validation of that data, want to draw attention to the data of concern, starting at the tab (I already got Grid cells highlighted and tooltips showing up as needed on them).

Ok, I got it working with a custom ArtProvider… here’s my demo:

#!/usr/bin/env python

from random import random

import wx
#import wx.aui as aui
import wx.lib.agw.aui as aui


text = """\
Hello!

Welcome to this little demo of coloring Notebook tabs dynamically using a custom AuiDefaultTabArt object.

To try it out, click tabs and another will randomly change color.
"""

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


color_whole_tab = True

class BgColorTabArt(aui.AuiDefaultTabArt):
    def __init__(self):
        # AuiNotebook
        # clones the tab art per tab strip via AuiDefaultTabArt.Clone(), which only
        # preserves attributes whose names end in _colour/_font/_brush/_pen
        # (see aui_utilities.CopyAttributes).
        self._custom_bg_colour = {}
        super().__init__()

    def SetPageBgColour(self, page_index, colour):
        self._custom_bg_colour[page_index] = colour

    def DrawTab(self, dc, wnd, page, rect, close_button_state, *args):
        old_base = self._base_colour

        try:
            page_index = -1
            if hasattr(wnd, "GetPageCount") and hasattr(wnd, "GetPage"):
                for i in range(wnd.GetPageCount()):
                    if wnd.GetPage(i) == page:
                        page_index = i
                        break

            if page_index in self._custom_bg_colour:
                colour = self._custom_bg_colour[page_index]
                
                if color_whole_tab:
                    # SetDefaultColours() recomputes ALL the derived colours that
                    # DrawTab() actually paints with: _base_colour_pen/_brush
                    # (active tab fill), _tab_top_colour/_tab_bottom_colour
                    # (active gradient), _tab_inactive_top_colour/
                    # _tab_inactive_bottom_colour (inactive gradient), and
                    # _border_colour/_border_pen.
                    self.SetDefaultColours(colour)
                else:
                    # just underline the tab with the color:
                     # # Fill tab rect
                    btm_rect = wx.Rect(*page.rect)
                    btm_rect.height -= 4
                    btm_rect.width -= 1
                    btm_rect.height //= 2
                    btm_rect.y = btm_rect.y + page.rect.height - btm_rect.height - 1
                    dc.SetBrush(wx.Brush(colour))
                    dc.SetPen(wx.Pen(colour))
                    dc.DrawRectangle(btm_rect)
            # Call base class with whatever args we got
            return super().DrawTab(dc, wnd, page, rect, close_button_state, *args)

        finally:
            self.SetDefaultColours(old_base)

class TestPanel(wx.Panel):
    def __init__(self, parent, log):
        self.log = log
    
        wx.Panel.__init__(self, parent, -1)

        self.nb = aui.AuiNotebook(self)
        self._art = BgColorTabArt()
        self.nb.SetArtProvider(self._art)
        page = wx.TextCtrl(self.nb, -1, text, style=wx.TE_MULTILINE)
        self.nb.AddPage(page, "Welcome")

        for num in range(1, 5):
            page = wx.TextCtrl(self.nb, -1, "This is page %d" % num ,
                               style=wx.TE_MULTILINE)
            self.nb.AddPage(page, "Tab Number %d" % num)

        self._art.SetPageBgColour(0, wx.RED)

        sizer = wx.BoxSizer()
        sizer.Add(self.nb, 1, wx.EXPAND)
        self.SetSizer(sizer)
        self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
        wx.CallAfter(self.nb.SendSizeEvent)
        
    def OnPageChanged(self, evt):
        print("OnPageChanged")
        import random
        page_to_color = random.randint(0, self.nb.GetPageCount() - 1)
        color = wx.Colour(int(random.random() * 255), int(random.random() * 255), int(random.random() * 255))
        self.nb.GetArtProvider().SetPageBgColour(page_to_color, color)
        evt.Skip()
#----------------------------------------------------------------------


class TestFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="AuiNotebook Dynamic Tab Background Color Test", size=(800, 200))
        panel =  TestPanel(self, None)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel, 1, wx.EXPAND | wx.ALL, 10)
        self.SetSizer(sizer)
        self.SetSize(800, 200)

        
class TestApp(wx.App):
    def OnInit(self):
        frame = TestFrame()
        frame.Show()
        return True

if __name__ == '__main__':
    app = TestApp()
    app.MainLoop()

Enjoy!

1 Like