实现效果

这次制作的桌面右下角弹窗,主要功能有透明度和位置动画、定时关闭。

实现思路

首先,我们需要获取桌面大小,然后 move 到右下角去,这里借助的 QScreen:

QScreen * screen = QGuiApplication::primaryScreen();
const QRect desk_rect = screen->availableGeometry();

对于动画,我用的  QPropertyAnimation 属性动画配合动画组。然后根据设置来决定启用哪些动画、是否定时关闭等。

还有要注意的是模态框的问题,如果有一个 ApplicationModal 的窗口显示了,就没法点击其他窗口。而且关闭模态窗口时,可能会导致主窗口跑到其他窗口后面去了。这里我时先设置为 WindowModal ,关闭时再设置程 NoModal 非模态。

目前还没有做鼠标放在上面不自动关闭的功能;目前的实现只有单个弹窗实例,可自行修改为允许多个弹框同时存在。

实现代码

完整代码链接(RDesktopTip类):https://github.com/gongjianbo/RectangleComponent

首先在ui中拖一个样式:

主要实现代码:

#ifndef RDESKTOPTIP_H
#define RDESKTOPTIP_H#include <QWidget>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
#include <QTimer>namespace Ui {
class RDesktopTip;
}/*** @brief 桌面右下角弹框* @author 龚建波* @date 2020-6-21* @note 可以增加show的parent参数,使模态有父子关系* @details 只有单个实例对象显示弹框,* 后面设置的信息会覆盖之前的。* 也可以修改为每次show单独创建一个实例对象*/
class RDesktopTip : public QWidget
{Q_OBJECTexplicit RDesktopTip();
public://动画模式枚举enum AnimationMode{//无动画NoAnimation = 0x00,//仅透明度动画OpacityAnimation = 0x01,//仅位置动画PosAnimation = 0x02,//全部动画//OpacityAnimation|PosAnimationAllAnimation = 0xFF};
public:~RDesktopTip();//显示弹框-已显示动画重新开始,timeout<=0不会定时消失static void showTip(const QStringList &texts,int timeout=0);//显示弹框-已显示不重复动画static void keepTip(const QStringList &texts);//隐藏弹框static void hideTip();//设置动画模式static RDesktopTip::AnimationMode getMode();static void setMode(RDesktopTip::AnimationMode newMode);private://初始化动画设置void initAnimation();//初始化定时器设置void initTimer();//准备定时器void readyTimer(int timeout);//启动显示动画-已显示动画重新开始void showAnimation();//启动显示动画-已显示不重复动画void keepAnimation();//启动隐藏动画void hideAnimation();//显示的文本void setTextList(const QStringList &texts);private:Ui::RDesktopTip *ui;//唯一实例static RDesktopTip *instance;//动画设置static AnimationMode mode;//动画组QParallelAnimationGroup *showGroup;//保存动画结束状态bool showAnimEnd=false;//透明度属性动画QPropertyAnimation *showOpacity=nullptr;//位置属性动画QPropertyAnimation *showPos=nullptr;//定时关闭QTimer *hideTimer=nullptr;//定时计数int hideCount=0;
};#endif // RDESKTOPTIP_H
#include "RDesktopTip.h"
#include "ui_RDesktopTip.h"#include <QApplication>
#include <QScreen>
#include <QDebug>RDesktopTip* RDesktopTip::instance=nullptr;
RDesktopTip::AnimationMode RDesktopTip::mode=RDesktopTip::AllAnimation;RDesktopTip::RDesktopTip(): QWidget(nullptr),ui(new Ui::RDesktopTip),showGroup(new QParallelAnimationGroup(this))
{ui->setupUi(this);setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);setAttribute(Qt::WA_TranslucentBackground);setAttribute(Qt::WA_DeleteOnClose);//setWindowModality(Qt::WindowModal);//resize会被label撑开setFixedSize(310,210);//关闭connect(ui->btnClose,&QPushButton::clicked,this,&RDesktopTip::hideTip);//程序退出时释放connect(qApp,&QApplication::aboutToQuit,this,&RDesktopTip::close);//动画设置initAnimation();//定时器设置initTimer();
}RDesktopTip::~RDesktopTip()
{qDebug()<<"delete DesktopTip";delete ui;
}void RDesktopTip::showTip(const QStringList &texts, int timeout)
{if(!instance){//仅在ui线程instance=new RDesktopTip;}instance->readyTimer(timeout);//模态框instance->setWindowModality(Qt::WindowModal);instance->setTextList(texts);instance->showAnimation();
}void RDesktopTip::keepTip(const QStringList &texts)
{if(!instance){//仅在ui线程instance=new RDesktopTip;}instance->readyTimer(0);//模态框instance->setWindowModality(Qt::WindowModal);instance->setTextList(texts);instance->keepAnimation();
}void RDesktopTip::hideTip()
{if(!instance){return;}instance->hideAnimation();
}RDesktopTip::AnimationMode RDesktopTip::getMode()
{return mode;
}void RDesktopTip::setMode(RDesktopTip::AnimationMode newMode)
{if(mode!=newMode){mode=newMode;}
}void RDesktopTip::initAnimation()
{//透明度动画showOpacity=new QPropertyAnimation(this,"windowOpacity");//判断是否设置了此模式的动画if(mode&AnimationMode::OpacityAnimation){showOpacity->setDuration(1500);showOpacity->setStartValue(0);}else{showOpacity->setDuration(0);showOpacity->setStartValue(1);}showOpacity->setEndValue(1);showGroup->addAnimation(showOpacity);//位置动画showPos=new QPropertyAnimation(this,"pos");QScreen * screen = QGuiApplication::primaryScreen();if (screen) {const QRect desk_rect = screen->availableGeometry();const QPoint hide_pos{desk_rect.width()-this->width(),desk_rect.height()};const QPoint show_pos{desk_rect.width()-this->width(),desk_rect.height()-this->height()};//判断是否设置了此模式的动画if(mode&AnimationMode::PosAnimation){showPos->setDuration(1500);showPos->setStartValue(hide_pos);}else{showPos->setDuration(0);showPos->setStartValue(show_pos);}showPos->setEndValue(show_pos);}showGroup->addAnimation(showPos);//connect(showGroup,&QParallelAnimationGroup::finished,[this]{//back消失动画结束关闭窗口if(showGroup->direction()==QAbstractAnimation::Backward){//Qt::WA_DeleteOnClose后手动设置为nullinstance=nullptr;qApp->disconnect(this);//关闭时设置为非模态,方式主窗口被遮挡,待测试this->setWindowModality(Qt::NonModal);this->close();}else{//配合keepAnimationshowAnimEnd=true;//配合定时关闭if(hideCount>0)hideTimer->start();}});
}void RDesktopTip::initTimer()
{hideTimer=new QTimer(this);hideTimer->setInterval(1000); //1s间隔connect(hideTimer,&QTimer::timeout,[this]{if(hideCount>1){hideCount--;ui->btnClose->setText(QString("%1 S").arg(hideCount));}else{ui->btnClose->setText(QString("Close"));hideTimer->stop();hideTip();}});
}void RDesktopTip::readyTimer(int timeout)
{//先设置,在显示动画结束再start开始计时器hideCount=timeout;hideTimer->stop();if(hideCount>0){ui->btnClose->setText(QString("%1 S").arg(hideCount));}else{ui->btnClose->setText(QString("Close"));}
}void RDesktopTip::showAnimation()
{showGroup->setDirection(QAbstractAnimation::Forward);//停止正在进行的动画重新if(showGroup->state()==QAbstractAnimation::Running){showGroup->stop();}showGroup->start();show();
}void RDesktopTip::keepAnimation()
{//show没有完成,或者正在动画中才进入if(!showAnimEnd||showGroup->state()!=QAbstractAnimation::Stopped){showGroup->setDirection(QAbstractAnimation::Forward);showGroup->start();show();}
}void RDesktopTip::hideAnimation()
{//Backward反向执行动画showGroup->setDirection(QAbstractAnimation::Backward);showGroup->start();
}void RDesktopTip::setTextList(const QStringList &texts)
{QString tip_text("<p style='line-height:120%'>");for (const QString &text : texts){if (text.isEmpty())continue;tip_text += text + "<br>";}tip_text += "</p>";ui->contentLabel->setText(tip_text);
}

使用方式:

void ToolTipDemo::initDesktopTip()
{//待修改样式ui->desktopTipBox->setView(new QListView(this));//选择启用的动画ui->desktopTipBox->addItems({"All","No","Opacity","Pos"});connect(ui->desktopTipBox,QOverload<int>::of(&QComboBox::currentIndexChanged),[](int index){switch (index) {case 0: RDesktopTip::setMode(RDesktopTip::AllAnimation); break;case 1: RDesktopTip::setMode(RDesktopTip::NoAnimation); break;case 2: RDesktopTip::setMode(RDesktopTip::OpacityAnimation); break;case 3: RDesktopTip::setMode(RDesktopTip::PosAnimation); break;default: break;}});connect(ui->btnDesktopTipShow,&QPushButton::clicked,[=]{RDesktopTip::showTip({"这是 1 条信息","这是 1 条信息","这是 1 条信息","这是 1 条信息"},5); //只显示5s就消失});connect(ui->btnDesktopTipKeep,&QPushButton::clicked,[=]{RDesktopTip::keepTip({"这是 2 条信息","这是 2 条信息","这是 2 条信息","这是 2 条信息"}); //一直显示,直到点关闭});connect(ui->btnDesktopTipHide,&QPushButton::clicked,[=]{RDesktopTip::hideTip();});
}

Qt实现桌面右下角弹窗相关推荐

  1. QML实现桌面右下角弹窗

    实现效果 这次制作的桌面右下角弹窗,主要功能有透明度和位置动画.定时关闭.鼠标放在上面暂留. 实现思路 首先,我们需要获取桌面大小,然后 move 到右下角去,这里借助的 Screen: //初始位置 ...

  2. Qt 实现桌面右下角消息弹窗提示

    简单的做了一个类似QQ消息提示的消息弹窗提示的小模块,便于在系统后台程序提示检测的信息,使用Qt开发,设计整体思路是做一个无框架的widget,自己实现标题栏和内容栏,添加了向上移出,自动消隐退出效果 ...

  3. java socket实现桌面右下角弹窗_java实现桌面右下角弹窗效果

    最近需要一个java实现桌面弹窗的小功能,类似于电脑桌面右下角的小广告一样的功能,在csdn上找到一个很好的一个,功能很多,我去除了一点不需要的代码,改了下外观等. 修改后的代码如下: InfoUti ...

  4. java实现桌面右下角弹窗(模仿,类似于qq消息弹窗)

    最近需要一个java实现桌面弹窗的小功能,类似于电脑桌面右下角的小广告一样的功能,在csdn上找到一个很好的一个,功能很多,我去除了一点不需要的代码,改了下外观等. 原作者:https://www.c ...

  5. 结合C++,网页实现消息即时提醒(桌面右下角弹窗)

    吃饭的时候 ,突然有所感悟.欣喜若狂. 首先这个不是C++外框包含网页 , 避免webbrower与一些页面的操作的不兼容性. 就是不知道这么想的,我是不是第一个.不然也能称为是一个创新. 这个想法的 ...

  6. Qt实现桌面右下角放置窗体

    代码如下: Q_Widget * dlgRight = new Q_Widget(NULL);QDesktopWidget *deskTop=QApplication::desktop();auto ...

  7. 精仿 QQ 右下角弹窗 / 广告

    VC编写,带原版通知声音,可二次开发,100%一模一样. 1.当前版本仅支持单个广告弹出展示. 2.程序经过反复测试,目前能十分稳定地在目标机器右下角位置弹出所指定的广告. 3.百分百精仿,无论样式. ...

  8. Qt4.8.2 模仿QQ右下角弹窗提示

    今天在CSDN偶然看到一位前辈用JAVA写的QQ右下角弹窗提示,而自己正在学习Qt,所以也自己试着写一下,虽然代码乱的一塌糊涂,但最后还是能够运行了. 程序最终运行: 输入内容并点击确定的时候,从右下 ...

  9. 【Qt】Qt 开发桌面程序 ( Qt 版本 5.14.2 | 编辑 Qt 桌面按钮控件 | 修改按钮文本 | 为按钮添加点击事件 | 系统调用 | 去掉系统调用命令窗口 )

    文章目录 一.添加按钮控件 二.修改按钮文本 三.为按钮添加点击事件 ( 弹出对话框 ) 四.为按钮添加点击事件 ( 打开记事本 ) 五.为按钮添加点击事件 ( 打开计算器 ) 六.去掉系统调用时弹出 ...

  10. Qt双击桌面快捷方式激活并使程序窗口置于最前端

    方法二转载:https://blog.csdn.net/winstonyi/article/details/108737600 qt在桌面应用程序中,会存在一个问题,官方示例中也无提及,桌面快捷方式, ...

最新文章

  1. java使用htmlunit工具抓取js中加载的数据
  2. 关于EF查询表里的部分字段
  3. bat查看java进程 过滤_通过查找.BAT中使用的端口来终止进程
  4. Linux 基础学习大考核
  5. ASP.NET Core Razor生成Html静态文件
  6. java二叉树原理_史上最全二叉树遍历详解(Java实现,原理相同)
  7. tensorflow 77 tensorflow android版本demo win10 下 编译
  8. php-screw 安装,PHP_SCREW安装
  9. 我看肖老师的《明日世界-云端计算下的程序设计需求》视频时,做的简单笔记
  10. 一个老网络工程师给年轻工程师的十大忠告!
  11. 移动硬盘装ubuntu
  12. JAVA死磕系列 疯狂创客圈
  13. 数据分析能力的8个等级
  14. dream_c梦想标准化语言评估,孩子语言发展落后,诊断治疗需“量体裁衣”
  15. 改造WinRE 从隐藏分区安装Win7
  16. 鸿蒙电视如何播放手机上的歌,鸿蒙这么用 荣耀智慧屏联动手机的正确打开方式...
  17. CSS网页设计教程:表单Button的Outl…
  18. BUUCTF SimpleRev(涉及大小端序存储的问题)
  19. 隆鑫通用VOGE机车首届文化艺术节圆满落幕
  20. 光纤传输网和接入网一些知识

热门文章

  1. 中继器有何作用?它的工作原理是什么?-道合顺大数据Infinigo
  2. python圣诞节祝福_Pyhton表白代码——浪漫圣诞节
  3. 工作缺点和不足及措施_【工作中存在的问题和不足及改进措施】_工作中的不足与改进_工作中不足及改进措施...
  4. linux鼠标手势双dock,Linnx Mint 上使用触摸板手势
  5. 文本数据挖掘(Text Mining)
  6. 百度地图API详解之驾车导航
  7. 实施ERP系统需要注意哪些方面?
  8. ansys 英文路径 安装失败
  9. CSP - 201403-1 - 相反数 (C++)
  10. linux下对IP地址的转发和端口的伪装----利用iptables部署