Qt实战项目学习5———横冲直撞的阿呆

一.鸟类

1.鸟类创建

首先将资源文件加载出。加载多张连续图片时,可将资源文件命名时添加1,2等顺序,加载时使用for循环即可

bird.h中声明及.cpp中实现

QPixmap m_Bird_pix;   //鸟的图片
    int min=1;
    int max=8;//最大最小图片下标
//加载所有鸟类资源
    for(int i=0;i<8;i++)
    {
        QString str=QString(":/bird%1.png").arg(i+1);
        this->m_Bird_pix.load(str);
    }

2.动画实现

在bird类中开启定时器,载入所有图片,并向主场景发射信号。主场景监听信号,通过不断调用绘图事件实现动画的完成

bird.cpp中

//创建定时器对象
    this->timer=new QTimer(this);

    //监听定时器信号
    connect(timer,&QTimer::timeout,[=](){
        QString str=QString(":/bird%1.png").arg(this->min++);
        this->m_Bird_pix.load(str);
        //判断
        if(this->min>this->max)
        {
            this->min=1;
        }
        emit changepix();
    });

mainsence中

//定时器启动
    this->m_bird->running();

    //监听鸟切图的信号
    connect(this->m_bird,&Bird::changepix,[=](){
        update();   //调用绘图事件
    });

//绘图事件重写
void MainSence::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawPixmap(0,0,this->m_bird->m_Bird_pix);

}

3.菜单栏创建 

 //创建菜单
    menu=new QMenu();
    connect(menu->addAction("退出"),&QAction::triggered,[=](){
        exit(0);
    });

二.鼠标拖拽实现

1.原理

首先明白其原理:当鼠标拖拽时,光标相对于屏幕原点的位置gpos改变,同时窗体相对屏幕原点位置fpos改变,但其相减后的分量m_pos为固定。

通过不变的m_pos以及能够获取到的gpos求出当前窗体位置即可

2.实现

bird.h中记录鼠标是否摁下及分量坐标

 //记录鼠标按下状态
    bool mouseDown=false;
 //记录分量的坐标
    QPoint m_pos;

 重写鼠标按下事件获取实时分量坐标

event->globalPos()     获取的鼠标位置是鼠标偏离电脑屏幕左上角(x=0,y=0)的位置;

 QCursor类提供具有任意形状的鼠标光标。

QCursor::pos返回主屏幕的光标(热点)在全局屏幕坐标中的位置

void popup(parent, point pos, MenuItem item = null):在弹出式坐标系中指定位置pos处打开菜单,即相对于其父项的坐标 

menu->exec(QCursor::pos());  也能达到菜单跟随鼠标效果

按下过程中获取分量坐标,并实现鼠标右键菜单 

bird.cpp中    求出分量

void Bird::mousePressEvent(QMouseEvent *e)
{
    mouseDown=true;
    //鼠标摁下的时候记录分量
    this->m_pos=e->globalPos()-((QWidget*)this->parent())->frameGeometry().topLeft();

    //如果是鼠标右键,弹出菜单
    if(e->button()==Qt::RightButton)
    {
        this->menu->popup(QCursor::pos());   //菜单弹出 弹出与鼠标当前一样位置
    }
    //如果菜单通过别的方式消失,鸟应该继续向前飞
    connect(this->menu,&QMenu::aboutToHide,[=](){
        this->mouseDown=false;
    });
}

发射信号 

void Bird::mouseMoveEvent(QMouseEvent *e)
{
    //移动过程中反向获取窗口位置
    emit this->moving(e->globalPos()-this->m_pos);
}

//释放后修改鼠标状态
void Bird::mouseReleaseEvent(QMouseEvent *e)
{
    mouseDown=false;
}

主场景中接收信号

//监听鸟拖拽信号
    connect(this->m_bird,&Bird::moving,[=](QPoint point){
        this->move(point);

        //鼠标拖拽时更新当前窗口位置
        m_auto_pos=point;
    });

mainsence中开启定时器,实现鸟的自动移动

//创建自动移动定时器对象
    this->timer=new QTimer(this);
//启动定时器
    this->timer->start(30);
 //获取屏幕信息
     QScreen*screen= QGuiApplication::primaryScreen();

//监听定时器
    connect(timer,&QTimer::timeout,[=](){

//如果鼠标没有按下才自动移动
    if(this->m_bird->mouseDown !=true)
      {
            this->m_auto_pos.setX(this->m_auto_pos.x()+5);  //每隔30毫秒移动5像素
       }
//超出屏幕飞回
     if(this->m_auto_pos.x()>screen->geometry().width())
      {
            this->m_auto_pos.setX(-this->m_bird->width());
       }
//窗口同步移动
    this->move(this->m_auto_pos);  });

三.窗口的透明化设置

//去掉标题栏
    this->setWindowFlag(Qt::FramelessWindowHint);
    //设置透明窗体,120号属性
    this->setAttribute(Qt::WA_TranslucentBackground);
    //设置窗口顶层
    this->setWindowFlags(this->windowFlags() |Qt::WindowStaysOnTopHint);
    //设置起始坐标
    this->m_auto_pos.setY(screen->geometry().height()*0.5-this->m_bird->height());

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值