【问题标题】:How to implement vertical tabs in QT?如何在 QT 中实现垂直制表符?
【发布时间】:2018-11-07 18:32:59
【问题描述】:

我正在尝试使用 QT 实现带有水平文本的垂直选项卡,但我在 QTabWidget 中找不到任何类似的选项。

SO 中有人要求类似here 的内容,但是,答案包含断开的链接,我怀疑它们是否提供了真正的解决方案。

有人能做到吗?

【问题讨论】:

    标签: c++ qt qt5 qtabwidget qtabbar


    【解决方案1】:

    您必须实现一个自定义的QTabBar 覆盖tabSizeHint()paintEvent() 方法,如下所示:

    #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();
    }
    

    【讨论】:

    • 嗨!我已经尝试了您的代码并得到:ibb.co/dVuuYd 然后我添加了this-&gt;setStyleSheet("QTabBar::tab {width: 115px; height: 30px; color: #000000; font-weight: bold; font-size: 10px;"); 以使其更大。我得到文本垂直:ibb.co/gJqMeJ 你如何设置选项卡的大小,所以文本是水平的?谢谢。
    • @Cobra91151 使用"QTabBar::tab {height: 115px; width: 30px; color: #000000; font-weight: bold; font-size: 10px;}"
    • 是的,我明白了。我已经更改了代码this-&gt;setStyleSheet("QTabBar::tab {height: 115px; width: 30px; color: #000000; font-weight: bold; font-size: 10px;}");,但现在我得到了:ibb.co/nGZWwy
    • 我已通过在 paintEvent 方法代码之后将 QTabBar::paintEvent(event); 更改为 QWidget::paintEvent(event); 来修复它。现在可以了:ibb.co/j8rN3d 谢谢。
    • 我的代码和你的混合在一起。现在问题解决了。谢谢。
    【解决方案2】:

    所以我解决这个样式问题的解决方案是:

    代码:

    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()
    {
    
    }
    

    现在是最后一部分:

    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")
    }
    

    结果:

    现在一切正常。

    【讨论】:

      【解决方案3】:

      PyQt5 解决方案

      对于PyQt5,解决方案是这样的(将@ellyanesc 的回复从C++ 翻译成Python):

      from __future__ import annotations
      from typing import *
      import sys
      from PyQt5.QtWidgets import *
      from PyQt5.QtCore import *
      from PyQt5.QtGui import *
      
      class VTabBar(QTabBar):
          def __init__(self, *args, **kwargs) -> None:
              super().__init__(*args, **kwargs)
              return
      
          def tabSizeHint(self, index:int) -> QSize:
              s = super().tabSizeHint(index)
              s.transpose()
              return s
      
          def paintEvent(self, event:QPaintEvent) -> None:
              painter:QStylePainter = QStylePainter(self)
              opt:QStyleOptionTab = QStyleOptionTab()
              for i in range(self.count()):
                  self.initStyleOption(opt, i)
                  painter.drawControl(QStyle.CE_TabBarTabShape, opt)
                  painter.save()
      
                  s:QSize = opt.rect.size()
                  s.transpose()
                  r:QRect = QRect(QPoint(), s)
                  r.moveCenter(opt.rect.center())
                  opt.rect = r
      
                  c:QPoint = self.tabRect(i).center()
                  painter.translate(c)
                  painter.rotate(90)
                  painter.translate(-c)
                  painter.drawControl(QStyle.CE_TabBarTabLabel, opt)
                  painter.restore()
              return
      
      class VTabWidget(QTabWidget):
          def __init__(self, parent:QWidget=None) -> None:
              super().__init__(parent)
              self.setTabBar(VTabBar())
              self.setTabPosition(QTabWidget.West)
              return
      
      if __name__ == '__main__':
          app = QApplication(sys.argv)
          QApplication.setStyle(QStyleFactory.create('Plastique'))
          w = VTabWidget()
          w.addTab(QWidget(), 'tab1')
          w.addTab(QWidget(), 'tab2')
          w.addTab(QWidget(), 'tab3')
          w.show()
          sys.exit(app.exec_())
      

      【讨论】:

        猜你喜欢
        • 2011-11-06
        • 2016-03-29
        • 1970-01-01
        • 2016-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-26
        • 2014-03-30
        相关资源
        最近更新 更多