QT实现消息提示,数秒后自动消失

        在 Qt 开发中,QLabel 是一个非常基础且常用的控件,用于显示文本或图像。然而,在某些应用场景中,我们可能需要一个带有渐变消失效果的通知标签(NoticeLabel),以便在特定时间后自动淡出并隐藏。本文将详细介绍如何通过自定义 QLabel 类来实现这一功能,并提供详细的代码解析和使用示例。

    一、简述

    为了满足实际开发中的需求,我们希望实现的 NoticeLabel 具备以下功能:

    • 显示消息:能够显示纯文字或带有背景颜色的消息。
    • 自动消失:在指定的时间后自动淡出并隐藏。
    • 渐变效果:在最后1秒内逐渐降低透明度,实现平滑的消失效果。
    • 自定义样式:支持设置文本颜色和背景颜色。
    • 居中显示:在父窗口中居中显示通知标签。

            使用Qt实现可定时消息提示的设计思路是使用QTimer和QLabel来实现消息提示,数秒后自动消失的效果。

            要实现定时消息提示,可以使用以下步骤:

    1. 确定需要发送消息的时间和内容。可以通过用户输入或者预设的方式来确定消息的发送时间和内容。

    2. 设置一个定时器,在指定的时间渐变消退。

    二、效果

     

    三、核心代码 
    1、头文件
    #ifndef NOTICELABEL_H
    #define NOTICELABEL_H
    
    #include <QLabel>
    #include <QTimer>
    #include <QColor>
    
    enum NoticeType
    {
        ONLY_TEXT = 0,	//纯文字;
        TEXT_BACKGROUND		//文字和背景
    };
    
    class NoticeLabel : public QLabel
    {
        Q_OBJECT
    public:
        NoticeLabel(QWidget *parent = 0);
        ~NoticeLabel();
    
        //显示消息,可设置delay_ms=0来控制显示时间
        void Notice(QWidget *parent, const QString &strMessage, const int delay_ms = 2000);
    
        void setNoticeType(NoticeType type);
        void setTextColor(QColor textColor);
        void setBackgroundColor(QColor bgColor);
    
    public slots:
        void onTimerTimeout();
    
    private:
        void setMesseage(const QString &strMessage, int delay_ms);
        void changeSize();
        void setColor();
    
    private:
        QWidget *m_pParent;
        QTimer  *m_pTimer;
        int m_delay_ms;//显示时间
        int m_opacity_cut_val;//透明度递减值
        int m_opacity_val;//当前透明度
        int m_Width;  //一行宽度
        int m_Height; //一行高度
        int m_MinHeight; //最小高度
        QVector<int> m_vecLinesLen;
        QColor m_textColor;
        QColor m_bgColor;
        NoticeType m_noticeType;
    };
    
    #endif // NOTICELABEL_H
    
    2、cpp代码
    #include "noticelabel.h"
    
    NoticeLabel::NoticeLabel(QWidget *parent)
        :m_pParent(parent)
    {
        //文字居中
        setAlignment(Qt::AlignCenter);
    
        m_pTimer = new QTimer();
        connect(m_pTimer, SIGNAL(timeout()), this, SLOT(onTimerTimeout()), Qt::UniqueConnection);
    
        m_opacity_cut_val = 255/(1000/40)+1;  //透明度最大值255  最后1000ms开始降低透明度
    
        QFont font;
        font.setFamily("微软雅黑");
        font.setBold(true);
        font.setPointSizeF(20);
        setFont(font);
    
        m_noticeType = NoticeType::ONLY_TEXT;
    }
    
    NoticeLabel::~NoticeLabel()
    {
        if (m_pTimer->isActive())
        {
            m_pTimer->stop();
        }
    
        delete m_pTimer;
        deleteLater();
    }
    
    void NoticeLabel::Notice(QWidget *parent, const QString &strMessage, const int delay_ms)
    {
        if (m_pTimer->isActive())
        {
            m_pTimer->stop();
            setVisible(false);
        }
    
        if (strMessage.isEmpty() || delay_ms <= 0)
        {
            return;
        }
    
        setParent(parent);
        m_pParent = parent;
        setMesseage(strMessage, delay_ms);
        m_pTimer->start(40);
    }
    
    void NoticeLabel::onTimerTimeout()
    {
        m_delay_ms -= 40;
        if (m_delay_ms > 0)
        {
            //重新定位(窗口大小和位置可能变化)
            if (nullptr != m_pParent)
            {
                QPoint pt((m_pParent->width() - width()) >> 1, (m_pParent->height() - height()) >> 1);
                if (pos() != pt)
                {
                    changeSize();
                    move(pt);
                }
            }
    
            //最后1s开始渐变消失
            if (m_delay_ms <= 1000)
            {
                m_opacity_val -= m_opacity_cut_val;
                if (m_opacity_val < 0)
                {
                    m_opacity_val = 0;
                }
    
                setColor();
            }
        }
        else
        {
            //显示结束
            m_pTimer->stop();
            setVisible(false);
        }
    }
    
    void NoticeLabel::setMesseage(const QString &strMessage, int delay_ms)
    {
        QStringList strList = strMessage.split("\n");
        QFontMetrics fontMetrics(font());
        m_vecLinesLen.clear();
    
        int tmpW = 0;
        int maxLineLen = 1; //最长那一行的长度
        foreach (auto s, strList)
        {
            tmpW = fontMetrics.width(s);
            m_vecLinesLen.push_back(tmpW);
            if (maxLineLen < tmpW)
            {
                maxLineLen = tmpW;
            }
        }
    
        m_Width = fontMetrics.width(strMessage);
        m_Height = fontMetrics.lineSpacing() + 10;
        m_MinHeight = (m_Width * m_Height)/maxLineLen + 1;//面积除以最长的宽就是最小的高
    
        //设置宽高
        changeSize();
    
        //换行
        setWordWrap(true);
    
        //设置显示内容
        setText(strMessage);
    
        //居中
        if (m_pParent != nullptr)
        {
            move((m_pParent->width() - width()) >> 1, (m_pParent->height() - height()) >> 1);
        }
    
        setVisible(true);//显示
        m_delay_ms = delay_ms;
        m_opacity_val = 255;
    
        setColor();
     }
    
    void NoticeLabel::changeSize()
    {
        if (m_pParent != nullptr)
        {
            double wd = m_pParent->width() * 0.6;
    
            int newH = (m_Height * m_Width)/wd + 10;
            if (newH < (m_Height + m_Height))
            {
                newH = m_MinHeight + m_Height;
            }
            else
            {
                foreach (auto lineLen, m_vecLinesLen)
                {
                    if (lineLen > wd)
                    {
                        newH += m_Height;
                    }
                }
            }
    
            setFixedSize((int)wd, newH);
        }
    }
    
    void NoticeLabel::setNoticeType(NoticeType type)
    {
        m_noticeType = type;
    }
    
    void NoticeLabel::setTextColor(QColor textColor)
    {
        m_textColor = textColor;
    }
    
    void NoticeLabel::setBackgroundColor(QColor bgColor)
    {
        m_bgColor = bgColor;
    }
    
    void NoticeLabel::setColor()
    {
        switch (m_noticeType) {
        case ONLY_TEXT:
            setStyleSheet(QString("color:rgba(%1, %2, %3, %4)").arg(m_textColor.red()).arg(m_textColor.green()).arg(m_textColor.blue()).arg(m_opacity_val));
            break;
        case TEXT_BACKGROUND:
            setStyleSheet(QString("color:rgb(%1, %2, %3);border-radius:8px;background-color:rgba(%4, %5, %6, %7);") \
                          .arg(m_textColor.red()).arg(m_textColor.green()).arg(m_textColor.blue()) \
                          .arg(m_bgColor.red()).arg(m_bgColor.green()).arg(m_bgColor.blue()).arg(m_opacity_val));
            break;
        default:
            break;
        }
    }
    
    

            

    上述代码实现NoticeLabel提示消息控件。流程如下:

    1. 定义一个NoticeLabel类来表示提示消息控件,继承自QLabel。

    2. 在NoticeLabel类中添加一个公开的属性,用于设置提示消息的样式,比如背景颜色、字体样式等。

    3. 添加一个公开的方法,用于设置提示消息的内容和显示时间。

    4. 在设置内容时,将内容赋给NoticeLabel的text属性,并根据内容的长度自适应NoticeLabel的宽度。

    5. 设置显示时间时,延迟一段时间后隐藏NoticeLabel。

    6. 当需要隐藏提示消息时,调用NoticeLabel的隐藏方法。

            通过这种方式,我们可以在需要的地方方便地实现消息提示的功能,并可以控制消息的显示时间。 

    四、使用示例
        m_noticeLable.setNoticeType(NoticeType::ONLY_TEXT);
        m_noticeLable.setTextColor(QColor(255,0,0));
        m_noticeLable.Notice(this,QString("你好,世界!Hello world!"));
        m_noticeLable.setNoticeType(NoticeType::TEXT_BACKGROUND);
        m_noticeLable.setTextColor(QColor(0,0,255));
        m_noticeLable.setBackgroundColor(QColor(127,127,127));
        m_noticeLable.Notice(this,QString("你好,世界!Hello world!"));

            本文通过实例代码详细介绍了如何利用Qt实现消息提示可定时自动关闭,希望这个示例能够帮助您更好地理解如何在Qt中实现此功能。感谢您的阅读和关注。如果有任何问题或建议,请随时与我联系。祝您一切顺利! 

    五、示例下载
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值