small bird

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

    this->setAttribute(Qt::WA_TranslucentBackground);  //窗口透明化

    //
    this->setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint);//设置窗口最顶层

this->setWindowIcon(abc);//设置窗口图标

“用鼠标全局坐标的位置减去父窗口的左上角位置”,这正是这段代码所做的。这种计算方式常用于实现拖拽窗口的功能,特别是当窗口没有标准的标题栏时。通过这种方式,你可以确定鼠标相对于父窗口的位置,进而实现拖拽窗口的功能

event->globalPos():
获取鼠标光标在全局坐标系中的位置。
((QWidget*)this->parent())->frameGeometry().topLeft():
获取父窗口左上角的位置。
event->globalPos() - ((QWidget*)this->parent())->frameGeometry().topLeft():
计算鼠标光标在全局坐标系中的位置与父窗口左上角位置之间的差值。
m_pos = ...:
将计算得到的差值赋给 m_pos,m_pos 是一个 QPoint 类型的成员变量,表示鼠标光标相对于父窗口左上角的位置。
void Bird_::mouseMoveEvent(QMouseEvent *event)
{

    //获取窗口的gai变量

    this->m_pos= event->globalPos()-this->m_pos;


    emit aftermove(m_pos);
    //
}
//((QWidget*)this->parent())->frameGeometry().topLeft();  获取当前窗口左上角的坐标
void Bird_::mousePressEvent(QMouseEvent *event)
{
    //用鼠标全局坐标的位置减去父窗口的左上角位置
    m_pos = event->globalPos()   - ((QWidget*)this->parent())->frameGeometry().topLeft();
}

 if(this->auto_pos.x()>QGuiApplication::primaryScreen()->geometry().width())
        {
            this->auto_pos.setX(-this->width());
            //  需要减去一个尺寸从屏幕左边飞过来        //超出屏幕 x设为 窗口的-宽度
        }

当前位置 为屏幕的尺寸的宽度就可  到达最右侧 将 x置为最左侧的-1倍

bird.cpp 及 bird.h

#ifndef BIRD__H
#define BIRD__H

#include <QWidget>
#include <QPixmap>//显示图片
#include <QTimer>
#include <QMouseEvent>
#include <QMenu>
class Bird_ : public QWidget
{
    Q_OBJECT
public:
    explicit Bird_(QWidget *parent = nullptr);

    QPixmap m_bird;

    int min =1;  //最小值图片下标
    int max = 8;//最大值图片下标  从1切到8实现飞翔的效果

    QTimer *timer;
    bool qmousedown =false; //刚开始并没有按下
bool movingRight;

    QPoint m_pos;//记录当前左边

    QMenu * menu;


    virtual void mouseMoveEvent(QMouseEvent *event); //移动事件
    virtual void mousePressEvent(QMouseEvent *event);//按下事件
    virtual void mouseReleaseEvent(QMouseEvent *event);
void reverseDirection();
    void running();
signals:

    void changepix();//告诉主场景正在改变图片显示  信号不用显示


    void aftermove(QPoint cc);//拖拽后 主场景移动的位置
};

#endif // BIRD__H

bird.cpp

#include "bird_.h"

Bird_::Bird_(QWidget *parent)
    : QWidget{parent}
{
    //需要提前加载图片

    // m_bird = new QPixmap();

    for(int i =0 ; i<8;i++)
    {
        //第一次string  = bird1 第二次bird2
        QString str = QString("./bird/bird%1").arg(i+1);  //%1占位符   arg用作填补占位
        this->m_bird.load(str);
    }

    this->setFixedSize(this->m_bird.width(),this->m_bird.height());//设置窗口尺寸为图片的高度和宽度


    timer = new QTimer(this);

    //监听信号
    //每隔1秒发送 timeout信号
    connect(timer,&QTimer::timeout,[this](){
        QString str = QString("./bird/bird%1").arg(this->min++);
        this->m_bird.load(str);
        if(this->min>max)
        {
            this->min = 1;
        }
        //发出信号
        emit       changepix();
    });

    menu = new QMenu;
    // this->menu->addAction("退出")添加菜单项(退出)

    //菜单项 trigger信号

    connect(this->menu->addAction("退出"),&QAction::trigger,[=](){
        exit(0);
    });



}

