12

I'm using Qt and I have a QTabWidget setup in the Qt Designer Editor, you can see it in picture 1.

picture 1

As you can see after Tab4 there is an empty space all the way to the right edge, in someway I need to fill that space with a color, like in picture 2 (the best thing would be to be able to set a fading color). Or another solution would be that the tabs float out to cover the whole screen.

picture 2

I use the following stylesheet right now:

QTabWidget::tab-bar {

 }

 QTabBar::tab {
  background: gray;
  color: white;
  padding: 10px;
 }

 QTabBar::tab:selected {
  background: lightgray;
 }

Is there a way to set the background color of the QTabBar using Qt stylesheets? Or can I get the tabs floating out to the edge using Qt stylesheets?

EDIT: I have been trying the solution that Caleb Huitt - cjhuitt suggested below. I really like the idea of making the tabs expand but can't get it working.

In Qt Designer Editor I right click on my QTabWidget->"Promote To ..." and choose "Base class name": QTabWidget "Promoted class name": ExpandableTabWidget and then I click add and then Promote.

In the init method of the widget that holds my QTabWidget I set

ui.tabWidget->SetTabsExpanding(true);

Everything is building fine but the QTabbar doesn't expand.

Am I doing something wrong?

Thanks!

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Martin
  • 1,675
  • 11
  • 34
  • 46
  • have you tried giving tab-bar a background-color ? what was the result ? – smerlin Mar 19 '10 at 22:09
  • Yes, tested that but nothing happened. Any ideas? – Martin Mar 19 '10 at 22:58
  • Thanks! But thats what I've been playing with so far but no results. Isn't this possible? – Martin Mar 20 '10 at 09:37
  • The Q_PROPERTY line will probably only help you if you make the expanding tab widget into a plugin. Otherwise, if it is generating warnings, you could remove it. – Caleb Huitt - cjhuitt Mar 21 '10 at 18:31
  • Also, regarding the expanding tab widget, I was assuming that this would work, never having done it myself. If it doesn't work, you could create your own tab widget pretty easily, with a QTabBar above a QFrame, and a QStackedWidget inside that QFrame. You'll need to add some logic to handle the switching, of course. However, I'd poke around a little more to try and find out why the tabs aren't expanding. – Caleb Huitt - cjhuitt Mar 21 '10 at 18:32
  • Aha, I'm quite new to Qt so I didn't know about the plugins. It's strange that it doesn't expand the QTabBar at all, I have been playing with it but can't get anything to happen. Please post if you make any progress. Thanks really much! – Martin Mar 21 '10 at 22:56

4 Answers4

19

Both expanding tabs and coloring the background can be accomplished using style sheets.

For expanding tabs, a style sheet can be applied to the tabs which sets their width to a fraction of the total width of the QTabWidget. Since the style sheet will need to be updated upon resize, it is applied using an event filter. See first example code below.

Although the background of the tab bar can be set, the tab bar doesn't fill the entire space above the tab pane. It is the container (or parent widget) which is showing through. To control the coloring of that area, put the QTabWidget in a QWidget and set the style sheet on the container. See second example code below.

Expanding tabs:

#include <QtGui>

// Sets the style sheet of the QTabWidget to expand the tabs.
static void expandingTabsStyleSheet(QTabWidget *tw)
{
    tw->setStyleSheet(QString("QTabBar::tab { width: %1px; } ")
                      .arg(tw->size().width()/tw->count()));
}

// On resize events, reapply the expanding tabs style sheet
class ResizeFilter : public QObject
{
    QTabWidget *target;
public:
    ResizeFilter(QTabWidget *target) : QObject(target), target(target) {}

    bool eventFilter(QObject *object, QEvent *event)
    {
        if (event->type() == QEvent::Resize)
            expandingTabsStyleSheet(target);
        return false;
    }
};


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

  QTabWidget *tw = new QTabWidget;
  tw->installEventFilter(new ResizeFilter(tw));
  tw->addTab(new QWidget, "Tab1");
  tw->addTab(new QWidget, "Tab2");
  tw->addTab(new QWidget, "Tab3");

  tw->show();

  return app.exec();
}

Background beside tabs:

