QTabWidget, setting colour of tab itself ?
-
@SPlatten said in QTabWidget, setting colour of tab itself ?:
mainly because its a lot of backtracking and changes
No it's not. It would take you 5 minutes to paste that code into a tiny, new, standalone program to test whether it works for you or not. You could have done it in the time it took you to answer that you didn't want to do it. You seem to spend a lot of time posting questions you want help with and pasting loads of your own code and expecting others to spend time to spot what is wrong, but are very resistant to simplifying and testing yourself. Not to mention, half the time you end up saying it was something else in your code what caused whatever problem which we have not even been shown.
If you don't want to do that, best of luck getting someone to spot what might be wrong in your code. Then either:
-
It does work, and your "mine does almost exactly the same" is then clearly not similar enough, and you can discover why; or
-
It does not work at all for you, standalone, not with your own code changes. In which case I will start by asking you whether you took the time to read the Comments to the SO post, as I did, and how you respond to:
Seen, It no effect in window's system...
so the solution is add a.setStyle("fusion"); to main.cpp. thanks
-
-
@JonB , did you see the edit to my post before you posted?
I am creating a simple application using the original code.
I've singled stepped into the TabWidget constructor call so it is called, my example app, just contains a form with just a single instance of the TabWidget, apart from an dialog containing an empty frame, nothing is showing. No tabs at all.
-
@JonB , main.cpp:
int main(int argc, char* argv[]) { QApplication a(argc, argv); MainWndow w; w.show(); return a.exec(); }
mainwindow.h:
#ifndef MAINWINDOW_H #defiine MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui:MainWindow* ui; }; #endif //MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; }
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindo"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>718</width> <height>496</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralWidget"> <widget class="TagWidget" name="tabWidget" native="true"> <property name="geometry"> <rect> <x>40</x> <y>50</y> <width>561</width> <height>331</height> </rect> </property> <property name="sizePolicy"> <sizePolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizePolicy> </property> <property name="maximumSize"> <size> <width>701</width> <height>491</height> </size> </property> </widget> </widget> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> <customwidget> <class>TagWidget</class> <extends>QTabWidget</extends> <header>tabwidget.h</header> <container>1</container> </customwidget> </customwidgets> <resources/> <connecitons/> </ui>
QT += core gui greaterThaan(QT|_MAJOR_VERSION, 4): QT += widgets TARGET = test TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp HEADERS += mainwindow.h \ tagwidget.h FORMS += mainwindow.ui
I haven't posted tabwidget.h as its identical to the stack overflow post.
-
-
@SPlatten said in QTabWidget, setting colour of tab itself ?:
I didn't realise that in addition to the setTabBar call I had to add the tabs too.
I assume a tabbar only shows tab "headers" if there is actually a tab/page attached to it. Else what would be the point/clicking on it do?
Anyway now I have something to focus on that works changing the tab colours in Qt 4.8.
:)
-
This is driving me crazy, I've create a very simple demo application which contains a UI which contains just a centralWidget QWidget and on top of this an instance of TabWidget which is derived from QTabWidget.
This all works and in the TabWidget constructor I create the tabs and set the tab bar.
Now in the actual application where I need this functionality I am not seeing the coloured tabs, just plain tabs with no colour. In the log file it contains:
TabBar::paintEvent: 10 possibleFaults:10 TabBar::blnState[0]:&Overall:1 TabBar::ColourSet: red
The code that produces this:
void paintEvent(QPaintEvent* pEvt) { Q_UNUSED(pEvt); int intTabs(count()), intPossibleFaults(Faults_->count()); if ( intTabs == 0 ) { //Nothing to do! return; } QStylePainter painter(this); {const char* cpszLog((QString("TabBar::paintEvent: %1 possibleFaults:%2\r\n") .arg(intTabs).arg(intPossibleFaults)).toLatin1().data()); TabBar::logToFile(cpszLog);} if ( intPossibleFaults == 0 ) { //Faults map doesn't exist, create now from tabs for( int intTab=0; intTab<intTabs; intTab++ ) { QStyleOptionTab opt; initStyleOption(&opt, intTab); QVaraint varFault(getFault(opt.text)); if ( varFault.isValue() != true ) { {const char* cpszLog((QString("TabBar::NOT FOUND[%1]\r\n") .arg(opt.text)).toLatin1().data()); TabBar::logToFile(cpszLog);} continue; } bool blnState(varFault.toBook()); {const char* cpszLog((QString("TabBar::blnState[%1]:%2:%3\r\n") .arg(intTab).arg(opt.text).arg(blnState)).toLatin1().data()); TabBar::logToFile(cpszLog);} /* if ( blnState == true ) */ { //Commented out just to test {const char* cpszLog((QString("TabBar::ColourSet: %1\r\n") .arg(kErrorColour)).toLatin1().data()); TabBar::logToFile(cpszLog);} opt.palette.setColor(QPalette::Button, QColor(kErrorColour)); } painter.drawControl(QStyle::CE_TabBarTabShape, opt); painter.drawControl(QStyle::CE_TabBarTabLabel, opt); } }
In the test code the tabs appear in different colours, but in the actual application using the above code the tabs do not appear in any colours.
-
@SPlatten said in QTabWidget, setting colour of tab itself ?:
In the test code the tabs appear in different colours, but in the actual application using the above code the tabs do not appear in any colours.
Then how can anyone know what differs in your actual application from the test code?
Do you use stylesheets in your actual app? Do you use an overall style (like "fusion")?
-
Source from working test code:
class TabBar : public QTabBar { private: QHash<QString, QColor> mColors; public: void paintEvent(QPaintEvent* pEvt) { Q_UNUSED(pEvt); QStylePainter painter(this); for( int i=0; i<count(); i++ ) { QStyleOptionTab opt; initStyleOption(&opt, i); if ( mColors.contains(opt.text)) { QColor color(mColors[opt.text]); opt.palette.setColor(QPalette::Button, color); } painter.drawControl(QStyle::CE_TabBarTabShape, opt); painter.drawContorl(QStyle::CE_TabBarTabLabel, opt); } } public: TabBar(const QHash<QString, QColor>& colors, QWidget* parent = 0) : QTabBar(parent) { mColors = colors; } } class TabWidget : public QTabWidget { public: TabWidget(QWidget* parent = 0) : QTabWidget(parent) { QStringList slstColours, slstTabs; slstColours << "#000000" << "#ff0000" << "#00ff00" << "#0000ff" << "#00ffff" << "#fff00" << "#ffffff"; slstTabs << "All" << "Simon" << "Susan" << "Lewis" << "Jordan" << "Oliver" << "Georgia"; QHash<QString, QColor> dict; for( int intPass=1; intPass<=2; intPass++ ) { for( int intIdx=0; intIdx<slstColours.length(); intIdx++ ) { QString strColour(slstColours[intIdx]), strTab(slstTabs[intIdx]); if ( intPass == 1 ) { dict[strTab] = QColor(strColour); } else { this->addTab(new QWidget(), strTab); } } if ( intPass == 1 ) { setTabBar(new TabBar(dict)); } } } };
-
@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.
-
@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.