qt 实现模拟实际物体带速度的移动(水平、垂直、斜角度)——————附带完整代码

文章目录

  • 0 效果
  • 1 原理
    • 1.1 图片旋转
    • 1.2 物体按照现实中的实际距离带真实速度移动
  • 2 完整实现
    • 2.1 将车辆按钮封装为一个类:
    • 2.2 调用方法
  • 3 完整代码
  • 参考

0 效果

实现后的效果如下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

可以显示属性(继承自QToolButton):
在这里插入图片描述
鼠标悬浮显示文字
在这里插入图片描述
按钮显示文字

1 原理

类继承自QToolButton,默认朝右行驶为正方向,设置图片为按钮的图标:

1.1 图片旋转

  • 1,如果水平移动,朝左移动(纵坐标差值为0,横坐标差值为负【终点-起点,后面计算方式相同】),则对图片进行镜像处理image.mirrored
QImage rotateImage(const QImage &image, qreal fAngle)
{

    QTransform transform;
    transform.rotate(fAngle);

    return image.transformed(transform, Qt::SmoothTransformation);

}

	QImage tmp;
    if(r_x == 0 )				//Y轴
    {
        if(r_y > 0)
        {
            tmp = rotateImage(m_image,90.0);
        }
        else
        {
            tmp = rotateImage(m_image,270.0);
        }
    }

在这里插入图片描述
朝右
在这里插入图片描述
朝左

  • 2,如果是垂直移动,朝下移动(水平坐标差值为0,纵坐标差值大于0),把图片顺时针旋转90度;朝上移动(水平坐标差值为0,纵坐标差值小于0),图片顺指针旋转270度(对图片使用镜像image.transformed处理);
QImage filp(const QImage &image, bool bIsHorizon)
{
    return image.mirrored(bIsHorizon,!bIsHorizon);
}


    else if(r_y == 0)			//X轴
    {
        if(r_x >0)
        {
            tmp = m_image;
        }
        else
        {
            tmp = filp(m_image,true);
        }
    }

在这里插入图片描述
朝下
在这里插入图片描述
朝上

  • 3,如果是倾斜移动,计算弧度(纵坐标的差和横坐标的差的比值(tan值)取反正切值(qAtan(r_y/r_x));),把弧度转为角度(qAtan(r_y/r_x)*180/PI;)【二、三象限的旋转角度为负数】;如果方向位于第2,3象限(因为x轴正向,为水平朝右,y轴正向,为垂直向下),则把车图片做镜像处理(image.transformed处理,把车头调为朝左);
//核心
        QImage _filp = filp(m_image,true);
        qreal k = qAtan(r_y/r_x)*180/PI;
        tmp = rotateImage(_filp,k);

下面为四个象限的情况:

    else if(r_x > 0 && r_y > 0) //第一象限
    {

        qreal k = qAtan(r_y/r_x)*180/PI;
        tmp = rotateImage(m_image,k);

        qDebug()<<"第一象限:"<<k;
    }
    else if(r_x < 0 && r_y > 0) //第二象限
    {

        QImage _filp = filp(m_image,true);
        qreal k = qAtan(r_y/r_x)*180/PI;

        qDebug()<<"第二象限:"<<k;

        tmp = rotateImage(_filp,360.0 + k);//顺时针旋转
        //tmp = rotateImage(_filp, k);//逆时针旋转
    }else if(r_x < 0 && r_y < 0) //第三象限
    {

        QImage _filp = filp(m_image,true);
        qreal k = qAtan(r_y/r_x)*180/PI;
        tmp = rotateImage(_filp,k);

        qDebug()<<"第三象限:"<<k;
    }
    else if(r_x > 0 && r_y < 0) //第四象限
    {
        qreal k = qAtan(r_y/r_x)*180/PI;

        tmp = rotateImage(m_image,360.0+k);
        //tmp = rotateImage(m_image, k);

         qDebug()<<"第四象限:"<<k;
    }

