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.
来源:https://stackoverflow.com/questions/50578661/how-to-implement-vertical-tabs-in-qt