偶然看到 web
端某个应用,右下角的错误信息弹窗配合上动画看起来很不错,于是想通过 Qt
自己实现一个类似的功能
初定需求
- 弹窗信息从右下角屏幕外,移动到右下角,停留 3s 左右后,逐渐消失
- 鼠标悬浮在弹窗上时,即使弹窗已经停留了 3s,依旧不能消失, 等鼠标移出弹窗后,逐渐消失
- 弹窗上添加超链接,用户点击的时候,可以有对应操作
- 旧的弹窗信息没有消失时候,出现新的弹窗的话,新弹窗动画方式不变,旧的弹窗向上移动一个弹窗的单位
先定这几个,以后想到可以在额外实现
功能的实现
先放一个最后实现的 gif,之后在逐步解释实现的过程
接下来的部分主要是代码逻辑的分析,文章最后有工程在 github
的地址
右下角动画弹出
这个功能大概的逻辑
- 初始化一个弹窗,移动到右下角的屏幕外
- 一个
m_showTimer
定时器,每隔 1 ms, 弹窗向上移动 1 个单位,直到移动到指定位置 - 移动到指定位置后,
m_stayTimer
定时器,每隔 1000 ms 触发一次,3次之后,启动关闭的m_closeTimer
的定时器 m_closeTimer
定时器, 每隔 100 ms, 窗口的透明度 (完全不透明为1) 减少 0.2,直到透明度为 0 时,关闭窗口
messageshow.h
// 窗口最后稳定不动时的坐标
QPoint end_showPoint;
// 因为是从右下角滑出, x 方向是固定的,所以需要记录一下当前窗口的实时 y 坐标
int m_currentHeight;
// 3 个定时器
QTimer* m_showTimer;
QTimer* m_stayTimer;
QTimer* m_closeTimer;
// 记录 m_stayTimer 执行的次数
int m_stayExeTime;
// 记录当前窗口的透明度
double m_transparent;
messageshow.cpp
// 所有定时器对应执行的信号槽
connect(m_showTimer, SIGNAL(timeout()), this, SLOT(slotMsgMove()));
connect(m_stayTimer, SIGNAL(timeout()), this, SLOT(slotMsgStay()));
connect(m_closeTimer, SIGNAL(timeout()), this, SLOT(slotMsgClose()));
// 显示弹窗的初始化函数
void MessageShow::showMessage(){
m_showTimer->stop();
m_stayTimer->stop();
m_closeTimer->stop();
setWindowOpacity(1);
// 获取当前桌面的位置
QRect desk_rect = QApplication::desktop()->availab