Qt 实现Android Toast效果,qtwidgets和qtquick都能用

先做个自我介绍,业余编程菜狗一名,毕业于西南大学。。。。。。

一开始学习了安卓开发,用到过toast消息提示功能,后面在学习Qt开发,发现没有这个库,于是百度,发现了一个Toast库,但是使用起来显示效果一点都不好,不美观,链接如下

终于有了时间,决定来实现自己的Toast库,gitee链接->Qt_Lib_toast: 一个简单的用于Qt widgets与Qt quick的Toast库 (gitee.com)

qtquick移植效果图

最起码美观上符合了自己的审美,接下来上代码。

toast头文件 msgtoast.h

#ifndef MSGTOAST_H
#define MSGTOAST_H

#include <QWidget>
#include <QPushButton>
#include <QApplication>
#include <QScreen>
#include <QVector>
#include <QPropertyAnimation>
namespace ToastTime {
enum Time{
    ToastTime_short=1,
    ToastTime_long=3,
};
}
class Screen{
private:
    QString m_name;
    int m_width;
    int m_height;
public:
    Screen(QString name="main_screen",int width=1920,int height=1080);
    inline int width(){return m_width;}
    inline int height(){return m_height;}
};
class ToastMsg{
private:
    QString m_text;
    ToastTime::Time m_time;
public:
    inline ToastMsg(QString text,ToastTime::Time time):m_text(text),m_time(time){}
    inline QString text(){return m_text;}
    inline ToastTime::Time time(){return m_time;}
    inline int time_toInt(){return m_time*1000;}
    bool operator ==(const ToastMsg& msg);
};
class Toast : public QWidget
{
    Q_OBJECT

public:
    Q_INVOKABLE void makeText(QString text,ToastTime::Time time=ToastTime::Time::ToastTime_short);
    static void showMsg(QString text,ToastTime::Time time=ToastTime::Time::ToastTime_short);
    static Toast& instance();
    Q_INVOKABLE void exit();
private:
    Toast(QWidget *parent = nullptr);
    ~Toast();
    QPushButton *toast_info=nullptr;
    Screen *screen_info=nullptr;
    QString m_text;
    QVector<ToastMsg> toast_msg_list;
    int master_timer_id;
    int msg_timer_id;
    void fadeToastAnimation(int time);
    void raiseToastAnimation(int time);
    void adaptPage(int width,int height=40);
public slots:
    void addMsg(QString msg);
    void removeMsg(QString msg);
    void appExit();
    // QObject interface
protected:
    virtual void timerEvent(QTimerEvent *event) override;
};
#endif // MSGTOAST_H

 重要的代码在timerEvent函数里面

看cpp代码

#include "msgtoast.h"
Toast::Toast(QWidget *parent)
    : QWidget(parent)
{
    QScreen *scr=QApplication::primaryScreen();
    this->screen_info=new Screen(scr->name(),scr->availableSize().width(),scr->availableSize().height());
    this->toast_info=new QPushButton(this);
    this->toast_info->setFont(QFont("Microsoft YaHei"));
//    adaptPage(100);
    this->toast_info->setStyleSheet("border-radius:20px;background-color: #f8bba7");//toast外观
    this->setWindowFlags(Qt::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground);
    this->master_timer_id=startTimer(200);

}

void Toast::makeText(QString text, ToastTime::Time time)
{
    this->toast_msg_list.append(ToastMsg(text,time));
    //    qDebug()<<"add a msg:"<<text;
}

void Toast::showMsg(QString text, ToastTime::Time time)
{
    instance().makeText(text,time);
}

Toast &Toast::instance()
{
    static Toast instance;
    instance.show();
    return instance;
}

void Toast::exit()
{
    this->close();
}

Toast::~Toast()
{
    delete toast_info;
    delete screen_info;
    toast_msg_list.clear();
}

void Toast::fadeToastAnimation(int time)
{
    QPropertyAnimation *animation = new QPropertyAnimation(this,"windowOpacity");
    animation->setDuration(time);
    animation->setStartValue(1);
    animation->setEndValue(0);
    animation->start();
}

void Toast::raiseToastAnimation(int time)
{
    QPropertyAnimation *animation = new QPropertyAnimation(this,"windowOpacity");
    animation->setDuration(time);
    animation->setStartValue(0);
    animation->setEndValue(1);
    animation->start();
}

void Toast::adaptPage(int width, int height)
{
    if(width<50){
        this->toast_info->setGeometry(0,0,50,height);
    }else {
        this->toast_info->setGeometry(0,0,width,height);
    }
    this->toast_info->setStyleSheet("border-radius:"+QString::number(height/2)+"px;background-color: #f8bba7");
    this->setGeometry((screen_info->width()-toast_info->width())*0.5,screen_info->height()*0.85,toast_info->width(),toast_info->height());
}

void Toast::addMsg(QString msg)
{
    Toast::showMsg(msg);
}

void Toast::removeMsg(QString msg)
{
    this->toast_msg_list.removeOne(ToastMsg(msg,ToastTime::ToastTime_short));
}

void Toast::appExit()
{
    this->exit();
}

void Toast::timerEvent(QTimerEvent *event)
{
    if(event->timerId()==this->master_timer_id){
        if(this->toast_msg_list.length()>0){
            this->msg_timer_id=startTimer(this->toast_msg_list.first().time_toInt());
            killTimer(this->master_timer_id);//暂停监控
            adaptPage(this->toast_msg_list.first().text().toLocal8Bit().length()*7.5+30);
            this->toast_info->setText(this->toast_msg_list.first().text());
            raiseToastAnimation(100);
            this->setVisible(true);
        }else {
            this->setVisible(false);
        }
    }else if (event->timerId()==msg_timer_id) {
        this->toast_msg_list.removeFirst();
        killTimer(this->msg_timer_id);
        this->master_timer_id=startTimer(200);//开启监控
        fadeToastAnimation(100);
    }else {
        makeText("i don't know the toast timer id:"+QString::number(event->timerId()));
    }
}
Screen::Screen(QString name, int width, int height):m_name(name),m_width(width),m_height(height)
{

}

bool ToastMsg::operator ==(const ToastMsg &msg)
{
    if(this->m_text==msg.m_text){
        return true;
    }else {
        return false;
    }
}

由于是自己用的代码就没还有写注释,目前已经在qtwidget和qtquick实现使用。下面是一个简单的qtquick移植例子。

  1. 创建qtquick工程。
  2. 添加工程文件到项目中。
  3. 修改代码,由于使用了qtwidget,pro工程文件,添加qwidgets
QT += quick widgets

4.修改main文件

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>//添加用于支持setContextProperty函数
#include "msgtoast.h"//库文件
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QApplication app(argc, argv);//qtwidgets工程只能用QApplication

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("Toast",&Toast::instance());//将库注入到qml环境中
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

 5.修改qml文件

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5//导入控件库
Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    Button {
        id: button
        x: 407
        y: 110
        text: qsTr("Button")
        onClicked: {
            Toast.makeText(msg.text)//toast提示消息
        }
    }

    Rectangle {
        id: rectangle
        x: 28
        y: 55
        width: 294
        height: 95
        color: "#ffffff"
        border.color: "#7ce9d8"
        TextEdit {//输入提示消息
            id: msg
            text: qsTr("Text Edit")
            anchors.fill: parent
            font.pixelSize: 12
            wrapMode: Text.WordWrap
        }
    }
}

6.移植完成

本库也可以以lib库方式使用,并移植与qtwidgets项目上,具体方法不叙述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值