Qt桌面应用开发 第九天(综合项目一 飞翔的鸟)

news2025/1/14 9:56:36

目录

1.鸟类创建

2.鸟动画实现

3.鼠标拖拽

4.自动移动

5.右键菜单

6.窗口透明化


项目需求:

实现思路:

  1. 创建项目
  2. 导入资源
  3. 鸟类创建
  4. 鸟动画实现
  5. 鼠标拖拽实现
  6. 自动移动
  7. 右键菜单
  8. 窗口透明化

1.鸟类创建

①鸟类中包含鸟图片、鸟图片的最小值下标和最大值下标

class Bird : public QWidget
{
    Q_OBJECT
public:
    explicit Bird(QWidget *parent = nullptr);

    QPixmap m_Bird_Pix;//鸟显示的图片

    int min=1;//最小值图片下标
    int max=2;//最大值图片下标

signals:

public slots:
};

②将鸟的图片资源加载到对应项目下的文件中

Bird::Bird(QWidget *parent)
    : QWidget{parent}
{

    for(int i=0;i<this->max;i++)
    {
        QString path=QString(":/Image/%1.png").arg(i);
        this->m_Bird_Pix.load(path);
    }

    //设置鸟的尺寸
    this->setFixedSize(this->m_Bird_Pix.width(),this->m_Bird_Pix.height());
}

③将鸟类对象添加到主窗口中

MainScene::MainScene(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);

    this->m_Bird=new Bird;
    //将鸟对象设置到窗口中
    this->m_Bird->setParent(this);

    //设置窗口尺寸
    this->setFixedSize(this->m_Bird->width(),this->m_Bird->height());
}

MainScene::~MainScene()
{
    delete ui;
}

void MainScene::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //绘制鸟的图像
    painter.drawPixmap(0,0,this->m_Bird->m_Bird_Pix);
}

2.鸟动画实现

鸟类中:设置一个定时器,每0.7秒超时一次,超时后加载小鸟图片,并发出切图信号

class Bird : public QWidget
{
    Q_OBJECT
public:
    explicit Bird(QWidget *parent = nullptr);
    
    QPixmap m_Bird_Pix;//鸟显示的图片
    
    int min=1;//最小值图片下标
    int max=2;//最大值图片下标
    
    QTimer* timer;
    
    //执行动画函数
    void running();
signals:
    //代表正在做动画切图
    void changePix();
    
public slots:
};
Bird::Bird(QWidget *parent)
    : QWidget{parent}
{

    for(int i=0;i<this->max;i++)
    {
        QString path=QString(":/Image/%1.png").arg(i);
        this->m_Bird_Pix.load(path);
    }

    //设置鸟的尺寸
    this->setFixedSize(this->m_Bird_Pix.width(),this->m_Bird_Pix.height());
    
    this->timer=new QTimer(this);
    connect(this->timer,&QTimer::timeout,[=]{
        QString path=QString(":/Image/%1.png").arg(this->min++);
        //超时之后,加载图片
        this->m_Bird_Pix.load(path);
        
        if(this->min>this->max)
        {
            this->min=1;
        }
        //切图
        emit changePix();
    })
}

void Bird::running()
{
    //0.7秒切一次动画
    this->timer->start(70);
}

主程序中:只要小鸟对象发出切图信号,就刷新一次

MainScene::MainScene(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainScene)
{
    ui->setupUi(this);

    this->m_Bird=new Bird;
    //将鸟对象设置到窗口中
    this->m_Bird->setParent(this);

    //设置窗口尺寸
    this->setFixedSize(this->m_Bird->width(),this->m_Bird->height());
    
    //启动计时器,开始动画
    this->m_Bird->running();
    //监听鸟在切图的信号
    connect(this->m_Bird,&Bird::changePix,[=]{
        update();
    })
}

3.鼠标拖拽

1.获取鼠标(QMouseEvent)点击的位置相对于全局窗口的坐标(globalPos())

2.获取鸟类窗口的左上角定点位置

3.计算鼠标点击位置到鸟类窗口左上角的相对分量,这一分量是绝对的

void Bird::mousePressEvent(QMouseEvent *e)
{
    this->m_Pox=e->globalPos()-((QWidget*)this->parent())->frameGeometry().topLeft();
}

