3

This is the same question as in: How to change text alignment in QTabWidget?

I tried to port that python code into C++ but it doesn't seem to work.

Here is header file:

#include <QTabBar>

class HorizontalTabWidget : public QTabBar
{
    Q_OBJECT
public:
    explicit HorizontalTabWidget(QWidget *parent = 0);

protected:
    void paintEvent(QPaintEvent *);
    QSize sizeHint() const;
};

Here is source file:

void HorizontalTabWidget::paintEvent(QPaintEvent *)
{
    for(int index = 0; index < count(); index++)
    {
        QPainter * painter = new QPainter(this);
        painter->begin(this);
        painter->setPen(Qt::blue);
        painter->setFont(QFont("Arial", 10));
        QRect tabrect = tabRect(index);
        painter->drawText(tabrect, Qt::AlignVCenter | Qt::TextDontClip, tabText(index));
        painter->end();
    }
}

QSize HorizontalTabWidget::sizeHint() const
{
    return QSize(130, 130);
}

I use it by creating NewTabWidget class that inherits QTabWidget. In the constructor of NewTabWidget I use:

setTabBar(new HorizontalTabWidget);

This is done just to be able to use that tabWidget because setTabBar is protected. Here is what I get: enter image description here

What am I missing?

Edit: What I want to create is this but with icons on the top and the labels under the icons (as in Qt Creator): enter image description here

Community
  • 1
  • 1
ashagi
  • 394
  • 6
  • 15
  • What do you want it to look like? What are you expecting from Qt::AlignVCenter? – TonyK Jan 26 '11 at 07:34
  • Is it about that "CustomerList" text? If you want to center this, you should use AlignHCenter. And I wouldn't call this class "HoriontalTabWidget" if the actual order of tabs is vertical. (I think this kind is often referred to as AcoordionTab) – thorsten müller Jan 26 '11 at 07:47
  • 1
    You could draw the text on the QRect defined by the icon as described in http://stackoverflow.com/questions/4270229/qt-how-to-set-text-on-top-of-qlabel-image. If your last edit is an actual result of your current code, then you could add painter->rotate(90) as a last step. – Kristofer Jan 26 '11 at 08:29
  • The last edit is the screenshot where I use QTabWidget without changing paintEvent(). – ashagi Jan 26 '11 at 08:46
  • 2
    From that question you referred to: "Solved! Just changed the method sizeHint in tabSizeHint and it works well :)" Here is the source code for the tab widget used in Qt Creator: http://qt.gitorious.org/qt-creator/qt-creator/blobs/master/src/plugins/coreplugin/fancytabwidget.cpp http://qt.gitorious.org/qt-creator/qt-creator/blobs/master/src/plugins/coreplugin/fancytabwidget.h – ak. Jan 26 '11 at 08:51

3 Answers3

3

the problem should be in the paint method; check if an example below would work for you, it should draw tabs the same way QTCreator does. I've reused the original tab style QStyleOptionTabV3 to do majority of paint work and then just rendered icon and tab's text on top of the image it produced:

class TestTabBar : public QTabBar
{
public:
    explicit TestTabBar(QWidget* parent=0) : QTabBar(parent)
    {
        setIconSize(QSize(80, 80));
    }

protected:
    QSize tabSizeHint(int) const
    {
        return QSize(80, 80);
    }
    void paintEvent(QPaintEvent *)
    {
        QStylePainter p(this);
        for (int index = 0; index < count(); index++)
        {
            QStyleOptionTabV3 tab;
            initStyleOption(&tab, index);

            QIcon tempIcon = tab.icon;
            QString tempText = tab.text;
            tab.icon = QIcon();
            tab.text = QString();

            p.drawControl(QStyle::CE_TabBarTab, tab);

            QPainter painter;
            painter.begin(this);
            QRect tabrect = tabRect(index);
            tabrect.adjust(0, 8, 0, -8);
            painter.drawText(tabrect, Qt::AlignBottom | Qt::AlignHCenter, tempText);
            tempIcon.paint(&painter, 0, tabrect.top(), tab.iconSize.width(), tab.iconSize.height(), Qt::AlignTop | Qt::AlignHCenter);    
            painter.end();
        }
    }
};

class TestTabWidget : public QTabWidget
{
public:
    explicit TestTabWidget(QWidget *parent = 0) : QTabWidget(parent)
    {
        setTabBar(new TestTabBar());
    }
};

tabwidget init:

TestTabWidget* test = new TestTabWidget(this);
test->setGeometry(20, 20, 300, 200);
test->addTab(new QWidget(), QIcon("icon0.png"), "test0");
test->addTab(new QWidget(), QIcon("icon1.png"), "test1");
test->setTabPosition(QTabWidget::West);

this worked fine on my ubuntu, hope it gonna work for you, regards

serge_gubenko
  • 20,186
  • 2
  • 61
  • 64
  • To paint the icon for all tabs and to centre align the icon I used the following mod: tempIcon.paint(&painter, tabrect.left() + 4, tabrect.top() + (tabrect.height() / 2) - (tab.iconSize.height() / 2), tab.iconSize.width(), tab.iconSize.height()); – gremwell Apr 04 '14 at 02:40
1

Vasiliy, thanks for fixing the double QPainter bug.

However, calling setTabIcon() and setTabText() from within paintEvent() leads to an infinite recursion. Remember that tab is a local object, so

tab.text = QString();

does not affect tabText().

So, the example can also be written without making temporary copies and do

p.drawText(tabrect, Qt::AlignBottom | Qt::AlignHCenter, tabText(index));
tabIcon(index).paint(&p, tabrect, Qt::AlignTop | Qt::AlignHCenter);
0

This example does not work. leads to a fall program.

bring your own example with minor edits - my system qt 4.6.3 for Windows and VS2008

class TestTabBar : public QTabBar
{
public:
    explicit TestTabBar(QWidget* parent=0) : QTabBar(parent)
    {
        setIconSize(QSize(58, 68));
    }

protected:
    QSize tabSizeHint(int) const
    {
        return QSize(58, 68);
    }

    void paintEvent(QPaintEvent *)
    {
        QStylePainter p(this);

        for (int index = 0; index < count(); index++)
        {
            QStyleOptionTabV3 tab;
            initStyleOption(&tab, index);

            QIcon tempIcon = tabIcon(index);
            QString tempText = this->tabText(index);

            QRect tabrect = tabRect(index);

            tab.icon = QIcon();
            tab.text = QString();

            p.drawControl(QStyle::CE_TabBarTab, tab);
            tabrect.adjust(0, 3, 0, -3);

            p.setPen(Qt::black);    
            p.setFont(QFont("Arial", 7));

            p.drawText(tabrect, Qt::AlignBottom | Qt::AlignHCenter, tempText );
            tempIcon.paint(&p, tabrect, Qt::AlignTop | Qt::AlignHCenter);

            this->setTabIcon(index, tempIcon );
            this->setTabText( index, tempText);
        }
    }
};

class TestTabWidget : public QTabWidget
{
public:
    explicit TestTabWidget(QWidget *parent = 0) : QTabWidget(parent)
    {
        setTabBar(new TestTabBar());
    }
};
p.i.g.
  • 2,815
  • 2
  • 24
  • 41
Vasiliy
  • 1
  • 1