Set and retain color on individual tabs in QTabBar


#1

I am trying to check existing tabs in a QTabBar against the list of items within a QMenu. And if the existing tabs contains item(s) that are not found in the QMenu, that said tab is to be highlighted in red.

Initially I was using the tabTextColor however it does not seems to be changing the text color. Then as I googled around, some were saying to use setStylesheet instead and hence I decided to change the background color instead of the text color that I was initially going for.

Even so, I am having issues in ‘retaining’ the red color/ setting color to a particular tab. In my following code, if I do the following:

  1. Populate 3 tabs eg. (A, B, C), contents read from a text file
  2. Remove B from text file
  3. Click on the add button, this will highlight the B tab to Red
  4. If I navigate to tab C, tab C will be colored red and the initial highlight B will be reverted back to the original color. And for any tabs I am selecting now, it will be highlighted in red.

Appreciate for any insights in advance!

class MyWin(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyWin, self).__init__()
        central_widget = QtGui.QWidget()
        self.setCentralWidget(central_widget)
        vlay = QtGui.QVBoxLayout(central_widget)
        hlay = QtGui.QHBoxLayout()
        vlay.addLayout(hlay)
        vlay.addStretch()

        self.add_button = QtGui.QToolButton()
        self.tab_bar = QtGui.QTabBar(self)
        self.add_button.setIcon(QtGui.QIcon('add.png'))

        self.qmenu = QtGui.QMenu(self.add_button)
        self.add_button.setMenu(self.qmenu)
        self.add_button.setPopupMode(QtGui.QToolButton.InstantPopup)

        self.qmenu.aboutToShow.connect(self.set_menu)

        self.tab_bar.setTabButton(
            0,
            QtGui.QTabBar.ButtonPosition.RightSide,
            self.add_button
        )
        hlay.addWidget(self.add_button)
        hlay.addWidget(self.tab_bar)

    @QtCore.pyqtSlot()
    def set_menu(self):
        with open('/Desktop/item_file.txt') as f:
            menu_options = f.read().splitlines()
        self.qmenu.clear()

        self.tabs_precheck()

        for opt in menu_options:
            self.qmenu.addAction(opt, partial(self.set_new_tab, opt))

    def get_all_tabs(self):
        all_existing_tabs = {}
        for index in range(self.tab_bar.count()):
            all_existing_tabs[index] = self.tab_bar.tabText(index)

        return all_existing_tabs

    def set_new_tab(self, opt):
        all_tabs = self.get_all_tabs()

        if not opt in all_tabs.values():
            self.tab_bar.addTab(opt)

    def tabs_precheck(self):
        # Get the tabs that are already populated
        before_tabs = {}
        for index in range(self.tab_bar.count()):
            before_tabs[self.tab_bar.tabText(index)] = index


        # Get the items in qmenu items
        with open('/Desktop/item_file.txt') as f:
           qmenu_items = f.read().splitlines()


        # Get the difference between the 2
        difference = list(set(before_tabs.keys()) - set(qmenu_items))

        for diff in difference:
            # Get the 'before' index
            index_value = before_tabs.get(diff)
            # Set that particular tab background color to 'RED'
            self.tab_bar.setCurentIndex(index_value)
            self.tab_bar.setStyleSheet('''
                QTabBar::tab {background-color: red;}
                '''
            )

            # Did try out using `self.tab_bar.setTabTextColor(index_value, QtCore.Qt.red)
            # But there are no colors made onto the text visually... But there are definetly 
            # changes in terms of values if I tried to print it out...


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = MyWin()
    w.show()
    sys.exit(app.exec_())