QT5 C++项目中实现倒计时自动关闭QMessageBox

  • 在Windows下的QT5 C++ qmake项目中,希望实现倒计时自动关闭QMessageBox。
  • 以下是基于 Qt5 C++ qmake 项目的完整实现,通过自定义 CountdownMessageBox 类(继承自 QMessageBox),实现“倒计时显示+自动关闭”功能,包含 .h 头文件和 .cpp 源文件,支持自定义倒计时时长、提示文本和按钮类型。效果见下面图片。
QMessageBox QT5 C++倒计时自动关闭03-out

1. 头文件:CountdownMessageBox.h

定义自定义对话框类,核心逻辑包括:倒计时定时器、动态更新按钮文本(显示剩余时间)、自动关闭触发。

#ifndef COUNTDOWNMESSAGEBOX_H
#define COUNTDOWNMESSAGEBOX_H

#include <QMessageBox>
#include <QTimer>
#include <QString>

// 继承 QMessageBox,实现倒计时自动关闭
class CountdownMessageBox : public QMessageBox
{
    Q_OBJECT

public:
    // 构造函数:支持自定义标题、内容、倒计时秒数、按钮类型
    // 参数说明:
    // - title: 对话框标题
    // - text: 对话框内容(会自动追加倒计时提示)
    // - countdownSec: 倒计时秒数(默认3秒)
    // - buttons: 对话框按钮(默认只有“确定”按钮)
    explicit CountdownMessageBox(const QString& title, 
                                 const QString& text, 
                                 int countdownSec = 3, 
                                 StandardButtons buttons = Ok,
                                 QWidget *parent = nullptr);

    // 显示对话框(重写 show(),确保倒计时启动时机正确)
    void show() override;

private slots:
    // 倒计时定时器触发的槽函数:更新剩余时间,到0时关闭对话框
    void onCountdownTimeout();

private:
    QTimer* m_countdownTimer;  // 倒计时定时器
    int m_remainingSec;        // 剩余倒计时秒数
    QString m_originalText;    // 原始对话框内容(用于拼接倒计时文本)
    StandardButton m_defaultBtn;// 默认按钮(倒计时结束后自动触发该按钮的点击事件)
};

#endif // COUNTDOWNMESSAGEBOX_H

2. 源文件:CountdownMessageBox.cpp

实现定时器初始化、倒计时更新、自动关闭逻辑,兼容 Windows 平台的对话框行为。

#include "CountdownMessageBox.h"

CountdownMessageBox::CountdownMessageBox(const QString& title, 
                                         const QString& text, 
                                         int countdownSec, 
                                         StandardButtons buttons,
                                         QWidget *parent)
    : QMessageBox(parent)
    , m_remainingSec(countdownSec)  // 初始化倒计时秒数
    , m_originalText(text)          // 保存原始内容(避免重复拼接)
    , m_defaultBtn(standardButton(buttons))  // 获取默认按钮(如 Ok)
{
    // 1. 初始化对话框基础属性(标题、按钮、图标等)
    setWindowTitle(title);
    setStandardButtons(buttons);
    setDefaultButton(m_defaultBtn);  // 设置默认按钮(按 Enter 可触发)

    // 2. 初始化倒计时定时器
    m_countdownTimer = new QTimer(this);
    m_countdownTimer->setInterval(1000);  // 定时器间隔:1秒(1000毫秒)
    m_countdownTimer->setSingleShot(false);  // 非单次触发(循环计时)

    // 3. 连接定时器信号与槽函数(每秒触发一次倒计时更新)
    connect(m_countdownTimer, &QTimer::timeout, 
            this, &CountdownMessageBox::onCountdownTimeout);

    // 4. 初始显示:拼接原始文本和倒计时提示(如“操作成功,3秒后自动关闭...”)
    updateText();
}

// 重写 show() 函数:显示对话框时启动倒计时
void CountdownMessageBox::show()
{
    m_countdownTimer->start();  // 启动定时器
    QMessageBox::show();        // 调用父类 show(),显示对话框
}

