自学内容网 自学内容网

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

目录

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());


原文地址:https://blog.csdn.net/m0_53349772/article/details/144071314

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!