在这里插入图片描述
四个象限

在这里插入图片描述
左上(位于第三象限)
在这里插入图片描述
右上(位于第四象限)

在这里插入图片描述
右下(位于第一象限)

在这里插入图片描述
左下(位于第二象限)

1.2 物体按照现实中的实际距离带真实速度移动

前提:

  • 1,使用QTimer计时器,进行刷新,来更新物体位置;
  • 2,传入每个线段路径的起点和终点到向量(Vector)构成总路线;
  • 3, 使用move方法来进行物体移动;

算法:

  • 1,根据总路线,依次计算出两点间的距离(两点间距离公式),累加后构成图形中的总距离m_linedistance
    for(int i = 1;i< m_pointVector.size();i++)
    {
        m_linedistanceVector.push_back(qSqrt((m_pointVector[i].x() - m_pointVector[i-1].x())*(m_pointVector[i].x() - m_pointVector[i-1].x())+
                                       (m_pointVector[i].y() - m_pointVector[i-1].y())*(m_pointVector[i].y() - m_pointVector[i-1].y())));

        m_linedistance += m_linedistanceVector.back();
    }
  • 2,计算出图形中单次刷新的实际移动的距离(像素):
    • 使用图形中的总距离m_linedistance(单位:像素)除以输入的距离m_distance(单位:m),得到图形中1像素代表实际距离中多少米;
    • 使用速度m_speed(单位:m/s)乘以时间time (单位:s,为QTimer的刷新时间)得到目前移动的像素;
qreal move_line = (time * m_speed)*m_linedistance/m_distance;
  • 3,计算出坐标的变化:
    • 计算方法:用上一步算出的实际移动的距离除以起点和终点两点间的距离得到移动的比列,起点的横、纵坐标分别加上比列乘以横、纵坐标的起终点之差,得到下一次移动后的坐标位置;
 QPoint p;
    qreal t = qSqrt((end.x() - start.x())*(end.x() - start.x()) + (end.y() - start.y())*(end.y() - start.y()));
    p.setX((end.x() - start.x())*distance/t + start.x());
    p.setY((end.y() - start.y())*distance/t + start.y());

在这里插入图片描述

    • 更换线路:如果当前点移动的距离和超过起点和终点间的距离差(也就是换到下一段线路上,且不是终点时),下一段线路的应该移动的距离减去当前点移动后超过的距离值(为了使得最终用时无误)为实际移动距离;
if(m_linedistanceVector[m_curposindex] <= m_curlinedistance + move_line)//超越该点
        {
            qDebug()<<"换点的距离:"<<"m_curlinedistance:"<<m_curlinedistance<<" m_linedistanceVector[m_curposindex]: "<<m_linedistanceVector[m_curposindex];
            //下一个点移动的距离 - 上一点移动的还未移动完的距离:为了使驾驶的时间正确
            m_curlinedistance = m_curlinedistance + move_line - m_linedistanceVector[m_curposindex];
            m_curposindex++;
            if(m_curposindex == m_pointVector.size() - 1)//当前点在终点
            {
                m_curlinedistance = 0;
                m_curposx = m_pointVector.back().x();
                m_curposy = m_pointVector.back().y();
            }
            else
            {
                QPoint pt = getPoswithLinedistance(m_curlinedistance, m_pointVector[m_curposindex], m_pointVector[m_curposindex+1]);
                m_curposx = pt.x();
                m_curposy = pt.y();
                //旋转图标位置
                setImageRote(m_pointVector[m_curposindex].x(), m_pointVector[m_curposindex].y(), m_pointVector[m_curposindex+1].x(), m_pointVector[m_curposindex+1].y());
            }
        }
  • 4,终止:如果该点为最后一个点,则车辆停止(停止定时器刷新);