void Bird_::running()
{
    timer->start(100);//每隔0.1秒启动 都会发出信号
}

void Bird_::mouseMoveEvent(QMouseEvent *event)
{

    //获取窗口的gai变量

    this->m_pos= event->globalPos()-this->m_pos;


    emit aftermove(m_pos);
    //
}
//((QWidget*)this->parent())->frameGeometry().topLeft();  获取当前窗口左上角的坐标
void Bird_::mousePressEvent(QMouseEvent *event)
{
    //用鼠标全局坐标的位置减去父窗口的左上角位置
    m_pos = event->globalPos()   - ((QWidget*)this->parent())->frameGeometry().topLeft();


    qmousedown = true;


    if(event->button()==Qt::RightButton)
    {
        menu->popup(QCursor::pos());//弹出菜单  和鼠标当前的位置意义 方便点击退出
    }

    //如果菜单是因为别的方式消失的 那么它继续往前飞

    //通过任何手段消失发出的信号
    //&QMenu::aboutToHide
    connect(this->menu,&QMenu::aboutToHide,[=](){


        //改变状态继续往前飞
        this->qmousedown =false;
    });
}

void Bird_::mouseReleaseEvent(QMouseEvent *event)
{
    qmousedown = false;

}

mainscence.h 及cpp

#ifndef MAINSCENCE_H
#define MAINSCENCE_H

#include <QWidget>
#include "bird_.h"
#include <QPainter>
#include <QTimer>
#include <QVector>
QT_BEGIN_NAMESPACE
namespace Ui {
class Mainscence;
}
QT_END_NAMESPACE

class Mainscence : public QWidget
{
    Q_OBJECT

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

   Bird_ *birds;


    //重写画图事件
    QPainter *painter;
    void paintEvent(QPaintEvent *event);

    //让窗口自动移动
    QPoint auto_pos;
    QTimer * timer;
private:
    Ui::Mainscence *ui;
};
#endif // MAINSCENCE_H

#include "mainscence.h"
#include "ui_mainscence.h"
//主场景
#include <QDesktopServices>
#include <QVector>
Mainscence::Mainscence(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Mainscence)
{
    ui->setupUi(this);

    this->setWindowTitle("主窗口");
    QIcon abc("./bird/birdIcon.ico");

    // QSize(30,30);
    this->setWindowIcon(abc);//设置窗口图标

    this->birds = new Bird_(this);

    //  birds->append(*new Bird_(this));
    this->setFixedSize(birds->width(),birds->height());
    this->setAutoFillBackground(1);

    this->birds->running();  //调用running 启动定时器

    //监听鸟切图的信号

    connect(birds,&Bird_::changepix,[=](){
        update();//手动调用绘图事件
        // 调用update后会调用   paintEvent
    });

    //监听鸟拖拽移动
    connect(birds,&Bird_::aftermove,[=](QPoint point){

        this->move(point);
        auto_pos = point; //鼠标拖拽跟新当前窗口的位置


    });


    timer = new QTimer(this);

    timer->start(30);

    //QGuiApplication::primaryScreen()->geometry();//qt6中使用这个代替了 qdesktop


    connect(timer,&QTimer::timeout,[=](){

        if(this->birds->qmousedown!=true){
            this->auto_pos.setX(this->auto_pos.x()+5);  //x坐标加上5像素
        }  //没有按下就往前飞


        if(this->auto_pos.x()>QGuiApplication::primaryScreen()->geometry().width())
        {
            this->auto_pos.setX(-this->width());
            //  需要减去一个尺寸从屏幕左边飞过来        //超出屏幕 x设为 窗口的-宽度
        }
        //窗口移动
        this->move(this->auto_pos);
    });



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

    this->setAttribute(Qt::WA_TranslucentBackground);  //窗口透明化

    //
    this->setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint);//设置窗口最顶层

}

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

void Mainscence::paintEvent(QPaintEvent *event)
{
    painter = new QPainter(this);
    //画图时用 drawPixmap
    painter->begin(this);
    painter->drawPixmap(0,0,this->birds->m_bird);
    //此处画鸟了

    painter->end();

}

  • []:不捕获任何外部变量。
  • [=]:按值捕获所有外部变量。
  • [&]:按引用捕获所有外部变量。
  • 混合使用:可以选择性地按值或按引用捕获特定变量