#include <QtGui>

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

  QWidget *container = new QWidget;
  container->setStyleSheet("background: qlineargradient( x1: 0, y1: 0, x2: 1, y2
: 0, stop: 0 black, stop: 1 blue);");

  QHBoxLayout *layout = new QHBoxLayout(container);
  layout->setContentsMargins(0, 0, 0, 0);

  QTabWidget *tw = new QTabWidget(container);
  layout->addWidget(tw);
  tw->setStyleSheet(
      "QTabBar::tab { background: gray; color: white; padding: 10px; } "
      "QTabBar::tab:selected { background: lightgray; } "
      "QTabWidget::pane { border: 0; } "
      "QWidget { background: lightgray; } ");
  tw->addTab(new QWidget, "Tab1");
  tw->addTab(new QWidget, "Tab2");
  tw->addTab(new QWidget, "Tab3");

  container->show();

  return app.exec();
}
Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
baysmith
  • 5,082
  • 1
  • 23
  • 18
  • really great answer! I was fighting with this problem for hours before finding your aswer :-) – Carlos Cordoba Jun 19 '15 at 22:01
  • Trying this on macOS, I find that the screen keeps expanding width until I stop it in the debugger! Works OK on iOS however, so thanks for that. – Pete Dec 23 '17 at 19:22
3

As I see it, you have two options, depending on what you want to do.

To fill the background with color:

Take advantage of the transparency of that portion of the tab widget.

QWidget *bg = new QWidget( parent );
bg->setAutoFillBackground( true );
QPalette bg_palette = bg->palette();
bg_palette.setColor( QPalette::Window, QColor( "orange" ) );
bg->setPalette( bg_palette );

QHBoxLayout layout = new QHBoxLayout();
layout->setMargin( 0, 0, 0, 0 );
layout->setSpacing( 0 );
bg->setLayout( layout );

QTabWidget *tab_widget = new QTabWidget();
// set up tab_widget however you want...
layout->addWidget( tab_widget );

This makes the bg widget all orange, but since most of the tab widget will draw over the bg widget, you'll only see the orange where the tab widget doesn't draw.

To make the tabs expand:

I thought this would be easier than it is, but you basically have to subclass QTabWidget in order to get access to the tab bar widget it uses.

class ExpandableTabWidget : public QTabWidget
{
    Q_OBJECT;
    Q_PROPERTY( bool expanding_tabs READ Expanding WRITE SetExpanding );

public:
    ExpandableTabWidget( QWidget *parent = NULL ) : QTabWidget( parent )
    {
    }

    bool Expanding() const
    {
        return tabBar()->expanding();
    }

    void SetTabsExpanding( bool expanding = true )
    {
        tabBar()->setExpanding( expanding );
    }
};

You would then either need to make your ExpandableTabWidget class into a plugin and use it in designer, or you could promote your tab widget to be of type ExpandableTabWidget and set the expanding value in code. If you choose to do the promotion, you won't see the results you want in designer, but you will when you run your program.

Caleb Huitt - cjhuitt
  • 14,785
  • 3
  • 42
  • 49
  • Thanks really much for your ideas! I updated my original question above with some questions regarding the expanding solution, can you please take a look at it? Thanks again! – Martin Mar 21 '10 at 15:37
2

On qt 4.5 there is a new property that control the tab widget rendering, called documentMode. Just call tabWidget->setDocumentMode(true) and set the background color of the QTabBar using the stylesheets.

From Qt Documentation:

This property holds whether or not the tab widget is rendered in a mode suitable for document pages. This is the same as document mode on Mac OS X.

When this property is set the tab widget frame is not rendered. This mode is useful for showing document-type pages where the page covers most of the tab widget area.

Community
  • 1
  • 1
PiXy
  • 621
  • 5
  • 4
0

I had same problem some time ago. I achieved it by making "big" top border, and moving tab bar with margin

Kamil Klimek
  • 12,884
  • 2
  • 43
  • 58
  • Thanks! But the thing is that I need to have fading on my backgroud otherwise that will work. – Martin Mar 23 '10 at 08:49
  • what do you mean by fading? You can set gradient as border color – Kamil Klimek Mar 23 '10 at 15:22
  • Here is example of what can you achieve with Qt CSS: http://pl.tinypic.com/r/24lsn5v/5 and here is CSS: QTabWidget::pane {border: 0; border-top: 30px solid qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 red, stop: 1 yellow); background: yellow; } QTabWidget::tab-bar { top: 30px; } – Kamil Klimek Mar 23 '10 at 15:49