class xx{
   //计时器
    QTimer m_timer;
};

    if(m_curposindex == m_pointVector.size() -1){//只剩最后一个坐标时,停止计时器(停车)
        m_timer.stop();
    }

2 完整实现

2.1 将车辆按钮封装为一个类:

#ifndef VEHICLE_TOOLBUTTON_H
#define VEHICLE_TOOLBUTTON_H
#include <QToolButton>
#include <QTimer>

class VehicleToolButton : public QToolButton
{
    Q_OBJECT

public:
    /**
     * @brief 使用默认图片
     * @param parent
     */
    VehicleToolButton(QWidget *parent = nullptr);
    /**
     * @brief VehicleToolButton
     * @param image:按钮的图标的文件路径
     * @param size:按钮大小
     * @param parent
     */
    VehicleToolButton(QString imagePath, QSize size,QWidget *parent = nullptr);
    ~VehicleToolButton();

public:
    /**
     * @brief 得到速度
     * @return
     */
    qreal getSpeed();

    /**
     * @brief 强制设置显示位置
     * @param x
     * @param y
     */
    void setCurCoordinate(int x,int y);
    /**
     * @brief 设置现在所处位置
     * @param x
     * @param y
     */
    void setCurrentPosition(int x, int y);
    /**
     * @brief 改变速度
     * @param _speed
     */
    void setSpeed(qreal _speed);
    /**
     * @brief 设置行进参数
     * @param _v_point
     * @param _distance
     * @param _speed
     */
    void setData(QVector<QPoint> _v_point, qreal _distance, qreal _speed);
    /**
     * @brief 设置图标图片
     * @param image
     */
    void setImage(QImage image);
    /**
     * @brief 设置图标大小
     * @param size
     */
    void setSize(QSize size);

private:
    /**
     * @brief 计算从起点到终点方向距离distance的坐标点
     * @param distance
     * @param start
     * @param end
     * @return
     */
    QPoint getPoswithLinedistance(qreal distance,QPoint start,QPoint end);
    /**
     * @brief 按水平轴或者垂直线作镜像翻转,bIsHorizon为true按水平轴,false按垂直方向
     * @param image
     * @param bIsHorizon
     * @return
     */
    QImage filp(const QImage& image,bool bIsHorizon);
    /**
     * @brief 根据弧度值(角度值)起点(x1,y1)和终点(x2,y2)确定图片旋转的角度
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     */
    void setImageRote(int x1,int y1,int x2,int y2);
    /**
     * @brief 将图片按顺时针方向旋转一定的角度,fAngle为角度值
     * @param image
     * @param fAngle
     * @return
     */
    QImage rotateImage(const QImage& image,qreal fAngle);
    /**
     * @brief 根据弧度值(角度值)r_x,r_y确定图片旋转的角度
     * @param r_x
     * @param r_y
     */
    void setImageRote(qreal r_x,qreal r_y);
    /**
     * @brief //根据车速和运动轨迹计算time时间之后位置,timer事件调用move()函数移动到该位置,
     * @param time
     * @param x
     * @param y
     */
    void getCurrentPos(qreal time,int& x,int& y);

public slots:
    /**
     * @brief 刷新图片
     */
    void updatedisplay();
    /**
     * @brief 开始定时器
     * @param _msec
     */
    void startTimer(int _msec);

private:
    QImage m_image;//按钮图标
    QSize m_pixSize;//按钮大小

    //车辆行进数据结构
    QVector<QPoint> m_pointVector;												//行驶路径点集合(图上位置)
    QVector<qreal> m_linedistanceVector;											//行驶路径段在图上的线段长度
    qreal m_distance;															//行驶路径总长度(单位m)
    qreal m_linedistance;														//行驶路径在图上的总长度
    int	   m_curposindex;														//当前所在点的下标
    qreal  m_curlinedistance;													//当前所在线段上距离
    qreal  m_curlinetotledistance;											//当前行驶完成的路径长度总和
    int	   m_curposx;															//当前在图上的点X坐标
    int    m_curposy;															//当前在图上的点Y坐标
    qreal m_speed;															//当前车速

