【Qt实用技巧】实现任务栏程序图标闪烁提醒(FlashWindow)的两种方法

433 阅读2分钟

📒博客首页:何名取 的个人主页 - 文章 - 掘金 (juejin.cn)
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
❤️期待一起交流!
🙏作者水平很有限,如果发现错误,求告知,多谢!
🌺有问题可私信交流!!!


FlashWindow

FlashWindow,用来闪烁显示指定窗口。

前言

本节来研究一下如何使用Qt来实现任务栏中的应用程序图标闪烁提醒。需求的效果如下图所示:

动画.gif

方法一

使用Qt中的QApplication类,其中用对应的成员函数可以直接实现上述我们所需的效果

void QApplication::alert(QWidget *widget, int msec = 0)

如果窗口不是活动窗口,则对界面显示警报。该警告以毫秒为单位显示。如果msec为零(默认值),则警报将无限期地显示,直到窗口再次激活为止。

目前这个函数在不支持任务栏程序图标闪烁的嵌入式Linux系统上没有任何作用。

注意这里并不意味着在所有Linux系统上都无法使用此方法,如果这个Linux桌面系统支持任务栏闪烁的话,可能也是可以使用此方法的。比如我在国产的银河麒麟系统上安装完桌面插件以后本来不支持闪烁的桌面也可以使用Qt中的方法进行功能实现了。

在macOS上,这更多地在应用程序级别工作,并将导致应用程序图标在dock中反弹。

在Windows上,这会导致窗口的任务栏条目闪烁一段时间。如果msec为零,闪烁将停止,任务栏条目将变成不同的颜色(目前是橙色)。

这种方法比较简单直接,在代码中使用定时器来触发即可。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
   void startFlash();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTimer *m_pTimer = NULL;
    m_pTimer = new QTimer(this);
    m_pTimer->setSingleShot(false);
    m_pTimer->start(3000);
    connect(m_pTimer, &QTimer::timeout, this, &MainWindow::startFlash);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::startFlash()
{
    QApplication::alert(this);
}

方法二

上述方法一无法主动进行任务栏图标的闪烁提醒,只在程序不是活动状态时触发。方法二则可以在正常状态下进行闪烁提醒,但是此方法只局限于Windows系统上使用,其他操作系统上没有相关支持。

方法二主要使用了winuser.h中的Windows API。使用这两个函数需要包含相关的头文件qt_windows.h


WINUSERAPI WINBOOL WINAPI FlashWindow (HWND hWnd, WINBOOL bInvert);

WINUSERAPI WINBOOL WINAPI FlashWindowEx (PFLASHWINFO pfwi);

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    void on_TimerEvent();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#ifdef Q_OS_WIN
#include <qt_windows.h>
#endif

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTimer *m_pTimer = NULL;
    m_pTimer = new QTimer(this);
    m_pTimer->setSingleShot(false);
    m_pTimer->start(3000);
    connect(m_pTimer, &QTimer::timeout, this, &MainWindow::on_TimerEvent);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_TimerEvent()
{
    FLASHWINFO info;
    info.cbSize = sizeof(info);
    info.hwnd = HWND(this->winId());
    info.dwFlags = FLASHW_TRAY;
    info.dwTimeout = 500;
    info.uCount = 5;
    FlashWindowEx(&info);
}

下图是程序运行后的效果图: 动画2.gif