当前位置: 首页 > news >正文

基于qt的桌面宠物——纳西妲源码纯享

本专栏会不定时更新,如果有有趣的C++代码或者编程可以在评论区留言,我会尽量满足粉丝的要求,同时还希望看到的朋友点个赞/收藏(感谢/感谢)

代码

main.cpp:

#include "widget.h"

#include <QApplication>
#include<QSystemTrayIcon>
#include<QIcon>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    QSystemTrayIcon sysTray(QIcon("://img/icon.png"),&w);

    QMenu menu;
    auto showAct=new QAction("show",&sysTray);
    auto exitAct=new QAction("exit",&sysTray);

    QObject::connect(showAct,&QAction::triggered,[&](){
        w.setVisible(true);
    });
    QObject::connect(exitAct,&QAction::triggered,[&](){
        QApplication::quit();
    });

    menu.addAction(showAct);
    menu.addAction(exitAct);

    sysTray.setContextMenu(&menu);

    sysTray.show();
    w.show();
    return a.exec();
}

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QMap>
#include<QList>
#include<QUrl>
#include<QTimer>
#include<QEvent>
#include<QMouseEvent>
#include<QContextMenuEvent>
#include<QMenu>

class QPaintEvent;

namespace Act {
Q_NAMESPACE

enum RoleAct{
    Swing,
    Sleep,
    SayHello
};
Q_ENUM_NS(RoleAct)

}

using namespace  Act ;

class Widget : public QWidget
{
    Q_OBJECT

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

public:
    void showActAnimation(RoleAct k);

public slots:
    void onMenuTriggered(QAction* action);

protected:
    void paintEvent(QPaintEvent* event)override;
    void contextMenuEvent(QContextMenuEvent* event);

private:
    void loadRoleActRes();
    void initMenu();

private:
    QMap<RoleAct,QList<QUrl>> action_map;
    QTimer* timer;
    RoleAct cur_role_act;
    QUrl cur_role_pix;
    QMenu* menu;
};

class DragFilter:public QObject{

public:
    bool eventFilter(QObject* obj,QEvent* event)
    {
        auto w=dynamic_cast<QWidget*>(obj);
        if(!w)
            return false;

        if(event->type()==QEvent::MouseButtonPress)
        {
            auto e=dynamic_cast<QMouseEvent*>(event);
            if(e)
            {
                pos=e->pos();
            }
        }
        else if(event->type()==QEvent::MouseMove)
        {
            auto e=dynamic_cast<QMouseEvent*>(event);
            if(e)
            {
                if(e->buttons()&Qt::MouseButton::LeftButton)
                {
                    w->move(e->globalPos()-pos);
                }
            }
        }
        return QObject::eventFilter(obj,event);
    }

private:
    QPoint pos;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include<QPaintEvent>
#include<QPainter>//绘图
#include<QPixmap>//图片
#include<QCursor>
#include<QMetaEnum>


Widget::Widget(QWidget *parent)
    : QWidget(parent),
    timer(new QTimer(this)),
    menu(new QMenu(this))
{
    this->setWindowFlag(Qt::FramelessWindowHint);//去除窗口边框
    this->setAttribute(Qt::WA_TranslucentBackground);//背景透明

    this->installEventFilter(new DragFilter);

    connect(timer,&QTimer::timeout,[this](){
        static int index=0;//记录显示动作的当前图片索引
        auto paths = this->action_map.value(this->cur_role_act);
        this->cur_role_pix=paths[index++ % paths.size()];
        //paintEvent() 不允许的
        this->update();

    });

    initMenu();

    loadRoleActRes();

    showActAnimation(RoleAct::Swing);
}

Widget::~Widget() {}

void Widget::showActAnimation(RoleAct k)
{
    timer->stop();

    this->cur_role_act=k;

    timer->start(60);
}

void Widget::onMenuTriggered(QAction *action)
{
    QMetaEnum me=QMetaEnum::fromType<RoleAct>();

    bool ok;
    int k =  me.keyToValue(action->text().toStdString().c_str(),&ok);
    if(!ok)
      return;

    showActAnimation(static_cast<RoleAct>(k));
}

void Widget::paintEvent(QPaintEvent *event)
{

    QPainter painter(this);

    QPixmap pix;
    pix.load(this->cur_role_pix.toLocalFile());

    painter.drawPixmap(0,0,pix);

}

void Widget::contextMenuEvent(QContextMenuEvent *event)
{
    this->menu->popup(QCursor::pos());
}

void Widget::loadRoleActRes()
{
    auto addRes=[this](RoleAct k,QString path,int count)
    {
        QList<QUrl> paths;
        char buf[260];
        for (int i = 0; i < count; ++i) {
            memset(buf, 0,sizeof(buf));
            sprintf_s(buf,path.toStdString().c_str(),i);
            paths.append(QUrl::fromLocalFile(buf));
        }
        action_map.insert(k,paths);
    };

    addRes(RoleAct::SayHello,"D:/001/pet/img/sayHello/sayHello_%d.png",28);
    addRes(RoleAct::Swing,"D:/001/pet/img/swing/swing_%d.png",32);
    addRes(RoleAct::Sleep,"D:/001/pet/img/sleep/sleep_%d.png",25);
}

void Widget::initMenu()
{
    menu->addAction("SayHello");
    menu->addAction("Sleep");
    menu->addAction("Swing");

    QAction* act=new QAction("Hide");
    connect(act,&QAction::triggered,[this](){
        this->setVisible(false);
    });

    menu->addAction(act);

    connect(this->menu,&QMenu::triggered,this,&Widget::onMenuTriggered);
}

演示:

右键会出现四个选项:

点击相应图标会有不同动作。

sleep:

hello:

打包参考文章:Qt程序发布完整教程以及打包成exe文件【小白版】_qt发布可执行程序-CSDN博客

需要代码的可以评论区留言,私聊。

相关文章:

  • CS144 Lab Checkpoint 5: down the stack (the network interface)
  • http status是什么?常见的http状态码指的是什么意思?
  • FPGA开发,使用Deepseek V3还是R1(9):FPGA的全流程(详细版)
  • C语言_图书管理系统_借阅系统管理
  • 极狐GitLab 17.9 正式发布,40+ DevSecOps 重点功能解读【三】
  • 毕业项目推荐:基于yolov8/yolov5/yolo11的暴力行为检测识别系统(python+卷积神经网络)
  • C# Unity 唐老狮 No.6 模拟面试题
  • DRMPlaneType里有VIG, DMA,和RGB三种类型,这是不是说明DRMPlane就是代表DPU里的Pipeline
  • ESP32S3读取数字麦克风INMP441的音频数据
  • 尚庭公寓项目记录
  • el-tree右键节点动态位置展示菜单;el-tree的节点图片动态根据节点属性color改变背景色;加遮罩层(opacity)
  • 数据挖掘校招面经一
  • 算法比赛中处理输入和输出
  • rabbitmq版本升级并部署高可用
  • JDBC、MyBatis 、MyBatis-Plus面试总结(一)
  • 【第14节】C++设计模式(行为模式)-Strategy (策略)模式
  • Spring Boot WebFlux 中 WebSocket 生命周期解析
  • 小程序分类页面
  • 字符串(三)14. 最长公共前缀 简单
  • 计算机网络面试题
  • 泉州网站seo公司/google seo 优化教程
  • 1号网站建设 高端网站建设/怎么做网站排名
  • 做服装外贸网站/百度一级代理商
  • 网站设计学习/前端seo是什么意思
  • 网站域名证书/长春关键词优化平台
  • 做视频赚钱的网站/整站优化关键词推广