    //设置刷新时间(毫秒)
    int m_refreshTime = 10;
    //计时器
    QTimer m_timer;

signals:
    /**
     * @brief 停止移动
     */
    void stopVehicleMove();
};

#endif // VEHICLE_TOOLBUTTON_H
#include "vehicle_toolbutton.h"
#include <qmath.h>
#include <QDebug>
#define PI 3.1415926


VehicleToolButton::VehicleToolButton(QWidget *parent) : QToolButton(parent){
    //设置按钮大小
    this->setFixedSize(50, 50);
    //设置图标大小
    this->setIconSize(QSize(50,50));

    this->setAutoRaise(true);//设置按钮自动凸起
    this->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

    QPixmap icoPix(":/Image/car.png");
    //QPixmap icoPix = QPixmap::fromImage(l_image);
    icoPix.scaled(QSize(50,50), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    m_image = icoPix.toImage();
    m_pixSize = QSize(50,50);
    this->setIcon(QIcon(icoPix));


}

VehicleToolButton::VehicleToolButton(QString imagePath, QSize size, QWidget *parent)
:QToolButton(parent),  m_pixSize(size)
{

    m_image.load(imagePath);

    //设置按钮大小
    this->setFixedSize(size.width(), size.height());
    //设置图标大小
    this->setIconSize(size);

    this->setAutoRaise(true);//设置按钮自动凸起
    this->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

    QPixmap icoPix = QPixmap::fromImage(m_image);
    icoPix.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    m_image = icoPix.toImage();

    this->setIcon(QIcon(icoPix));

}

VehicleToolButton::~VehicleToolButton()
{

}

void VehicleToolButton::updatedisplay()
{
    int x=0, y=0;
    getCurrentPos(m_refreshTime*0.001, x, y);//得到现在的坐标

    this->move(x, y);//移动
    if(m_curposindex == m_pointVector.size() -1){//只剩最后一个坐标时,停止计时器(停车)
        //emit stopVehicleMove();
        m_timer.stop();
    }
}

void VehicleToolButton::startTimer(int _msec)
{
    m_refreshTime = _msec;
    //关联计时器
    //connect(&m_timer, &QTimer::timeout, this, &VehicleToolButton::updatedisplay);

    //关联计时器
    connect(&m_timer, &QTimer::timeout, this, &VehicleToolButton::updatedisplay, Qt::UniqueConnection);
    m_timer.start(_msec);
}

qreal VehicleToolButton::getSpeed()
{
    return m_speed;
}
//根据车速和运动轨迹计算time时间之后位置,timer事件调用move()函数移动到该位置
void VehicleToolButton::getCurrentPos(qreal time, int &x, int &y)
{

    if(m_linedistance <=0 )//所有点之间的距离为0
        return;

    //time  = 刷新时间(单位为s)
    //time * m_speed:得到图形中点的距离长度
    //m_linedistance/m_distance:图形中的距离和设置距离的比列(图形中的距离1像素对应设置的实际距离?米)
    qreal move_line = (time * m_speed)*m_linedistance/m_distance;

    if(m_curposindex == m_pointVector.size()-1)//当前点在终点
    {

    }
    else
    {
        if(m_linedistanceVector[m_curposindex] <= m_curlinedistance + move_line)//超越该点
        {
            
            //下一个点移动的距离 - 上一点移动的还未移动完的距离:为了使驾驶的时间正确
            m_curlinedistance = m_curlinedistance + move_line - m_linedistanceVector[m_curposindex];
            m_curposindex++;
            if(m_curposindex == m_pointVector.size() - 1)//当前点在终点
            {
                m_curlinedistance = 0;
                m_curposx = m_pointVector.back().x();
                m_curposy = m_pointVector.back().y();
            }
            else
            {
                QPoint pt = getPoswithLinedistance(m_curlinedistance, m_pointVector[m_curposindex], m_pointVector[m_curposindex+1]);
                m_curposx = pt.x();
                m_curposy = pt.y();
                //旋转图标位置
                setImageRote(m_pointVector[m_curposindex].x(), m_pointVector[m_curposindex].y(), m_pointVector[m_curposindex+1].x(), m_pointVector[m_curposindex+1].y());
            }
        }
        else
        {
            m_curlinedistance += move_line;
            QPoint pt = getPoswithLinedistance(m_curlinedistance, m_pointVector[m_curposindex], m_pointVector[m_curposindex + 1]);
            m_curposx = pt.x();
            m_curposy = pt.y();
        }
        m_curlinetotledistance += move_line;
    }
    x = m_curposx;
    y = m_curposy;



}

void VehicleToolButton::setCurCoordinate(int x, int y)
{
    m_curposx = x;
    m_curposy = y;
}

void VehicleToolButton::setCurrentPosition(int x, int y)
{
    this->move(x,y);
}

void VehicleToolButton::setSpeed(qreal _speed)
{
    m_speed = _speed;
}
//设置行进参数
void VehicleToolButton::setData(QVector<QPoint> _v_point, qreal _distance, qreal _speed)
{
    m_pointVector.clear();
    m_linedistanceVector.clear();
    m_pointVector = _v_point;
    m_distance = _distance;
    m_speed = _speed;
    m_linedistance = 0;//距离总长度
    m_curposindex = -1;
    m_curposx = -1;
    m_curposy = -1;
    m_curlinetotledistance = 0;

    //计算两点间的距离长度
    for(int i = 1;i< m_pointVector.size();i++)
    {
        m_linedistanceVector.push_back(qSqrt((m_pointVector[i].x() - m_pointVector[i-1].x())*(m_pointVector[i].x() - m_pointVector[i-1].x())+
                                       (m_pointVector[i].y() - m_pointVector[i-1].y())*(m_pointVector[i].y() - m_pointVector[i-1].y())));

        m_linedistance += m_linedistanceVector.back();
    }

    //位置坐标大于2个,设置最开始的坐标为起始位置,并旋转图片
    if(m_pointVector.size() > 0 )
    {
        m_curposindex = 0;
        m_curlinedistance = 0;
        m_curposx = m_pointVector[0].x();
        m_curposy = m_pointVector[0].y();
        if(m_pointVector.size() >1)
            setImageRote(m_pointVector[0].x(), m_pointVector[0].y(), m_pointVector[1].x(), m_pointVector[1].y());
    }
}

void VehicleToolButton::setImage(QImage image)
{
    m_image = image;
}

void VehicleToolButton::setSize(QSize size)
{
    m_pixSize = size;
}
//计算从起点到终点方向距离distance的坐标点
QPoint VehicleToolButton::getPoswithLinedistance(qreal distance, QPoint start, QPoint end)
{
    QPoint p;
    qreal t = qSqrt((end.x() - start.x())*(end.x() - start.x()) + (end.y() - start.y())*(end.y() - start.y()));
    p.setX((end.x() - start.x())*distance/t + start.x());
    p.setY((end.y() - start.y())*distance/t + start.y());
    return p;
}
//按水平轴或者垂直线作镜像翻转,bIsHorizon为true按垂直方向,false按水平轴
QImage VehicleToolButton::filp(const QImage &image, bool bIsHorizon)
{
    return image.mirrored(bIsHorizon,!bIsHorizon);
}

//根据弧度值(角度值)起点(x1,y1)和终点(x2,y2)确定图片旋转的角度
void VehicleToolButton::setImageRote(int x1, int y1, int x2, int y2)
{
    setImageRote(qreal(x2-x1),qreal(y2-y1));
}
//将图片按顺时针方向旋转一定的角度,fAngle为角度值
QImage VehicleToolButton::rotateImage(const QImage &image, qreal fAngle)
{
    // QMatrix matrix;
    // matrix.rotate(fAngle);
    //  return image.transformed(matrix, Qt::SmoothTransformation);

    QTransform transform;
    transform.rotate(fAngle);

    return image.transformed(transform, Qt::SmoothTransformation);

}
//根据弧度值(角度值)r_x,r_y确定图片旋转的角度(核心算法)
void VehicleToolButton::setImageRote(qreal r_x, qreal r_y)
{
    //坐标和理论坐标轴不同,X轴正向为水平右,Y轴正向为垂直向下
    QImage tmp;
    if(r_x == 0 &&  r_y == 0)
        return;
    if(r_x == 0 )				//Y轴
    {
        if(r_y > 0)
        {
            tmp = rotateImage(m_image,90.0);
        }
        else
        {
            tmp = rotateImage(m_image,270.0);
        }
    }
    else if(r_y == 0)			//X轴
    {
        if(r_x >0)
        {
            tmp = m_image;
        }
        else
        {
            tmp = filp(m_image,true);
        }
    }
    else if(r_x > 0 && r_y > 0) //第一象限
    {

        qreal k = qAtan(r_y/r_x)*180/PI;
        tmp = rotateImage(m_image,k);

        qDebug()<<"第一象限:"<<k;
    }
    else if(r_x < 0 && r_y > 0) //第二象限
    {

        QImage _filp = filp(m_image,true);
        qreal k = qAtan(r_y/r_x)*180/PI;

        qDebug()<<"第二象限:"<<k;

        tmp = rotateImage(_filp,360.0 + k);//顺时针旋转
        //tmp = rotateImage(_filp, k);//逆时针旋转
    }else if(r_x < 0 && r_y < 0) //第三象限
    {

        QImage _filp = filp(m_image,true);
        qreal k = qAtan(r_y/r_x)*180/PI;
        tmp = rotateImage(_filp,k);

        qDebug()<<"第三象限:"<<k;
    }
    else if(r_x > 0 && r_y < 0) //第四象限
    {
        qreal k = qAtan(r_y/r_x)*180/PI;

        tmp = rotateImage(m_image,360.0+k);
        //tmp = rotateImage(m_image, k);

         qDebug()<<"第四象限:"<<k;
    }

    tmp.scaled(this->width(), this->height());

    QPixmap icoPix = QPixmap::fromImage(tmp);
    icoPix.scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    this->setIcon(QIcon(icoPix));
}

2.2 调用方法



class MainInterface : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainInterface *ui;

private:
    VehicleToolButton* train;
    QVector<QPoint> m_trainMovePointVector;
signals:
    void startTrainMove(int msec=10);

private slots:
    void on_pushButton_clicked();
};
MainInterface::MainInterface(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainInterface)
{
    ui->setupUi(this);

    QPixmap icoPix(":/Image/routeBackimage.png");
    icoPix.scaled(ui->label->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->label->setScaledContents(true);
    ui->label->setPixmap(icoPix);

	//构造方法1
    // train = new VehicleToolButton(this);
    //构造方法2
    train = new VehicleToolButton(QString(":/Image/car.png"), QSize(50,50),this);

    //目标点,路径长度,速度
    train->setData(m_trainMovePointVector,  500.0,   20.0);
    train->hide();
    train->setText("车:112");

    train->setToolTip(QString("当前速度为:%1").arg(train->getSpeed()));

    connect(this, &MainInterface::startTrainMove, train, &VehicleToolButton::startTimer);

    // ui->label->hide();

}

//按钮点击事件
void MainInterface::on_pushButton_clicked()
{
    // QVector<QPoint> v_point;
    train->show();
    m_trainMovePointVector.clear();

     m_trainMovePointVector.push_back(QPoint(100,100));

    m_trainMovePointVector.push_back(QPoint(400,400));//对角线右下
    m_trainMovePointVector.push_back(QPoint(100,100));//对角线左上


     m_trainMovePointVector.push_back(QPoint(100,400));//向下开

     m_trainMovePointVector.push_back(QPoint(400,100));//对角线右上
     m_trainMovePointVector.push_back(QPoint(100,400));//对角线左下


     m_trainMovePointVector.push_back(QPoint(400,400));//向右开
     m_trainMovePointVector.push_back(QPoint(400,100));//向上开
     m_trainMovePointVector.push_back(QPoint(100,100));//向左开


    // m_trainMovePointVector.clear();
    // m_trainMovePointVector.push_back(QPoint(10, 822));
    // m_trainMovePointVector.push_back(QPoint(1200, 822));
    // m_trainMovePointVector.push_back(QPoint(10, 822));

      train->setData(m_trainMovePointVector,  300.0,   20.0);


    emit startTrainMove();
}

3 完整代码

代码仓库(欢迎star):

github
码云

参考

https://blog.csdn.net/u012739657/article/details/22645375

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Bagging与Boosting的应用与优势

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

Excel 常用技巧(四)

Microsoft Excel 是微软为 Windows、macOS、Android 和 iOS 开发的电子表格软件&#xff0c;可以用来制作电子表格、完成许多复杂的数据运算&#xff0c;进行数据的分析和预测&#xff0c;并且具有强大的制作图表的功能。由于 Excel 具有十分友好的人机界面和强大的计算功能&am…

【Python高级编程】Pickle实现AI算法训练的权重数据的保存

任务描述 代码实现 import pickle import time import os import numpy as np# 模拟耗时的权重计算过程 def calculate_weights():print("开始计算权重...")time.sleep(5) # 模拟耗时操作&#xff0c;暂停5秒以模拟计算过程weights np.random.rand(10, 10) # 随机…

python实践笔记(三): 异常处理和文件操作

1. 写在前面 最近在重构之前的后端代码&#xff0c;借着这个机会又重新补充了关于python的一些知识&#xff0c; 学习到了一些高效编写代码的方法和心得&#xff0c;比如构建大项目来讲&#xff0c;要明确捕捉异常机制的重要性&#xff0c; 学会使用try...except..finally&…

小区噪音监测管理系统设计

一、引言 随着城市化进程的加快&#xff0c;小区居民对于居住环境的要求日益提高。其中&#xff0c;噪音污染已成为影响居民生活质量的重要因素。因此&#xff0c;设计一套小区噪音监测管理系统&#xff0c;对于提升居民的生活品质和小区管理效率具有重要意义。本文将详细阐述…

如何拥有自己的微信小程序

如何拥有自己的微信小程序 ~~话先放在这里~~ 写在前面申请一个属于自己的小程序先去[微信开放平台](https://open.weixin.qq.com/home)申请一个你的小程序扫码申请新小程序小程序该记好的个人信息 安装微信开发者工具下载工具关联你的小程序请求域名配置发布小程序 BUY一个自己…

SQL:按用户名复制权限

生产系统中有一个模块是管理用户及菜单权限&#xff0c;它们是由3个数据表组成&#xff0c;关系及字段如下&#xff1a; 原来为每个用户添加菜单的访问权限时都是一个一个添加&#xff0c;但今天遇到有个新来的员工&#xff0c;需要具有与另一个员工相同的权限。新建一个用户后…

PS插件创成式填充功能全面测评:轻松实现AI修图新高度

大家好&#xff0c;我是你们的AIGC测评博主。今天&#xff0c;我将为大家带来一款ps插件创成式填充功能——深度体验 在图像处理领域&#xff0c;AI技术的应用已经越来越广泛。而创成式填充功能&#xff0c;无疑是其中的佼佼者。它利用AI技术&#xff0c;能够根据用户输入的关…

c语言——c51单片机——数码管

数码管&#xff1a; #include "reg51.h"void delay(unsigned int n) {while (n)--n; }void main(void) { //unsigned char num[] {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d,0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c,0x39, 0x5e, 0x79, 0x71, 0x00};unsigned int i 0…

坚持刷题|合并有序链表

文章目录 题目思考代码实现迭代递归 扩展实现k个有序链表合并方法一方法二 PriorityQueue基本操作Java示例注意事项 Hello&#xff0c;大家好&#xff0c;我是阿月。坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;消失了一段时间&#xff0c;我又回来刷题啦&#xff0c;今天…

雪花算法和UUID

目录 雪花算法概念优点和不足优点:缺点:解决方案代码示例 UUID优点与不足优点不足 两种算法的比较应用场景区别 雪花算法 概念 雪花算法是一个分布式id生成算法&#xff0c;它生成的id一般情况下具有唯一性。由64位01数字组成&#xff0c;第一位是符号位&#xff0c;始终为0。…

【leetcode刷题】面试经典150题 , 27. 移除元素

leetcode刷题 面试经典150 27. 移除元素 难度&#xff1a;简单 文章目录 一、题目内容二、自己实现代码2.1 方法一&#xff1a;直接硬找2.1.1 实现思路2.1.2 实现代码2.1.3 结果分析 2.2 方法二&#xff1a;排序整体删除再补充2.1.1 实现思路2.1.2 实现代码2.1.3 结果分析 三、…

大模型泡沫退去,谁能活到下半场?

前言 从今年3月开始&#xff0c;国内企业纷纷下场大模型&#xff0c;铆足劲秀肌肉&#xff0c;如今转向垂直行业淘金&#xff0c;试图争霸行业大模型。我们的心态也逐渐从看乐子&#xff0c;到严肃讨论。 在人工智能的世界&#xff0c;我们经历了众多的概念游戏&#xff0c;在…

shell编程——脚本入门

在编写脚本的时候指定解析器 在编写shell脚本时第一行以#&#xff01;/bin/bash开头指定解析器。 在shell脚本中使用echo语句来在屏幕中打印内容。 调用shell脚本的第一种方式 在shell脚本中以bash或者是sh脚本路径的方式来启动脚本。这种执行脚本的方式是在Linux操作系统的b…

【C++高阶】掌握C++多态:探索代码的动态之美

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C继承 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀继承 &#x1f4d2;1. 多态的定义及实现&…

【总线】AXI总线:FPGA设计中的通信骨干

目录 AXI4&#xff1a;高性能地址映射通信的基石 AXI4-Lite&#xff1a;轻量级但功能强大的通信接口 AXI4-Stream&#xff1a;高速流数据传输的利器 结语&#xff1a;AXI总线在FPGA设计中的重要性 大家好,欢迎来到今天的总线学习时间!如果你对电子设计、特别是FPGA和SoC设计…

Go 并发控制:RWMutex 实战指南

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

怎么管理网站的数据

每一个网站都会有很多的数据&#xff0c;这些数据的来源&#xff0c;有一些是直接把数据存放在运行文件里面&#xff0c;有一些则是存放在数据库里面&#xff0c;如MySQL、SQL Server等等&#xff0c;这些数据库都是需要安装指定的数据库环境才能运行起来&#xff0c;数据库的存…

减肥药实质利好服装业:身材好了,更时尚了 1-5月份,新建商品房销售面积同比下降20.3%

减肥药实质利好服装业&#xff1a;身材好了&#xff0c;更时尚了 减肥成功的顾客纷纷瞄准性感look&#xff0c;不但促进了销售&#xff0c;还给服装品牌节省了成本&#xff0c;因为小尺寸的衣服使用的面料更少。大码女装&#xff0c;可能是下一个被 GLP-1减肥神药杀死的行业。…

【计算机毕业设计】234基于微信小程序的中国各地美食推荐平台

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…