I am trying to implement vertical tabs with horizontal text with QT but I cannot find any similar option in QTabWidget.
Somebody in SO asked for something similar here, however, the answers contain broken links and I doubt that they present a real solution.
Anybody has been able to do that?
You have to implement a custom QTabBar
overwriting the tabSizeHint()
and paintEvent()
methods as shown below:
#include <QApplication>
#include <QStyleOptionTab>
#include <QStylePainter>
#include <QTabBar>
#include <QTabWidget>
class TabBar: public QTabBar{
public:
QSize tabSizeHint(int index) const{
QSize s = QTabBar::tabSizeHint(index);
s.transpose();
return s;
}
protected:
void paintEvent(QPaintEvent * /*event*/){
QStylePainter painter(this);
QStyleOptionTab opt;
for(int i = 0;i < count();i++)
{
initStyleOption(&opt,i);
painter.drawControl(QStyle::CE_TabBarTabShape, opt);
painter.save();
QSize s = opt.rect.size();
s.transpose();
QRect r(QPoint(), s);
r.moveCenter(opt.rect.center());
opt.rect = r;
QPoint c = tabRect(i).center();
painter.translate(c);
painter.rotate(90);
painter.translate(-c);
painter.drawControl(QStyle::CE_TabBarTabLabel,opt);
painter.restore();
}
}
};
class TabWidget : public QTabWidget
{
public:
TabWidget(QWidget *parent=0):QTabWidget(parent){
setTabBar(new TabBar);
setTabPosition(QTabWidget::West);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TabWidget w;
w.addTab(new QWidget, "tab1");
w.addTab(new QWidget, "tab2");
w.addTab(new QWidget, "tab3");
w.show();
return a.exec();
}
So my solution to fix this styling issue is:
Code:
apptabbar.h
#ifndef APPTABBAR_H
#define APPTABBAR_H
#include <QTabBar>
#include <QStylePainter>
#include <QStyleOptionTab>
class AppTabBar : public QTabBar
{
public:
AppTabBar();
AppTabBar(int tabWidth, int tabHeight);
AppTabBar(QSize tabSize);
AppTabBar(QWidget *parent);
AppTabBar(QWidget *parent, int tabWidth, int tabHeight);
AppTabBar(QWidget *parent, QSize tabSize);
QSize tabSizeHint(int index) const override;
~AppTabBar();
protected:
void paintEvent(QPaintEvent *event) override;
private:
int width, height;
};
#endif // APPTABBAR_H
apptabbar.cpp
#include "apptabbar.h"
AppTabBar::AppTabBar() : QTabBar(),
width(30),
height(115)
{
}
AppTabBar::AppTabBar(int tabWidth, int tabHeight) : QTabBar(),
width(tabWidth),
height(tabHeight)
{
}
AppTabBar::AppTabBar(QSize tabSize) : QTabBar(),
width(tabSize.width()),
height(tabSize.height())
{
}
AppTabBar::AppTabBar(QWidget *parent) : QTabBar(parent),
width(30),
height(115)
{
}
AppTabBar::AppTabBar(QWidget *parent, int tabWidth, int tabHeight) : QTabBar(parent),
width(tabWidth),
height(tabHeight)
{
}
AppTabBar::AppTabBar(QWidget *parent, QSize tabSize) : QTabBar(parent),
width(tabSize.width()),
height(tabSize.height())
{
}
AppTabBar::~AppTabBar()
{
}
QSize AppTabBar::tabSizeHint(int index) const
{
QSize s = QTabBar::tabSizeHint(index);
s.setWidth(width);
s.setHeight(height);
s.transpose();
return s;
}
void AppTabBar::paintEvent(QPaintEvent *event)
{
QStylePainter painter(this);
QStyleOptionTab opt;
for (int i = 0; i < this->count(); i++) {
initStyleOption(&opt, i);
painter.drawControl(QStyle::CE_TabBarTabShape, opt);
painter.save();
QSize s = opt.rect.size();
s.transpose();
QRect r(QPoint(), s);
r.moveCenter(opt.rect.center());
opt.rect = r;
QPoint c = tabRect(i).center();
painter.translate(c);
painter.rotate(90);
painter.translate(-c);
painter.drawControl(QStyle::CE_TabBarTabLabel, opt);
painter.restore();
}
QWidget::paintEvent(event);
}
apptabcontrol.h
#ifndef APPTABCONTROL_H
#define APPTABCONTROL_H
#include <QTabWidget>
#include <QTabBar>
#include <QPalette>
#include <QPainter>
#include <QDebug>
#include "apptabbar.h"
class AppTabControl : public QTabWidget
{
public:
AppTabControl();
AppTabControl(QWidget *parent);
AppTabControl(QWidget *parent, int width, int height);
AppTabControl(QWidget *parent, QSize size);
void setTabControlSize(int width, int height);
void setTabControlSize(QSize tabSize);
~AppTabControl();
private:
int tabWidth, tabHeight;
QSize tabSize;
};
#endif // APPTABCONTROL_H
apptabcontrol.cpp
#include "apptabcontrol.h"
AppTabControl::AppTabControl()
{
}
AppTabControl::AppTabControl(QWidget *parent) : QTabWidget(parent)
{
this->setTabBar(new AppTabBar(parent, tabWidth, tabHeight));
this->setTabPosition(QTabWidget::West);
}
AppTabControl::AppTabControl(QWidget *parent, int width, int height) : QTabWidget(parent),
tabWidth(width),
tabHeight(height)
{
this->setTabBar(new AppTabBar(parent, tabWidth, tabHeight));
this->setTabPosition(QTabWidget::West);
}
AppTabControl::AppTabControl(QWidget *parent, QSize size) : QTabWidget(parent),
tabSize(size)
{
this->setTabBar(new AppTabBar(parent, tabSize));
this->setTabPosition(QTabWidget::West);
}
void AppTabControl::setTabControlSize(int width, int height)
{
tabWidth = width;
tabHeight = height;
}
void AppTabControl::setTabControlSize(QSize size)
{
tabSize = size;
}
AppTabControl::~AppTabControl()
{
}
And now the final part:
Test::Test(QWidget *parent) :
QWidget(parent),
ui(new Ui::Test)
{
AppTabControl *tabControl = new AppTabControl(this, 30, 115);
this->setStyleSheet("QTabBar::tab {color: #000000; font-weight: bold; font-size: 10px; font-family: Gotham, Helvetica Neue, Helvetica, Arial, sans-serif;} "
"QTabBar::tab:selected {background-color: #FA9944; color: #000000; border-top: 1px solid #FA9944;} "
"QTabBar::tab:hover {color: #000000; border-top: 1px solid #FA9944; background-color: #FFFFFF;}");
AppTabBar *tabBar1 = new AppTabBar(tabControl);
AppTabBar *tabBar2 = new AppTabBar(tabControl);
AppTabBar *tabBar3 = new AppTabBar(tabControl);
tabControl->addTab(tabBar1, "Tab1");
tabControl->addTab(tabBar2, "Tab2");
tabControl->addTab(tabBar3, "Tab3")
}
The result:
Everything works well now.