Qt(C ++):动态设置QTabWidget中单个标签的样式 [英] Qt (C++): dynamically style an individual tab in QTabWidget

查看:2363
本文介绍了Qt(C ++):动态设置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);
    }
};

完整的示例可在以下链接

这篇关于Qt(C ++):动态设置QTabWidget中单个标签的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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