Qt:如何美化QTabWidget

12

我正在使用Qt,我在Qt Designer编辑器中设置了一个QTabWidget,您可以在图片1中看到。

picture 1

正如您所看到的,在Tab4之后,有一段空白区域一直延伸到右边缘,我需要以某种方式使用颜色填充该空间,就像图片2中所示(最好能够设置渐变颜色)。或者另一种解决方案是选项卡浮出覆盖整个屏幕。

picture 2

我目前使用以下样式表:

QTabWidget::tab-bar {

 }

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

 QTabBar::tab:selected {
  background: lightgray;
 }
有没有一种方法可以使用Qt样式表设置QTabBar的背景颜色?或者我可以使用Qt样式表将选项卡浮动到边缘吗?
编辑:我一直在尝试Caleb Huitt - cjhuitt下面建议的解决方案。我非常喜欢使选项卡扩展的想法,但是无法让它工作。
在Qt Designer Editor中,我右键单击我的QTabWidget->“Promote To ...”,选择“Base class name”: QTabWidget,“Promoted class name”: ExpandableTabWidget,然后我点击添加,再点击Promote。
在容纳我的QTabWidget的窗口小部件的init方法中,我进行了设置。
ui.tabWidget->SetTabsExpanding(true);

一切都在正常构建,但QTabbar没有扩展。

我做错了什么吗?

谢谢!


你尝试过给标签栏(tab-bar)设置背景颜色吗?结果如何? - smerlin
是的,我测试过了,但是没有任何反应。你有什么想法吗? - Martin
谢谢!但这就是我一直在尝试的,但并没有结果。这不可能吗? - Martin
如果您将可扩展的选项卡小部件转换为插件,Q_PROPERTY行可能会有所帮助。否则,如果它生成警告,则可以将其删除。 - Caleb Huitt - cjhuitt
另外,关于可扩展的选项卡小部件,我假设它可以工作,因为我自己从未尝试过。如果它不起作用,您可以很容易地创建自己的选项卡小部件,使用QTabBar在QFrame上方,并在该QFrame内部使用QStackedWidget。当然,您需要添加一些逻辑来处理切换。但是,我建议您再仔细研究一下为什么选项卡没有扩展。 - Caleb Huitt - cjhuitt
啊哈,我对Qt还比较新,所以我不知道插件的存在。很奇怪它根本没有扩展QTabBar,我一直在尝试但是什么也没发生。如果你有任何进展,请发布一下。非常感谢! - Martin
5个回答

19

使用样式表可以同时实现扩展标签和背景着色。

对于扩展标签,可以将样式表应用于标签,将它们的宽度设置为QTabWidget总宽度的一部分。由于在调整大小时需要更新样式表,因此使用事件过滤器应用它。请参见下面的第一个示例代码。

虽然可以设置选项卡栏的背景色,但选项卡栏并未填充在选项卡窗格上方的整个空间。显示的是容器(或父小部件)。 若要控制该区域的着色,请将QTabWidget放入QWidget中,并在容器上设置样式表。请参见下面的第二个示例代码。

扩展标签:

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

选项卡旁边的背景:

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

真的是非常棒的答案!在找到你的回答之前,我为这个问题苦战了好几个小时 :-) - Carlos Cordoba
在macOS上尝试时,我发现屏幕的宽度会不断扩展,直到我在调试器中停止它!但在iOS上运行正常,所以感谢您。 - Pete

3

我认为,根据你想要做什么,你有两个选择。

要填充背景颜色:

利用选项卡小部件的透明度。

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 );

这会使背景小部件变成橙色,但由于大多数选项卡小部件将绘制在背景小部件上方,因此只有在选项卡小部件未绘制的区域才会看到橙色。
要使选项卡扩展:
我认为这比想象中要容易,但基本上您必须子类化QTabWidget以便访问它使用的选项卡栏小部件。
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 );
    }
};

接下来您需要将您的ExpandableTabWidget类转换成插件并在设计器中使用它,或者将您的选项卡窗口提升为ExpandableTabWidget类型并在代码中设置展开值。如果您选择进行提升,您将无法在设计器中看到所需结果,但在运行程序时会看到。


非常感谢您的想法!我已经更新了我的原始问题,并提出了一些关于扩展解决方案的问题,您能否请看一下?再次感谢! - Martin

2
在qt 4.5中,有一个名为“documentMode”的新属性用于控制选项卡小部件的呈现。只需调用tabWidget->setDocumentMode(true)并使用样式表设置QTabBar的背景颜色即可。
来自Qt文档:
此属性控制选项卡小部件是否以适合文档页面的模式呈现。这与Mac OS X上的文档模式相同。当设置此属性时,不会呈现选项卡小部件框架。此模式对于显示覆盖大多数选项卡小部件区域的文档类型页面非常有用。

0

我之前也遇到过同样的问题。我通过设置“大”的顶部边框,并通过外边距移动选项卡栏来解决它。


谢谢!但问题是我需要在我的背景上有淡入淡出效果,否则那样不行。 - Martin
你所说的“fading”是什么意思?你可以将渐变色设置为边框颜色。 - Kamil Klimek
这是使用Qt CSS可以实现的示例:http://pl.tinypic.com/r/24lsn5v/5,以下是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

-1
备选方案: 将各个选项卡的宽度设置为230%,以使其适应窗口的长度。
QTabBar::tab { width: 234%; }

根据目前的写法,你的回答不够清晰。请编辑以添加更多细节,帮助其他人理解这如何回答所提出的问题。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接