Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTabWidget, setting colour of tab itself ?
Forum Updated to NodeBB v4.3 + New Features

QTabWidget, setting colour of tab itself ?

Scheduled Pinned Locked Moved Solved General and Desktop
114 Posts 4 Posters 61.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JoeCFDJ JoeCFD

    @SPlatten I can explain the concept to you, but can not give you code. You create a tabbar class to inherit qtabbar and add it to qtabwidget. Define or add your tabs(a class tab with text and icons) to tabbar and override paintEvent in tabbar to paint all tabs. Then you can add a timer to tab class to hide or display or toggle icons when needed.
    QTabBar source code is here:
    https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qtabbar.cpp.html

    SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by
    #25

    @JoeCFD , thank you

    Kind Regards,
    Sy

    1 Reply Last reply
    0
    • JoeCFDJ JoeCFD

      @SPlatten I can explain the concept to you, but can not give you code. You create a tabbar class to inherit qtabbar and add it to qtabwidget. Define or add your tabs(a class tab with text and icons) to tabbar and override paintEvent in tabbar to paint all tabs. Then you can add a timer to tab class to hide or display or toggle icons when needed.
      QTabBar source code is here:
      https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qtabbar.cpp.html

      SPlattenS Offline
      SPlattenS Offline
      SPlatten
      wrote on last edited by SPlatten
      #26

      @JoeCFD , hello, I'm trying to do this today, but not sure quite where to start. I have code already existing which I didn't write, the existing code uses a QTabWidget in the UI. Each tab is defined in the UI as QWidget.

      Do I replace the QWidget with my own implementation? Is there a tutorial that could help me or guide me through this process ?

      I'm getting confused by the online documentation for QTabWidget and QTabBar:

      https://doc.qt.io/qt-6/qtabwidget.html
      QTabWidget Class
      The QTabWidget class provides a stack of tabbed widgets.

      https://doc.qt.io/qt-6/qtabbar.html
      QTabBar Class
      The QTabBar class provides a tab bar, e.g. for use in tabbed dialogs.

      I want to implement a tab where I can set the background colour according to my own logic.

      I found this:
      https://stackoverflow.com/questions/46137500/qt-tabwidget-each-tab-title-background-color

      I am trying to tailor it to my problem....the issue I'm having now is that the tabs are already defined in the UI. How can I apply this logic to the tabs that are already defined in the UI ?

      Kind Regards,
      Sy

      1 Reply Last reply
      0
      • SPlattenS Offline
        SPlattenS Offline
        SPlatten
        wrote on last edited by
        #27

        @J-Hilk , @JonB , @JoeCFD , This is the current issue or at least one issue:

        The UI contained an instance of QTabWidget. This was set-up to contain the following tabs:

        &Overall
        C&2
        &CGU
        &LMS
        &PDLT
        &NLA
        P&GU
        &HCU
        &UPSD
        &Sensors
        

        In the XML file these tabs were defined with the class as QWidget I have edited the XML file and changed instances of QTabWidget to TabWidget and the tabs from QWidget to TabBar which matches the names of the new implementation I am trying to use.

        However I'm not sure why or what I need to do in order to transfer the tabs from the UI into the class I am using so I can use the colours that the replacement class is going to allow?

        Kind Regards,
        Sy

        SPlattenS JonBJ 2 Replies Last reply
        0
        • SPlattenS SPlatten

          @J-Hilk , @JonB , @JoeCFD , This is the current issue or at least one issue:

          The UI contained an instance of QTabWidget. This was set-up to contain the following tabs:

          &Overall
          C&2
          &CGU
          &LMS
          &PDLT
          &NLA
          P&GU
          &HCU
          &UPSD
          &Sensors
          

          In the XML file these tabs were defined with the class as QWidget I have edited the XML file and changed instances of QTabWidget to TabWidget and the tabs from QWidget to TabBar which matches the names of the new implementation I am trying to use.

          However I'm not sure why or what I need to do in order to transfer the tabs from the UI into the class I am using so I can use the colours that the replacement class is going to allow?

          SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by
          #28

          @J-Hilk , @JonB , @JoeCFD , a snippet from the UI file:

          <widget class="TabWidget" name="tab_widget">
            <property name="font">
              <font>
                <pointsize>12</pointsize>
                <weight>75</weight>
                <bold>true</bold>
              </font>
            </property>
            <property name="styleSheet">
              <string notr="true"/>
            </property>
            <property name="currentIndx">
              <number>0</number>
            </property>
            <widget class="TabBar" nam="overall_tab">
              <property name="focusPolicy">
                <enum>Qt::TabFocus</enum>
              </property>
              <attribute name="title">
                <string>&amp;Overall</string>
              </attribute>
              ....
          

          I can see in my log output that the constructor for the TabBar is called for each instance of the TabBar in the UI file. Can I determine from the constructor call what the title attribute is ?

          Kind Regards,
          Sy

          JonBJ 1 Reply Last reply
          0
          • SPlattenS SPlatten

            @J-Hilk , @JonB , @JoeCFD , a snippet from the UI file:

            <widget class="TabWidget" name="tab_widget">
              <property name="font">
                <font>
                  <pointsize>12</pointsize>
                  <weight>75</weight>
                  <bold>true</bold>
                </font>
              </property>
              <property name="styleSheet">
                <string notr="true"/>
              </property>
              <property name="currentIndx">
                <number>0</number>
              </property>
              <widget class="TabBar" nam="overall_tab">
                <property name="focusPolicy">
                  <enum>Qt::TabFocus</enum>
                </property>
                <attribute name="title">
                  <string>&amp;Overall</string>
                </attribute>
                ....
            

            I can see in my log output that the constructor for the TabBar is called for each instance of the TabBar in the UI file. Can I determine from the constructor call what the title attribute is ?

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #29

            @SPlatten
            Constructor of what?

            As far as I can see code must call either QTabWidget::setTabText(int index, const QString &label), QTabWidget::addTab(QWidget *page, const QString &label) or QTabBar::setTabText(int index, const QString &text). These are all individual calls, there is no "constructor" which takes the tab text/title as a parameter. Nor are any of the methods virtual. I imagine an explicit call is made to one of these after whatever construction. So does that answer your question as "No"?

            Meanwhile you can also look in the uic-generated ui_....h file for the actual code used to execute what it reads from the .ui file, if that helps clarify.

            SPlattenS 1 Reply Last reply
            0
            • JonBJ JonB

              @SPlatten
              Constructor of what?

              As far as I can see code must call either QTabWidget::setTabText(int index, const QString &label), QTabWidget::addTab(QWidget *page, const QString &label) or QTabBar::setTabText(int index, const QString &text). These are all individual calls, there is no "constructor" which takes the tab text/title as a parameter. Nor are any of the methods virtual. I imagine an explicit call is made to one of these after whatever construction. So does that answer your question as "No"?

              Meanwhile you can also look in the uic-generated ui_....h file for the actual code used to execute what it reads from the .ui file, if that helps clarify.

              SPlattenS Offline
              SPlattenS Offline
              SPlatten
              wrote on last edited by
              #30

              @JonB , the default constructor of the TabBar is being called I assume when the UI file is parsed?

              class TabBar : public QTabBar {
              private:
                  QHash<QString, QColor> colors_;
              
              protected:
                  void paintEvent(QPaintEvent* evt) {
              ... 
                  }
              
              public:
                  TabBar(QWidget* parent = 0) : QTabBar(parent) {
                      ...
                  }
              ...
              }
              

              Kind Regards,
              Sy

              JonBJ 1 Reply Last reply
              0
              • SPlattenS SPlatten

                @JonB , the default constructor of the TabBar is being called I assume when the UI file is parsed?

                class TabBar : public QTabBar {
                private:
                    QHash<QString, QColor> colors_;
                
                protected:
                    void paintEvent(QPaintEvent* evt) {
                ... 
                    }
                
                public:
                    TabBar(QWidget* parent = 0) : QTabBar(parent) {
                        ...
                    }
                ...
                }
                
                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #31

                @SPlatten
                Like I said, look in the ui_...h file?

                But I don't see that helps particularly. Doesn't the ui_...h show some explicit, separate call to one of the functions I pasted after the TabWidget/TabBar has been constructed?

                SPlattenS 1 Reply Last reply
                0
                • JonBJ JonB

                  @SPlatten
                  Like I said, look in the ui_...h file?

                  But I don't see that helps particularly. Doesn't the ui_...h show some explicit, separate call to one of the functions I pasted after the TabWidget/TabBar has been constructed?

                  SPlattenS Offline
                  SPlattenS Offline
                  SPlatten
                  wrote on last edited by SPlatten
                  #32

                  @JonB , from ui_...h file:

                  overall_tab = new TabBar();
                  overall_tab->setObjectName(QString::fromUtf8("overall_tab"));
                  

                  Some where nearer the end of file in the function retranslateUi there is a call to:

                  tab_widget->setTabText(tab_widget->indexOf(overall_tab), QApplication::translate("::wsStatusPage", "&Overall", 0, QApplication::UnicodeUTF8));
                  

                  Its all a bit fragmented...is there anything I can do to the UI file that will help me to identify the tab when the constructor is called?

                  I'm reworking this code, as it isn't well written and doesn't follow the correct way of doing things, hopefully this will lead to a solution.

                  Kind Regards,
                  Sy

                  JonBJ 1 Reply Last reply
                  0
                  • SPlattenS SPlatten

                    @JonB , from ui_...h file:

                    overall_tab = new TabBar();
                    overall_tab->setObjectName(QString::fromUtf8("overall_tab"));
                    

                    Some where nearer the end of file in the function retranslateUi there is a call to:

                    tab_widget->setTabText(tab_widget->indexOf(overall_tab), QApplication::translate("::wsStatusPage", "&Overall", 0, QApplication::UnicodeUTF8));
                    

                    Its all a bit fragmented...is there anything I can do to the UI file that will help me to identify the tab when the constructor is called?

                    I'm reworking this code, as it isn't well written and doesn't follow the correct way of doing things, hopefully this will lead to a solution.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #33

                    @SPlatten said in QTabWidget, setting colour of tab itself ?:

                    is there anything I can do to the UI file that will help me to identify the tab when the constructor is called?

                    Nope. As you can see, the tab text is not set until that tab_widget->setTabText() is called, much later than construction. That's how it implements the instructions from the .ui file.

                    At least in terms of the tab's text/title, which is what you say you want to know.

                    And once again anyway (not that it helps): "the constructor" of what are you asking about? QTabWidget? QTabBar? Tabs are not even constructed until after both of these anyway.

                    SPlattenS 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @SPlatten said in QTabWidget, setting colour of tab itself ?:

                      is there anything I can do to the UI file that will help me to identify the tab when the constructor is called?

                      Nope. As you can see, the tab text is not set until that tab_widget->setTabText() is called, much later than construction. That's how it implements the instructions from the .ui file.

                      At least in terms of the tab's text/title, which is what you say you want to know.

                      And once again anyway (not that it helps): "the constructor" of what are you asking about? QTabWidget? QTabBar? Tabs are not even constructed until after both of these anyway.

                      SPlattenS Offline
                      SPlattenS Offline
                      SPlatten
                      wrote on last edited by
                      #34

                      @JonB , I guess I could generate an index of the tabs and use its position to indicate what it is...

                      Kind Regards,
                      Sy

                      JonBJ 1 Reply Last reply
                      0
                      • SPlattenS SPlatten

                        @JonB , I guess I could generate an index of the tabs and use its position to indicate what it is...

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #35

                        @SPlatten
                        So now you are saying you do not need to know about the text/title after all??

                        SPlattenS 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @SPlatten
                          So now you are saying you do not need to know about the text/title after all??

                          SPlattenS Offline
                          SPlattenS Offline
                          SPlatten
                          wrote on last edited by
                          #36

                          @JonB , if its available but I can do it using an index...

                          Kind Regards,
                          Sy

                          1 Reply Last reply
                          0
                          • SPlattenS SPlatten

                            @J-Hilk , @JonB , @JoeCFD , This is the current issue or at least one issue:

                            The UI contained an instance of QTabWidget. This was set-up to contain the following tabs:

                            &Overall
                            C&2
                            &CGU
                            &LMS
                            &PDLT
                            &NLA
                            P&GU
                            &HCU
                            &UPSD
                            &Sensors
                            

                            In the XML file these tabs were defined with the class as QWidget I have edited the XML file and changed instances of QTabWidget to TabWidget and the tabs from QWidget to TabBar which matches the names of the new implementation I am trying to use.

                            However I'm not sure why or what I need to do in order to transfer the tabs from the UI into the class I am using so I can use the colours that the replacement class is going to allow?

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #37

                            @SPlatten said in QTabWidget, setting colour of tab itself ?:

                            I have edited the XML file and changed instances of QTabWidget to TabWidget and the tabs from QWidget to TabBar

                            class TabBar : public QTabBar

                            BTW, what is going on here? You confuse me (not for the first time!). A QTabWidget is supposed to have one QTabBar and a number of QWidgets for the widgets/contents/tabs of each page; one page per item in the tab bar. You have changed so that your QTabWidget has a QTabBar as each of its widgets/pages/tabs??

                            SPlattenS 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @SPlatten said in QTabWidget, setting colour of tab itself ?:

                              I have edited the XML file and changed instances of QTabWidget to TabWidget and the tabs from QWidget to TabBar

                              class TabBar : public QTabBar

                              BTW, what is going on here? You confuse me (not for the first time!). A QTabWidget is supposed to have one QTabBar and a number of QWidgets for the widgets/contents/tabs of each page; one page per item in the tab bar. You have changed so that your QTabWidget has a QTabBar as each of its widgets/pages/tabs??

                              SPlattenS Offline
                              SPlattenS Offline
                              SPlatten
                              wrote on last edited by SPlatten
                              #38

                              @JonB , to be honest, I'm confused by the implementation I have downloaded, I was looking online for an implementation that allows me to set the colours of the tabs and I found the source I'm using, this does appear to use a TabBar for each tab, please take a look at the source I posted in my earlier posts.

                              I'm looking at it again as I may have goofed it up.

                              Kind Regards,
                              Sy

                              JonBJ 1 Reply Last reply
                              0
                              • SPlattenS SPlatten

                                @JonB , to be honest, I'm confused by the implementation I have downloaded, I was looking online for an implementation that allows me to set the colours of the tabs and I found the source I'm using, this does appear to use a TabBar for each tab, please take a look at the source I posted in my earlier posts.

                                I'm looking at it again as I may have goofed it up.

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by
                                #39

                                @SPlatten
                                Nothing in https://stackoverflow.com/questions/46137500/qt-tabwidget-each-tab-title-background-color creates multiple QTabBars or changes the QWidgets which are the content/pages of each tab to themselves be QTabBars!

                                SPlattenS 2 Replies Last reply
                                0
                                • JonBJ JonB

                                  @SPlatten
                                  Nothing in https://stackoverflow.com/questions/46137500/qt-tabwidget-each-tab-title-background-color creates multiple QTabBars or changes the QWidgets which are the content/pages of each tab to themselves be QTabBars!

                                  SPlattenS Offline
                                  SPlattenS Offline
                                  SPlatten
                                  wrote on last edited by
                                  #40

                                  @JonB , no as I said I goofed up, looking at it again now.

                                  Kind Regards,
                                  Sy

                                  1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @SPlatten
                                    Nothing in https://stackoverflow.com/questions/46137500/qt-tabwidget-each-tab-title-background-color creates multiple QTabBars or changes the QWidgets which are the content/pages of each tab to themselves be QTabBars!

                                    SPlattenS Offline
                                    SPlattenS Offline
                                    SPlatten
                                    wrote on last edited by SPlatten
                                    #41

                                    @J.Hilk, @JonB , @JoeCFD, so I've finally got everything the way it should be and in my debug output I can see that various bits are being called, but it doesn't do what it is supposed to do, I'm not seeing the tabs in a different colour.

                                    The modified classes:

                                    typedef QMap<QString, QVariant> mpFaults;
                                    
                                    class TabBar : public QTabBar {
                                    private:
                                        mpFault* Faults_;
                                    
                                    protected:
                                        void paintEvent(QPaintEvent* evt) {
                                            int intTabs(count()), intPossibleFaults(Faults_->count());
                                            QStylePainter painter(this);
                                            QStyleOptionTab opt;
                                     const char* cpszLog((QString("TabBar::paintEvent: %1 possibleFaults:%2\r\n")
                                                              .arg(intTabs).arg(intPossibleFaults)).toLatin1().data());
                                    TabBar::logToFile(cpszLog);
                                            if ( intTabs > 0 && intPossibleFaults == 0 ) {
                                                for ( int intTab=0; intTab<intTabs; intTab++ ) {
                                                    QString strText(tabText(intTab));
                                                    Faults_->insert(strText, QVariant(false));
                                                }
                                            }
                                            for( int intTab=0; intTab<intTabs; intTab++ ) {
                                                initStyleOption(&opt, intTab);
                                    const char* cpszLog((QString("TabBar::tab: %1\r\n")
                                                  .arg(opt.text)).toLatin1().data());
                                    TabBar::logToFile(cpszLog);
                                                mpFaults::iterator itTab(Faults_->find(opt.text));
                                                if ( itTab != Faults_->end() ) {
                                                    QVariant varValue(itTab.value());
                                                    bool blnState(varValue.toBool());
                                    const char* cpszLog((QString("TabBar::blnState: %1\r\n")
                                                  .arg(blnState)).toLatin1().data());
                                    TabBar::logToFile(cpszLog);
                                                    if ( blnState == true ) {
                                    const char* cpszLog((QString("TabBar::ColourSet: %1\r\n")
                                                  . arg(kErrorColour)).toLatin1().data());
                                                        opt.palette.setColor(QPalette::Button, QColor(kErrorColour));
                                                    }
                                                }
                                                painter.drawControl(QStyle::CE_TabBarTabShape, opt);
                                                painter.drawControl(QStyle::CE_TabBarTabLabel, opt);
                                            }
                                        }
                                    public:
                                        static void logToFile(const char* cpszMsg) {
                                            FILE* fp(fopen("/usr/local/cgu/paint.txt", "at"));
                                            if ( fp ) {
                                                fputs(cpszMsg, fp);
                                                fclose(fp);
                                            }
                                        } 
                                        TabBar(QWidget* pParent = 0) : QTabBar(pParent) {
                                    TabBar::logToFile("TabBar::TabBar!!\r\n");
                                            Faults_ = new mpFaults();
                                        }
                                        bool setFault (QString& strText, bool blnState) {
                                            mpFaults::iterator itTab(Faults_->find(strText));
                                    const char* cpszLog((QString("TabBar::setFault(%1,%2)\r\n")
                                                    .arg(strText).arg(blnState)).toLatin1().data());
                                    TabBar::logToFile(cpszLog);
                                            if ( itTab != Faults_->end() ) {
                                                itTab.value() = QVariant(blnState);
                                                return true;
                                            }
                                            return false;
                                        }
                                    };
                                    
                                    class TabWidget : public QTabWidget {
                                    public:
                                        TabWidget(QWidget* pParent = 0) : QTabWidget(pParent) {
                                            setTabBar(new TabBar());
                                        }
                                        bool setFault(QString& strText, bool blnState) {
                                            TabBar* pTabBar(dynamic_cast<TabBar*>(tabBar()));
                                            if ( pTabBar ) {
                                                return pTabBar->setFault(strText, blnState);
                                            }
                                            return false;
                                        }
                                    };
                                    

                                    I see all the various debug messages in the log file, but tab is not showing as red which is the string literal assigned to kErrorColour:

                                    const char_t kErrorColour[] = "red";
                                    

                                    Logged to file:

                                    TabBar::paintEvent: 10 possibileFaults:10
                                    TabBar::tab: &Overall
                                    TabBar::blnState: 1
                                    TabBar::ColourSet: red
                                    

                                    Kind Regards,
                                    Sy

                                    1 Reply Last reply
                                    0
                                    • JoeCFDJ Offline
                                      JoeCFDJ Offline
                                      JoeCFD
                                      wrote on last edited by
                                      #42

                                      You really want to add flashing icons to the tabs or simply change their colors?

                                      SPlattenS 1 Reply Last reply
                                      0
                                      • JoeCFDJ JoeCFD

                                        You really want to add flashing icons to the tabs or simply change their colors?

                                        SPlattenS Offline
                                        SPlattenS Offline
                                        SPlatten
                                        wrote on last edited by
                                        #43

                                        @JoeCFD , changing the colour of the tab is the intention but it isn't working.

                                        Kind Regards,
                                        Sy

                                        1 Reply Last reply
                                        0
                                        • JoeCFDJ Offline
                                          JoeCFDJ Offline
                                          JoeCFD
                                          wrote on last edited by JoeCFD
                                          #44

                                          You can not change it with style sheet? My suggestion for you was to flash the icons on the tabs.

                                          SPlattenS 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved