• 23797阅读
  • 5回复

关于QTabWidget中的TabBar在左边Text水平显示 [复制链接]

上一主题 下一主题
离线notton
 

只看楼主 倒序阅读 楼主  发表于: 2010-11-05
— 本帖被 XChinux 执行加亮操作(2010-11-05) —
QT中Example/dialogs/tabdialog下有一个QTabWidget ,把它的风格改成:tabWidget->setTabPosition(QTabWidget::West);
希望做成下面类似的效果:


但它存在一个问题,就是文字显示是竖着排列的,查了一下资料,发现在网上也有不少人问。目前自己也没有解决,现在把当前做到的代码放出来,希望有人能在这基础上改进一下。
当前主要还存在两个比较大的问题:
1。TabBar右边显示的内容,也就晨QStackWidget中的位置如何调整。.
2。TabBar高度如何调整。

代码是参考一个老外的:(GPL内容就不贴了)
HorusStyle.h:
#ifndef                __HORUSSTYLE_H__
# define            __HORUSSTYLE_H__

# include            <QPlastiqueStyle>
# include            <QString>

class                HorusStyle : public QPlastiqueStyle
{
public:
    int            pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
    void            drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const;
    QRect            subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const;
};

#endif

HorusStyle.cpp:

#include    "HorusStyle.h"

#include    <QStyleOptionTab>
#include    <QPainter>

int    HorusStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
{
    if (metric == QStyle::PM_DockWidgetSeparatorExtent)
        return (2);
    return (QPlastiqueStyle::pixelMetric(metric, option, widget));
}

void HorusStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *widget) const
{
    switch (element)
    {
    case CE_TabBarTabLabel:
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
            QStyleOptionTabV3 tabV2(*tab);
            QRect tr = tabV2.rect;
            if (tabV2.shape != QTabBar::TriangularWest && tabV2.shape != QTabBar::TriangularNorth)
            //if (tabV2.shape != QTabWidget::West && tabV2.shape != QTabBar::TriangularNorth)
            {
                QPlastiqueStyle::drawControl(element, opt, p, widget);
                break;
            }
            bool verticalTabs = tabV2.shape == QTabBar::RoundedEast
                                || tabV2.shape == QTabBar::RoundedWest
                                || tabV2.shape == QTabBar::TriangularEast
                                || tabV2.shape == QTabBar::TriangularWest;

            int alignment;
            if (verticalTabs)
                alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
            else
                alignment = Qt::AlignLeft | Qt::TextShowMnemonic;
            if (!styleHint(SH_UnderlineShortcut, opt, widget))
                alignment |= Qt::TextHideMnemonic;

            if (verticalTabs) {
                p->save();
                int newX, newY, newRot;
                if (tabV2.shape == QTabBar::RoundedEast || tabV2.shape == QTabBar::TriangularEast) {
                    newX = tr.width() + tr.x();
                    newY = tr.y();
                    newRot = 90;
                } else {
                    newX = tr.x();
                    newY = tr.y() +  (tabV2.shape == QTabBar::TriangularWest ? 0 : tr.height());
                    newRot = tabV2.shape == QTabBar::TriangularWest ? 0 : -90;
                }
                QTransform m;
                m.translate(newX, newY);
                m.rotate(newRot);
                p->setTransform(m, true);
            }
            tr = subElementRect(SE_TabBarTabText, opt, widget);

            if (!tabV2.icon.isNull()) {
                QSize iconSize;
                int iconExtent;
                if (tabV2.shape == QTabBar::TriangularWest)
                    iconExtent = 32;
                else if (tabV2.shape == QTabBar::TriangularNorth)
                    iconExtent = 24;
                iconSize = QSize(iconExtent, iconExtent);
                QSize tabIconSize = tabV2.icon.actualSize(iconSize,
                                                          (tabV2.state & State_Enabled) ? QIcon::Normal
                                                          : QIcon::Disabled);
                QPixmap tabIcon = tabV2.icon.pixmap(iconSize,
                                                    (tabV2.state & State_Enabled) ? QIcon::Normal
                                                                                  : QIcon::Disabled);

                int offset = 4;
                int left = opt->rect.left();
                if (tabV2.leftButtonSize.isEmpty())
                    offset += 2;
                else
                    left += tabV2.leftButtonSize.width() + (6 + 2) + 2;
                QRect iconRect = QRect(left + offset, tr.center().y() - tabIcon.height() / 2,
                            tabIconSize.width(), tabIconSize.height());
                if (tabV2.shape == QTabBar::TriangularWest)
                    iconRect = QRect(tr.center().x() - tabIcon.width() / 2, 10, tabIconSize.width(), tabIconSize.height());
                else if (tabV2.shape == QTabBar::TriangularNorth)
                    iconRect = QRect(4, tr.center().y() - tabIcon.height() / 2,  tabIconSize.width(), tabIconSize.height());
                if (!verticalTabs)
                    iconRect = visualRect(opt->direction, opt->rect, iconRect);
                p->drawPixmap(tabV2.rect.left() + iconRect.x(), iconRect.y(), tabIcon);
            }

            //tr.moveLeft(tabV2.rect.left() + 64);
            //tr.moveTop(tr.top() - 20);
            drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text, QPalette::WindowText);
            if (verticalTabs)
                p->restore();

            if (tabV2.state & State_HasFocus) {
                const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth);

                int x1, x2;
                x1 = tabV2.rect.left();
                x2 = tabV2.rect.right() - 1;

                QStyleOptionFocusRect fropt;
                fropt.QStyleOption::operator=(*tab);
                fropt.rect.setRect(x1 + 1 + OFFSET, tabV2.rect.y() + OFFSET,
                                   x2 - x1 - 2*OFFSET, tabV2.rect.height() - 2*OFFSET);
                drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
            }
        }
        break;
    default:
        QPlastiqueStyle::drawControl(element, opt, p, widget);
    }
}

QRect HorusStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const
{
    QRect r;
    switch (sr)
    {
    case SE_TabBarTabText:
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
            QStyleOptionTabV3 tabV2(*tab);
            QRect tr = tabV2.rect;
            bool verticalTabs = tabV2.shape == QTabBar::RoundedEast
                                || tabV2.shape == QTabBar::RoundedWest
                                || tabV2.shape == QTabBar::TriangularEast
                                || tabV2.shape == QTabBar::TriangularWest;
            if (tabV2.shape == QTabBar::TriangularWest)
                tr.setRect(0, 0, tr.width(), tr.height());
            else if (verticalTabs)
                tr.setRect(0, 0, tr.height(), tr.width());
            int verticalShift = pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget);
            int horizontalShift = pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget);
            if (tabV2.shape == QTabBar::RoundedSouth || tabV2.shape == QTabBar::TriangularSouth)
                verticalShift = -verticalShift;
            tr.adjust(0, 0, horizontalShift, verticalShift);
            bool selected = tabV2.state & State_Selected;
            if (selected) {
                tr.setBottom(tr.bottom() - verticalShift);
                tr.setRight(tr.right() - horizontalShift);
            }

            // left widget
            if (!tabV2.leftButtonSize.isEmpty()) {
                tr.setLeft(tr.left() + 6 + 2 +
                    (verticalTabs ? tabV2.leftButtonSize.height() : tabV2.leftButtonSize.width()));
            }

            // icon
            if (!tabV2.icon.isNull()) {
                QSize iconSize = tabV2.iconSize;
                if (!iconSize.isValid()) {
                    int iconExtent = pixelMetric(PM_SmallIconSize);
                    iconSize = QSize(iconExtent, iconExtent);
                }
                QSize tabIconSize = tabV2.icon.actualSize(iconSize,
                                                          (tabV2.state & State_Enabled) ? QIcon::Normal
                                                          : QIcon::Disabled);
                int offset = 4;
                if (tabV2.leftButtonSize.isEmpty())
                    offset += 2;

                QRect iconRect = QRect(tr.left() + offset, tr.center().y() - tabIconSize.height() / 2,
                            tabIconSize.width(), tabIconSize .height());
                if (!verticalTabs)
                    iconRect = visualRect(opt->direction, opt->rect, iconRect);
                if (tabV2.shape == QTabBar::TriangularWest)
                {
                    tr.setTop(5);
                    tr.setBottom(20);
                    tr.setLeft(2);
                    tr.setRight(188);
                    return (tr);
                }
                else if (tabV2.shape == QTabBar::TriangularNorth)
                {
                    tr.setTop(9);
                    tr.setBottom(19);
                    tr.setLeft(tr.left() + 32);
                    tr.setRight(tr.left() + 118);
                    return (tr);
                }
            }
            else if (tabV2.shape == QTabBar::TriangularWest)
            {
                tr.setTop(5);
                tr.setBottom(30);
                tr.setLeft(2);
                 tr.setRight(188);
                return (tr);
            }
            else if (tabV2.shape == QTabBar::TriangularNorth)
            {
                tr.setTop(9);
                tr.setBottom(19);
                tr.setLeft(tr.left() + horizontalShift + 4);
                tr.setRight(tr.left() + 118);
                return (tr);
            }

            // right widget
            if (!tabV2.rightButtonSize.isEmpty()) {
                tr.setRight(tr.right() - 6 - 2 -
                    (verticalTabs ? tabV2.rightButtonSize.height() : tabV2.rightButtonSize.width()));
            }

            if (!verticalTabs)
                tr = visualRect(opt->direction, opt->rect, tr);
            r = tr;
        }
        break;
    default:
        return QPlastiqueStyle::subElementRect(sr, opt, widget);
    }
    return r;
}

ImTabDialog::ImTabDialog(QWidget *parent)
: QTabWidget(parent)
{
    setTabPosition(QTabWidget::West);
    m_tabBar = new QTabBar(this);
    m_tabBar->setFixedWidth(128);
    m_tabBar->setShape(QTabBar::TriangularWest);
    setTabBar(m_tabBar);
}

把tabdialog样例中的QtabWidget改成ImTabWidget

最近调用:
tabdialog样例加一句即可
#include <QApplication>

#include "horusStyle.h"
#include "tabdialog.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QString fileName;

    if (argc >= 2)
        fileName = argv[1];
    else
        fileName = ".";
       app.setStyle(new HorusStyle());
    TabDialog tabdialog(fileName);
    return tabdialog.exec();
}

[ 此帖被notton在2010-11-05 15:31重新编辑 ]
c++ dev
离线water_wf

只看该作者 1楼 发表于: 2010-11-05
能上传整个工程吗,贴代码太乱了
离线notton

只看该作者 2楼 发表于: 2010-11-05
可以
附件: HorusStyle.zip (11 K) 下载次数:239
c++ dev
离线notton

只看该作者 3楼 发表于: 2010-11-09
c++ dev
离线wussup

只看该作者 4楼 发表于: 2017-03-13
1. 能否更新到Qt 5?
2. 在Qt creator中找了下qtabdialog 样例  没找到  不知道是否在其他地方可以找到, 能否把样例代码也贴出来?
3. 谢谢
离线767864513

只看该作者 5楼 发表于: 2018-03-15
正好需要改变tab的字体的方向,学习下
快速回复
限100 字节
 
上一个 下一个