4.当鼠标拖拽到另一点时,鼠标点击位置可以获取到,相对分量也知道,鸟类窗口的位置即【鼠标点击位置-相对分量】

5.完成鼠标拖拽后,将鸟类窗口位置作为参数,发送窗口移动的信号

void Bird::mouseMoveEvent(QMouseEvent *e)
{
    emit this->moving(e->globalPos()-this->m_Pox);
}

6.主窗口,监听鸟类对象是否发送移动信号,发送信号就移动窗口位置

    //监听鸟的移动信号
    connect(this->m_Bird,&Bird::moving,[=](QPoint point){
            this->move(point);
    });

4.自动移动

1.创建自动移动点位和定时器

    //自动移动位置
    QPoint m_Auto_Pos;
    
    //自动移动定时器
    QTimer* timer;

2.获取主屏幕宽度

    //获取屏幕
    QDesktopWidget* desk=QApplication::desktop();
    int deskWidth=desk->width();

3.自动移位定时器超时,则将自动移动点位的x坐标加5,不断向右移动【当自动移动点位的x坐标超过主屏幕大小时,将自动移动点位的x坐标设置为鸟类窗口宽度的负数】

    this->timer=new QTimer(this);
    timer->start(30);
    
    //超时后将窗口x坐标加5,不断向右移动,超过主屏幕时,将移动位置设为当前窗口宽度的负数
    connect(this->timer,&QTimer::timeout,[=]{
        this->m_Auto_Pos.setX(m_Auto_Pos.x()+5);
        
        if(this->m_Auto_Pos.x()>desk->width())
        {
            this->m_Auto_Pos.setX(-this->width());
        }
        
        this->move(this->m_Auto_Pos);
    };

4.将窗口移动到自动移动点位的位置

【优化】上述代码,鼠标按下时,图像也会自由移动,现优化为鼠标按下时,不移动图像

1.添加鼠标是否按下的标识

    //鼠标按下的状态
    bool mouseDown=false;

2.鼠标按下事件中,将mouseDown置为true,鼠标释放事件中,将mouseDown置为false

void Bird::mouseReleaseEvent(QMouseEvent *e)
{
    this->mouseDown=false;
}

void Bird::mousePressEvent(QMouseEvent *e)
{
    this->mouseDown=true;
    this->m_Pox=e->globalPos()-((QWidget*)this->parent())->frameGeometry().topLeft();
}

3.鼠标按下状态mouseDown=false时,才可以自由移动

    //超时后将窗口x坐标加5,不断向右移动,超过主屏幕时,将移动位置设为当前窗口宽度的负数
    connect(this->timer,&QTimer::timeout,[=]{
        //鼠标不是按下的状态时,才可以自由移动
        if(this->m_Bird->mouseDown==false)
        {
            this->m_Auto_Pos.setX(m_Auto_Pos.x()+5);
        }
        
        if(this->m_Auto_Pos.x()>desk->width())
        {
            this->m_Auto_Pos.setX(-this->width());
        }
        
        this->move(this->m_Auto_Pos);
    };

5.右键菜单

1.创建菜单

    this->m_menu=new QMenu();
    
    connect(this->m_menu->addAction("退出"),&QAction::triggered,[=]{
        exit(0);
    });

2.鼠标按下后,判断按键,如果是右键,则弹出菜单

void Bird::mousePressEvent(QMouseEvent *e)
{
    this->mouseDown=true;
    this->m_Pox=e->globalPos()-((QWidget*)this->parent())->frameGeometry().topLeft();
    
    if(e->button()==Qt::RightButton)
    {
        //将菜单弹到光标位置处
        this->m_menu->popup(QCursor::pos());
    }
}

3.菜单如果消失,也要将鼠标按下状态置为false

void Bird::mousePressEvent(QMouseEvent *e)
{
    this->mouseDown=true;
    this->m_Pox=e->globalPos()-((QWidget*)this->parent())->frameGeometry().topLeft();
    
    if(e->button()==Qt::RightButton)
    {
        //将菜单弹到光标位置处
        this->m_menu->popup(QCursor::pos());
    }
    
    //菜单消失后,将鼠标按下状态置为false
    connect(this->m_menu,&QMenu::aboutToHide,[=]{
        this->mouseDown=false;
    })
}

6.窗口透明化

1.去掉标题栏

     //去掉标题栏
    this->setWindowFlags(Qt::FramelessWindowHint);

2.设置透明窗体

    //设置透明窗体
    this->setAttribute(Qt::WA_TranslucentBackground);

3.窗口设置到顶层(鼠标如果点击,鸟会消失,其实鸟隐藏在页面的下一层,设置之后,鸟永远在页面最顶层,不会消失)

    //窗口设置到顶层(鼠标如果点击,鸟会消失,其实鸟隐藏在页面的下一层,设置之后,鸟永远在页面最顶层,不会消失)
    this->setWindowFlags(this->windowFlags()|Qt::WindowStaysOnTopHint);

 4.设置起始Y位置,从主窗口中间出现

    //设置起始Y位置,从主窗口中间出现
    this->m_Auto_Pos.setY(desk->height()*0.5-this->m_Bird->height());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2252095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【实体配置】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…

Pytorch-GPU版本离线安装

最近在复现一项深度学习的工作&#xff0c;发现自己的pytorch是装的cpu版的(好像当时是直接加清华源&#xff0c;默认是cpu版本&#xff09;。从官网在线下载速度太慢&#xff0c;还时不时断开连接&#xff0c;我们可以配置conda的清华源去这个问题&#xff0c;但是考虑到是在用…

聊聊Flink:这次把Flink的触发器(Trigger)、移除器(Evictor)讲透

一、触发器(Trigger) Trigger 决定了一个窗口&#xff08;由 window assigner 定义&#xff09;何时可以被 window function 处理。 每个 WindowAssigner 都有一个默认的 Trigger。 如果默认 trigger 无法满足你的需要&#xff0c;你可以在 trigger(…) 调用中指定自定义的 tr…

[Redis#12] 常用类型接口学习 | string | list

目录 0.准备 1.string get | set set_with_timeout_test.cpp set_nx_xx_test.cpp mset_test.cpp mget_test.cpp getrange_setrange_test.cpp incr_decr_test.cpp 2.list lpush_lrange_test.cpp rpush_test.cpp lpop_rpop_test.cpp blpop_test.cpp llen_test.cpp…

网络安全之IP伪造

眼下非常多站点的涉及存在一些安全漏洞&#xff0c;黑客easy使用ip伪造、session劫持、xss攻击、session注入等手段危害站点安全。在纪录片《互联网之子》&#xff08;建议搞IT的都要看下&#xff09;中。亚伦斯沃茨&#xff08;真实人物&#xff0c;神一般的存在&#xff09;涉…

Spring Web开发(请求)获取JOSN对象| 获取数据(Header)

大家好&#xff0c;我叫小帅今天我们来继续Spring Boot的内容。 文章目录 1. 获取JSON对象2. 获取URL中参数PathVariable3.上传⽂件RequestPart3. 获取Cookie/Session3.1 获取和设置Cookie3.1.1传统获取Cookie3.1.2简洁获取Cookie 3. 2 获取和存储Session3.2.1获取Session&…

(SAST检测规则-1)Android - 权限管理漏洞

所属分类&#xff1a;Android - 权限管理漏洞缺陷详解&#xff1a;应用未正确实施最小权限原则或滥用已声明的权限可能导致敏感信息泄露。例如&#xff0c;恶意代码利用已授予的权限绕过用户授权&#xff0c;访问通讯录、位置、短信等敏感资源。部分开发者还可能滥用权限以执行…

EC2还原快照

EC2还原快照 AWS EC2 磁盘快照 是您 Amazon Elastic Block Store (EBS) 卷在特定时间点的增量备份。您可以使用快照创建 EBS 卷的副本&#xff0c;以便在出现故障时恢复数据或将数据迁移到其他区域。 创建磁盘快照 找到ec2实例挂载的磁盘&#xff0c;直接选择创建快照 等待创建…

oracle RAC各版本集群总结和常用命令汇总

oracle RAC学习 RAC介绍 RAC&#xff1a;高可用集群&#xff0c;负载均衡集群&#xff0c;高性能计算集群 RAC是⼀种⾼可⽤&#xff0c;⾼性能&#xff0c;负载均衡的share-everything的集群 8i:内存融合雏形 内存融合雏形&#xff08;Oracle Parallel Server&#xff09;…

【聚类】K-Means 聚类(无监督)及K-Means ++

1. 原理 2. 算法步骤 3. 目标函数 4. 优缺点 import torch import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.decomposition import PCA import torch.nn as nn# 数据准备 # 生成数据&#xff1a;100 个张量&#xff0c…

智慧银行反欺诈大数据管控平台方案(一)

智慧银行反欺诈大数据管控平台建设方案的核心在于通过整合先进的大数据技术和深度学习算法&#xff0c;打造一个全面、智能且实时的反欺诈系统&#xff0c;以有效识别、预防和应对各类金融欺诈行为。该方案涵盖数据采集、存储、处理和分析的全流程&#xff0c;利用多元化的数据…

搭建业务的性能优化指南

这是一篇搭建业务优化的心路历程&#xff0c;也是写给搭建业务的性能优化指南。 前言 直到今天&#xff0c;淘内的页面大多都迁移到了 SSR&#xff0c;从我们终端平台 - 搭建研发团队的视角看&#xff0c;业务大致可以分为两类 —— 搭建派 和 源码派。 这两者互不冲突&#xf…

【Db First】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…

搭建私有云存储

1、安装LNMP环境 yum install nginx -y yum install -y nginx mariadb-server php php-fpm php-mysqlnd systemctl restart nginx.service --- 启动Nginx systemctl start mariadb.service ---启动数据库 mysql -e create database lxdb character set utf8 ---创建数据库 my…

YOLO 标注工具 AutoLabel 支持 win mac linux

常见的标注工具&#xff0c;功能基础操作繁琐&#xff0c;无复制粘贴&#xff0c;标签无法排序修改&#xff0c;UI不美观&#xff0c;bug修正不及时&#xff0c;没有集成识别、训练、模型导出… 怎么办呢&#xff1f;AutoLabel它来了 Quick Start 一图胜千言 图像标注 支持YOL…

qt QGraphicsPolygonItem详解

1、概述 QGraphicsPolygonItem是Qt框架中QGraphicsItem的一个子类&#xff0c;它提供了一个可以添加到QGraphicsScene中的多边形项。通过QGraphicsPolygonItem&#xff0c;你可以定义和显示一个多边形&#xff0c;包括其填充颜色、边框样式等属性。QGraphicsPolygonItem支持各…

Linux网络_网络协议_网络传输_网络字节序

一.协议 1.概念 协议&#xff08;Protocol&#xff09; 是一组规则和约定&#xff0c;用于定义计算机网络中不同设备之间如何进行通信和数据交换。协议规定了数据的格式、传输方式、传输顺序等详细规则&#xff0c;确保不同设备和系统能够有效地互联互通。 在网络通信中&#…

MySQL查看日志

目录 1. 日志 1.1 错误日志 1.2 二进制日志 1.2.1 介绍 1.2.2 格式 1.2.3 查看 1.2.4 删除 1.3 查询日志 1.4 慢查询日志 1. 日志 1.1 错误日志 错误日志是 MySQL 中最重要的日志之一&#xff0c;它记录了当 mysqld 启动和停止时&#xff0c;以及服务器在运行过…

【深度学习】四大图像分类网络之AlexNet

AlexNet是由Alex Krizhevsky、Ilya Sutskever&#xff08;均为Hinton的学生&#xff09;和Geoffrey Hinton&#xff08;被誉为”人工智能教父“&#xff0c;首先将反向传播用于多层神经网络&#xff09;在2012年ImageNet图像分类竞赛中提出的一种经典的卷积神经网络。AlexNet在…

MySQL数据库做题笔记

题目链接https://leetcode.cn/problems/invalid-tweets-ii/description/https://leetcode.cn/problems/invalid-tweets-ii/description/ # Write your MySQL query statement below SELECT tweet_id FROM Tweets where LENGTH(content)>140 OR (length(content)-length(rep…