在 QTabWidget 中动态设置单个选项卡的样式 [英] dynamically style an individual tab in QTabWidget

查看:195
本文介绍了在 QTabWidget 中动态设置单个选项卡的样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,这里和其他网站上已经讨论过这个问题,但还没有真正的解决方案,尽管我认为我不是唯一遇到这个问题的人:

I know, that this question has been discussed here and on other sites, but there has not been a really solution yet, although I think, that I'm not the only one with this problem:

我如何单独和动态地访问单个选项卡(不是其内容或选项卡中的小部件)以进行样式设置,例如更改背景颜色或为其添加图形效果?应用程序可以通知用户某个选项卡需要他的注意,方法是让它以另一种颜色闪烁(就像在 Windows 任务栏中,如果窗口想要获得焦点).有改变文字颜色的功能,何乐而不为呢?样式表可用于访问选定的、第一个等选项卡,但不能通过其索引访问特定的选项卡.有些人谈到了 QTabBar 的子类化,但我不知道,这将如何导致所需的解决方案.是否有可能实现这一点,如果是,请提供示例.

How can I individually and dynamically access a single tab (not its content resp. the widget in the tab) for styling purposes, such as changing the background color or adding graphical effects to it? An application could be to notify the user, that a tab requires his attention, by letting it flash in another color (like in the windows task bar, if a window wants to get focus). There is a function to change the text color, why not more? Stylesheets can be used to access the selected, the first etc. tab, but not a specific one by its index. Some people talked about subclassing QTabBar, but I do not know, how this will lead to the desired solution. Is there any possibility to achieve this and if yes, please provide an example.

推荐答案

为了访问每个 QTabBar 选项卡的每个样式,您必须覆盖 paintEvent() 方法

In order to access each style of each QTabBar tab you must overwrite the paintEvent() method of it.

执行此操作的通用方法应具有以下结构:

The generic way of doing this should have the following structure:

void paintEvent(QPaintEvent *event){
    QStylePainter painter(this);
    QStyleOptionTab opt;

    for(int index = 0; index < count(); index++)
    {
        initStyleOption(&opt,index);
        /*Here make the changes*/
        painter.drawControl(QStyle::CE_TabBarTabShape, opt);
        painter.drawControl(QStyle::CE_TabBarTabLabel,opt);
    }
}

在这一部分中,我将展示如何创建 QTabWidget 的示例,其中显示了一个闪烁的选项卡,并且只有在我们单击该选项卡时才会结束闪烁

In this part I show an example of how to create a QTabWidget where it shows a tab that blinks and only ends the blinking if we click on that tab

TabBarAlert:

class TabBarAlert : public QTabBar
{
    int indexAlert = -1;
    QColor mColor;
    Q_OBJECT
public:
    TabBarAlert(QWidget *parent = Q_NULLPTR):QTabBar(parent)
    {
        mColor = Qt::red;
    }
    void setIndexAlert(int index){
        if(indexAlert == index)
            return;
        indexAlert = index;
        update();
    }

    int getIndexAlert() const{
        return indexAlert;
    }

    QColor getColor() const{
        return mColor;
    }
    void setColor(const QColor &color){
        if(color == mColor)
            return;
        mColor = color;
        update();
    }

protected:
    void paintEvent(QPaintEvent *event){

        if(indexAlert> -1 && indexAlert < count()){
            QStylePainter painter(this);
            QStyleOptionTab opt;

            for(int i = 0;i < count();i++)
            {
                initStyleOption(&opt,i);

                if(indexAlert == i)
                    opt.palette.setColor(QPalette::Button, mColor);
                painter.drawControl(QStyle::CE_TabBarTabShape, opt);
                painter.drawControl(QStyle::CE_TabBarTabLabel,opt);
            }
        }
        else{
            QTabBar::paintEvent(event);
        }
    }

};

TabWidgetAlert:

class TabWidgetAlert : public QTabWidget
{
    TabBarAlert *tb;
    QTimer *timer;
    bool on = false;
    int indexAlert = -1;

    Q_OBJECT
public:
    TabWidgetAlert(QWidget *parent = Q_NULLPTR):QTabWidget(parent)
    {
        tb = new TabBarAlert(this);
        setTabBar(tb);
        tb->setColor(Qt::black);

        /*
        *Disable the alert if the current tab matches the alert tab.
        */
        connect(this, &TabWidgetAlert::currentChanged, [this](int index){
            if(index == tb->getIndexAlert()){
                tb->setIndexAlert(-1);
                on = false;
                timer->stop();
           }
        });

        timer = new QTimer(this);

        /*
        *Create the blink
        */
        connect(timer, &QTimer::timeout, [this](){
            tb->setIndexAlert(on? indexAlert: -1);
            on = !on;
        });
    }

    void setAlert(int index){
        indexAlert = index;
        timer->start(100);
    }
};

完整示例可在以下链接

这篇关于在 QTabWidget 中动态设置单个选项卡的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