一、前言
好久没写博客了,最近一直写材料,很难受,在家做点小东西,正好遇到了想做的效果,在桌面程序实现Android的toast效果
二、环境
目标机linux,测试机window10
qt5.7
本文参考连接
我的Android toast效果实现方法
三、正文
我需求的和心目中的toast有两种效果:
第一种是比较常规的Androidtoast效果,也是比较简单实现,主要参考以上连接,操作部分稍加修改,可以无线连续点击,不会造成内存堆积。下面是实现效果和方法。
cpp?
#include "mytoast.h"
#include <QGuiApplication>
#include <QScreen>
Mytoast::Mytoast(QWidget*parent):QLabel(parent)
{
//设置样式
this->setStyleSheet("background-color: rgba(40, 40, 40, 140);color: rgb(255, 255, 255);border-radius:4px");
//居中对齐
this->setAlignment(Qt::AlignCenter);
//隐藏
this->hide();
//信号和槽
connect(this->timer,&QTimer::timeout,this,&Mytoast::time_toast);
}
//第一个参数为弹窗内容
//第二个参数为持续时间ms,默认-1不消失,需调用stop关闭或重新start
void Mytoast::start(QString str, int time)
{
//关闭上次弹窗的定时器
if(timer->isActive())timer->stop();
//计算字体的宽度和高度,字体可以自己更换
QFontMetrics metrics(QFont("黑体",16));
int text_width = metrics.width(str);
int text_height = metrics.height();
//设置弹窗大小,增加一些像素更美观一点
this->resize(text_width+16,text_height+12);
//设置弹窗内容
this->setText(str);
//设置弹窗字体,注意一定要和上面的相同
this->setFont(QFont("黑体",16));
//设置位置居中父级窗体
int p_x = int((this->parentWidget()->width()-this->width())/2);
int p_y = int((this->parentWidget()->height()-this->height())/2);
this->move(p_x,p_y);
//time为-1时不关闭
if(time == -1){
this->show();
}
//启动定时器
else{
this->show();
this->timer->start(time);
}
}
//主动调用关闭弹窗,用于time=-1的情况
void Mytoast::stop()
{
this->timer->stop();
this->close();
}
//定时关闭函数
void Mytoast::time_toast()
{
this->timer->stop();
this->close();
}
h?
#ifndef MYTOAST_H
#define MYTOAST_H
#include <QLabel>
#include <QTimer>
#include "main.h"
//继承QLabel类,父级窗体为QWidget类及派生类
class Mytoast:public QLabel
{
Q_OBJECT
public:
Mytoast(QWidget*parent);
void start(QString str ,int time =-1);
void stop();
private slots:
void time_toast();
private:
QTimer *timer = new QTimer;
QPixmap pic;
};
#endif // MYTOAST_H
调用cpp
///显示三级提示框toast(暂时未实现渐变效果、界面外显示、变更长条背景)
void MessageBox2::showtoast(QString str,int time)
{
//删除上次toast
QList<Mytoast*> List = this->findChildren<Mytoast*>();
for(int i=0;i<List.size();i++)delete List[i];
//新建toast
Mytoast * box = new Mytoast(this);
box->setAttribute(Qt::WA_DeleteOnClose);//若是关闭界面,则彻底释放资源
box->start(str,time);
}
方式一的实现比较简单,没加动画效果,不能界面外显示,背景单一,方式二会升级
第二种方式就是我需要的在第一种方式基础上升级,将其升级为可以在 界面任意地方设置显示,包括在小界面的外部,界面背景可以自定义为渐变色或者图片的形式,并且具有逐渐消失的动画效果,再次有新的toast弹出时,会瞬间高亮,然后重新开始逐渐消失,新的提示出来,杀掉之前的toast界面,不会覆盖显示,并且界面会一直保持在顶层,不会被新聚焦的底层界面覆盖。下面是实现效果和方法。
原理倒是没什么复杂的,就是遇到一些问题卡住了,最终是如愿实现了效果,无论是toast显示在此界面还是界面外,都会有信息保持在顶层显示,直到显示完毕自动隐藏,两种方式的源码资源可下载?
下面贴关键代码,很简单的
mytoast_form.cpp
#include "mytoast_form.h"
#include "ui_mytoast_form.h"
#include <qDebug>
mytoast_form::mytoast_form(QString name, int time,QWidget *parent) :
QWidget(parent),
ui(new Ui::mytoast_form)
{
ui->setupUi(this);
// this->setWindowModality(Qt::ApplicationModal);//设置一直保持在顶端,不可切换其他界面,除非被新界面带此属性覆盖
this->setWindowFlags(Qt::FramelessWindowHint);//设置窗体无边框
this->setAttribute(Qt::WA_TranslucentBackground);//设置背景透明
this->setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint);//界面在最前方,覆盖其他界面
ui->label->setText(name);
this->move(800,1200);
QPropertyAnimation *animation = new QPropertyAnimation(this,"windowOpacity");
animation->setDuration(time);
animation->setStartValue(1);
animation->setEndValue(0);
animation->start();
timer->start(time);
connect(timer,&QTimer::timeout,[=](){
timer->stop();
this->close();
});
}
mytoast_form::~mytoast_form()
{
delete ui;
}
mytoast_form.h
#ifndef MYTOAST_FORM_H
#define MYTOAST_FORM_H
#include <QWidget>
#include <QPropertyAnimation>
#include <QLabel>
#include <QTimer>
namespace Ui {
class mytoast_form;
}
class mytoast_form : public QWidget
{
Q_OBJECT
public:
explicit mytoast_form(QString name, int time, QWidget *parent = 0);
~mytoast_form();
private:
Ui::mytoast_form *ui;
QTimer *timer = new QTimer;
};
#endif // MYTOAST_FORM_H
执行cpp
//删除上次toast,不能直接删除界面会崩溃,先隐藏,之后等待时间结束自动删除
QWidgetList aaa=QApplication::allWidgets();
// qDebug()<<QString::number(aaa.size());
for(int i=0;i<aaa.size();i++){
if(aaa.at(i)->objectName()=="mytoast_form"){
aaa.at(i)->hide();
}
}
//新建toast
mytoast_form * box = new mytoast_form("这是一个测试文本!!!",2000);
box->show();
box->setAttribute(Qt::WA_DeleteOnClose);//若是关闭界面,则彻底释放资源
四、结语
学而时习之,不亦说乎
|