// 倒计时定时器槽函数:更新剩余时间,到0时关闭对话框
void CountdownMessageBox::onCountdownTimeout()
{
    // 1. 减少剩余秒数
    m_remainingSec--;

    // 2. 更新对话框文本(显示最新剩余时间)
    updateText();

    // 3. 倒计时结束:停止定时器 + 触发默认按钮点击 + 关闭对话框
    if (m_remainingSec <= 0)
    {
        m_countdownTimer->stop();  // 停止定时器
        // 模拟点击默认按钮(触发对话框的 accept/reject 逻辑,确保信号正常发射)
        clickButton(m_defaultBtn);
        // 关闭对话框(若 clickButton 未触发关闭,手动关闭)
        close();
    }
}

// 辅助函数:更新对话框文本(拼接原始内容和剩余时间)
void CountdownMessageBox::updateText()
{
    // 格式:原始文本 + “(X秒后自动关闭)”
    QString newText = QString("%1(%2秒后自动关闭)")
                      .arg(m_originalText)
                      .arg(m_remainingSec);
    setText(newText);
}

3. 使用示例(main.cpp)

在项目中调用自定义的 CountdownMessageBox,支持不同场景(如成功提示、警告提示)。

#include <QApplication>
#include "CountdownMessageBox.h"

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

    // 示例1:基础用法(3秒自动关闭,默认“确定”按钮)
    CountdownMessageBox msg1(
        "操作成功",                // 标题
        "文件已成功保存到 D:\\Temp\\",  // 内容
        3,                        // 倒计时3秒
        QMessageBox::Ok           // 按钮类型
    );
    msg1.setIcon(QMessageBox::Information);  // 设置图标(信息图标)
    msg1.exec();  // 模态显示(也可使用 show() 非模态,根据需求选择)

    // 示例2:自定义倒计时+多按钮(5秒自动关闭,“确定”+“取消”按钮)
    CountdownMessageBox msg2(
        "警告",                    // 标题
        "检测到未保存的修改,是否放弃?",  // 内容
        5,                        // 倒计时5秒
        QMessageBox::Ok | QMessageBox::Cancel  // 多按钮
    );
    msg2.setIcon(QMessageBox::Warning);  // 设置图标(警告图标)
    // 监听按钮点击结果(即使自动关闭,也能获取默认按钮的结果)
    int result = msg2.exec();
    if (result == QMessageBox::Ok)
    {
        qDebug() << "用户选择:放弃修改(或倒计时自动触发)";
    }
    else if (result == QMessageBox::Cancel)
    {
        qDebug() << "用户选择:取消操作";
    }

    return a.exec();
}

4. 项目配置(.pro 文件)

确保 qmake 项目配置正确,仅需依赖 Qt 核心模块(无需额外第三方库)。

QT       += core gui widgets  # 依赖 widgets 模块(QMessageBox 属于 widgets)
TARGET = CountdownMsgDemo     # 项目名称
TEMPLATE = app                # 应用程序模板
SOURCES += main.cpp           # 源文件
           CountdownMessageBox.cpp
HEADERS  += CountdownMessageBox.h  # 头文件

5. 关键特性说明(Windows 平台适配)

  1. 定时器稳定性:使用 QTimer 而非 sleep,避免阻塞 UI 线程,确保对话框可正常交互(用户可手动点击按钮提前关闭)。
  2. 按钮事件兼容:倒计时结束时通过 clickButton(m_defaultBtn) 模拟按钮点击,而非直接 close(),确保 exec() 的返回值(如 QMessageBox::Ok)正常,与原生 QMessageBox 行为一致。
  3. 文本动态更新:通过 updateText() 函数实时刷新倒计时文本,用户可清晰看到剩余时间。
  4. 模态/非模态支持:支持 exec()(模态,阻塞后续代码)和 show()(非模态,不阻塞),根据业务场景选择(如后台操作提示用非模态,关键确认用模态)。

posted on 2025-09-08 19:46  patton88  阅读(49)  评论(0)    收藏  举报

导航