QTabWidget, setting colour of tab itself ?
-
@JonB , @JoeCFD , I have finally realised what is different between the working code and the project that doesn't work.
In the project that doesn't work the tabs are already set-up in the UI so there is no call in code to setTabBar after adding the tabs.
What is the correct way to fix this so the project which has the tabs in the UI will work? I cannot simply discard the UI as each tab has many controls defined.
-
@JonB , @JoeCFD , I have finally realised what is different between the working code and the project that doesn't work.
In the project that doesn't work the tabs are already set-up in the UI so there is no call in code to setTabBar after adding the tabs.
What is the correct way to fix this so the project which has the tabs in the UI will work? I cannot simply discard the UI as each tab has many controls defined.
@SPlatten https://doc.qt.io/qt-5/qtabwidget.html#setTabBar
Replaces the dialog's QTabBar heading with the tab bar tb. Note that this must be called before any tabs have been added, or the behavior is undefined.You have to customize qtabwidget and drop ui file for qtabwidget in the project completely. Manually create a qtabwidget. But you can copy most contents from ui_*** for that qtabwidget.
-
I have the line:
TabWidget* pTabWidget(qobject_cast<TabWidget*>(ui->tab_widget));
This results in the compiler messages for this line:
qobject.h:378:5: instantiated from 'T qobject_cast(QObject*) [with T = cgu::vip::TabWidget*]' ws_status_page.cc:388:67: instantiaged from here /usr/include/qt4/QtGui/qtabwidget.h:62:5: error: void value not igored as it ought to be
None of the above make any sense to me....line 388 is the line I posted.
[Edit] Replaced line with:
TabWidget* pTabWidget(reinterpret_cast<TabWidget*>(ui->tab_widget));
Message has gone, will deploy and test.
-
I have the line:
TabWidget* pTabWidget(qobject_cast<TabWidget*>(ui->tab_widget));
This results in the compiler messages for this line:
qobject.h:378:5: instantiated from 'T qobject_cast(QObject*) [with T = cgu::vip::TabWidget*]' ws_status_page.cc:388:67: instantiaged from here /usr/include/qt4/QtGui/qtabwidget.h:62:5: error: void value not igored as it ought to be
None of the above make any sense to me....line 388 is the line I posted.
[Edit] Replaced line with:
TabWidget* pTabWidget(reinterpret_cast<TabWidget*>(ui->tab_widget));
Message has gone, will deploy and test.
-
@SPlatten
Doesn't theqobject_cast
indicate it is not aTabWidget*
, and usingreinterpret_cast
makes it compile by lying to it?line 388 is the line I posted.
You have posted hundreds of lines. Which one is 388?
-
@JonB the item I am casting from the UI is a TabWidget and the line I posted as I said in my post is line 388. From the UI file:
<widget class="TabWidget" name="tab_widget">
-
I have the line:
TabWidget* pTabWidget(qobject_cast<TabWidget*>(ui->tab_widget));
This results in the compiler messages for this line:
qobject.h:378:5: instantiated from 'T qobject_cast(QObject*) [with T = cgu::vip::TabWidget*]' ws_status_page.cc:388:67: instantiaged from here /usr/include/qt4/QtGui/qtabwidget.h:62:5: error: void value not igored as it ought to be
None of the above make any sense to me....line 388 is the line I posted.
[Edit] Replaced line with:
TabWidget* pTabWidget(reinterpret_cast<TabWidget*>(ui->tab_widget));
Message has gone, will deploy and test.
@SPlatten said in QTabWidget, setting colour of tab itself ?:
Message has gone, will deploy and test.
I think that error message is due to the initialisation you choose.
Use assignment initialisation instead:TabWidget* pTabWidget = qobject_cast<TabWidget*>(ui->tab_widget);
from what I can tell, the cast isn't needed at all, seems like
ui->tab_widget
is a TabWidget-Pointer in the first place -
@SPlatten said in QTabWidget, setting colour of tab itself ?:
Message has gone, will deploy and test.
I think that error message is due to the initialisation you choose.
Use assignment initialisation instead:TabWidget* pTabWidget = qobject_cast<TabWidget*>(ui->tab_widget);
from what I can tell, the cast isn't needed at all, seems like
ui->tab_widget
is a TabWidget-Pointer in the first place@J-Hilk said in QTabWidget, setting colour of tab itself ?:
from what I can tell, the cast isn't needed at all, seems like ui->tab_widget is a TabWidget-Pointer in the first place
Indeed that is the point, so
reinterpret_cast
should not be necessary andqobject_cast
should work (or be made to work as you said). -
@JoeCFD , @JonB , @J-Hilk , I have created very simple test application to test my TabWidget class. I have tried to replicate the project I want to use this functionality in as much as possible, a snippet from the UI:
<widget class="TabWidget" name="tab_widget"> <property name="font"> <font> <pointsize>12</pointsize> <weight>75</weight> <bold>true</bold> </font> </property> <property name="currentIndex"> <number>0</number> </property> <widget class="QWidget" name="overall_tab"> <property name="focusPolicy"> <enum>Qt::TabFocus</enum> </property> <attribute name="title"> <string>&Overall</string> </attribute> <layout class="QGridLayout" name="gridLayout_23"> <item row="0" column="0"> <widget class="QFrame" name="overall_frame">
Unfortunately I am not able to get the entire file to post as the development system is locked down. In my test project everything works find and I am able to change the colour of the tab which I do with:
void paintEvent(QPaintEvent* pEvt) { Q_UNUSED(pEvt); int intTabs(count()); if ( intTabs == 0 ) { return; } QStylePainter painter(this); for( int intTab=0; intTab<intTabs; intTab++ ) { QStyleOptionTab opt; initStyleOption(&opt, intTab); const char* cpszProperty(opt.text.toLatin1().data()); QVariant varProperty(property(cpszProperty)); if ( varProperty.isValid() == true ) { bool blnState(varProperty.toBool()); if ( blnState == true ) { QColor color(kErrorColour); opt.palette.setColor(QPalette::Button, color); } //Edit#1, Just add the 5 lines below, compiling and trying out QWidget* pTabButton(tabButton(intTab, QTabBar::LeftSide)); if ( pTabButton ) { pTabButton->setStyleSheet(QString("background-color: rgb(%1,%2,%3)") .arg(color.red()).arg(color.green()).arg(color.blue()); } } painter.drawControl(QStyle::CE_TabBarTabShape, opt); painter.drawControl(QStyle::CE_TabBarTabLabel, opt); } }
I can see that the loop is paintEvent is being called and it iterates through the loop with the colour being set, but the colour is not displayed.
The test application works perfectly, however the same code in the actual project does not.
Is there anything I can do to find out why it isn't working?
[Edit#2] Edit#1 didn't resolve anything, still doesn't work.
-
@JoeCFD , @JonB , @J-Hilk Still working on this...the current paintEvent function:
void paintEvent(QPaintEvent* pEvt) { Q_UNUSED(pEvt); int intTabs(count()); QStylePainter painter(this); for( int intTab=0; intTab<intTabs; intTab++ ) { QStyleOptionTab opt; initStyleOption(&opt, intTab); const char* cpszProperty(opt.text.toLatin1().data()); QVariant varProperty(property(cpszProperty)); bool blnValid(varProperty.isValid()); if ( blnValid == true ) { bool blnState(varProperty.toBool()); if ( blnState == true ) { QColor color(kErrorColour); if ( color.isValid() ) { opt.palette.setColor(QPalette::Button, color); } } } painter.drawControl(QStyle::CE_TabBarTabShape, opt); painter.drawControl(QStyle::CE_TabBarTabLabel, opt); } }
What I am seeing is that blnValid is always false and the text member in opt never matches any of the tabs. Why could this be?
In my test application the problem does not exist, so it has to be some I have failed to do.
-
@SPlatten said in QTabWidget, setting colour of tab itself ?:
QStyleOptionTab
opt.text is a qstring. Print it to the screen or use debugger to check its value. Then you can see if it is valid or not.
@JoeCFD , @JonB , @J-Hilk , I've progressed this to the point where it gets all the way to:
opt.palette.setColor(QPalette::Button, color);
I output the color to the log file and its valid and the name() returns #ff0000. But still the colour of the tab doesn't change, again in my standard alone test project it does the same and in this it works...so why doesn't it work here?
-
@JoeCFD , @JonB , @J-Hilk , I've progressed this to the point where it gets all the way to:
opt.palette.setColor(QPalette::Button, color);
I output the color to the log file and its valid and the name() returns #ff0000. But still the colour of the tab doesn't change, again in my standard alone test project it does the same and in this it works...so why doesn't it work here?
-
@SPlatten Make sure the same tabs are painted. Assign object names to the tabs when they are created. Check if the names are the same when they are painted.
-
@JoeCFD , I can see in the ui / XML file that each widget / tab has a name attribute. How do I go about checking if the names are the same when painted?
-
@SPlatten it is object name. https://doc.qt.io/qt-5/qobject.html#objectName-prop
-
@JoeCFD , thank you, I realise that but I was expecting the QStyleOptionTab to have some member that represents the tab object name, it doesn't, the only way I can think of doing this is to make the object name the same as the tab text ?
-
@SPlatten The better way to check it is to make sure the pointer addresses of your tabs are the same as the ones when they are created. Changing object names can not help anything. It is only one way for debug.
-
@JoeCFD , I'm not sure how this is going to help as only one set of tabs is displayed. I could try changing the text of any tab to see if that updates...if it does it doesn't explain why the colour doesn't change.
-
@JoeCFD said in QTabWidget, setting colour of tab itself ?:
@SPlatten Good idea. Try to change the texts to see if it works.
I've modified the code where it sets the colour to also change the tab text:
setTabText(intTab, "modified: " + tabText(intTab));
[Edit] With this code in place I can see that no tab text is modified, which makes me wonder what is going on, the tabs show the same as defined in the UI file, but it appears they aren't the same in that they cannot be modified???