当前位置: 首页 > news >正文

简单Qt贪吃蛇项目

目录

先看效果

项目介绍 

界面一:游戏大厅界面

界面二:关卡选择界面​编辑

界面三:游戏界面

游戏大厅页面

游戏关卡选择页面

游戏房间页面

封装贪吃蛇数据结构

初始化游戏房间界面

设置窗口大小、标题、图标等

蛇的移动

初始化贪吃蛇本体和食物节点

实现各个方向的移动

实现向上移动

实现向下移动

实现向左移动

实现向右移动

检查是否自己会不会撞自己

设置游戏开始和游戏暂停按钮

设置退出游戏按钮

获取历史战绩


先看效果

项目介绍 

贪吃蛇游戏是⼀款休闲益智类游戏。它通过控制蛇头⽅向吃⻝物,从⽽使得蛇变得越来越⻓。在本游戏中设置了上下左右四个⽅向键来控制蛇的移动⽅向。⻝物的产⽣是随机⽣成的,当蛇每吃⼀次⻝物就会增加⼀节⾝体,同时游戏积分也会相应的加⼀。在本游戏的设计中,蛇的⾝体会越吃越⻓,⾝体越⻓对应的难度就越⼤,因为⼀旦蛇头和⾝体相交游戏就会结束。

界面一:游戏大厅界面

当用户点击 “开始游戏” 按钮之后,就会进⼊到关卡选择界面。

界面二:关卡选择界面

在关卡选择界⾯上设置了三个游戏模式按钮,分别是:简单模式、正常模式、困难模式;⼀个 “历史战绩” 按钮;⼀个返回游戏⼤厅界⾯的按钮。
当我们点击三个游戏按钮中的任意⼀个时,就会进⼊游戏房间界⾯,游戏房间界⾯如下:

界面三:游戏界面

在游戏界⾯,如果想要开始游戏,⾸先点击 “开始” 按钮,此时蛇就会移动并且还有背景⾳效。如果 想要暂停游戏,那么点击 “暂停” 按钮即可。当我们在游戏时,可以通过右边控制区域的上下左右方向键来控制蛇的移动。当蛇每吃⼀次⻝物时,伴随有吃⻝物的⾳效,蛇⾝会增加⼀节⻓度,并且分数 积分也会相应的加⼀。最后在控制区域的右下⻆布局了⼀个 “退出” 按钮,当点击 “退出” 按钮时,就会弹出一个对话框,我们点击OK就会退出游戏,点击cancel我们便不会退出游戏。

在刚进⼊游戏房间界⾯时,⼀定不能点击 “退出” 按钮,如果点击 “退出” 按钮,那么程序就会异常退出。点击的顺序⼀定是:先点击 “开始” 按钮,最后才能点击 “退出” 。

游戏大厅页面

主要内容重写了绘图事件

    //重写绘图事件void paintEvent(QPaintEvent *event);
void GameHall::paintEvent(QPaintEvent *event)
{(void) event;//实例化画家对象QPainter painter(this);//QpixmapQPixmap pix(":/res/game_hall.png");//画家绘画painter.drawPixmap(0,0,this->width(),this->height(),pix);}

固定窗口的大小,同时将其与的窗口也设置为(1000,800),设置窗口的图标以及窗口的标题名,使用信号和槽函数点击开始按钮跳转的游戏选择窗口。

GameHall::GameHall(QWidget *parent): QWidget(parent), ui(new Ui::GameHall)
{ui->setupUi(this);//调整窗口大小this->setFixedSize(1000,800);//设置窗口的图表this->setWindowIcon(QIcon(":/res/ico.png"));this->setWindowTitle("贪吃蛇游戏");QFont font("华为行楷",24);QPushButton* starBtn = new QPushButton(this);starBtn->move(430,530);starBtn->setFont(font);starBtn->setText("开始游戏");starBtn->setStyleSheet("QPushButton{border:0px;}");  //去掉边框//跳转到第二个窗口GameSelect * gameSelect = new GameSelect;connect(starBtn,&QPushButton::clicked,[=](){this->close();//设置第二个窗口和第一个窗口一样大gameSelect->setGeometry(this->geometry());gameSelect->show();QSound::play(":/res/clicked.wav");});
}

使用的知识点总结:

  • 通过使用setFixedSize设置窗口的大小
  • 使用setWindowIcon设置左上角的图标
    
  • 使用setWindowTitle设置文本标题
  • 使用lambda表达式
  • 使用信号和槽函数跳转到第二个页面

游戏关卡选择页面

实现代码如下:

    //绘图事件void paintEvent(QPaintEvent *event);
GameSelect::GameSelect(QWidget *parent) : QWidget(parent)
{this->setFixedSize(1000,800); //设置窗口大小(其实可以设置也可以不设置)this->setWindowIcon(QIcon(":/res/ico.png"));this->setWindowTitle("游戏关卡选择");QPushButton* backBtn = new QPushButton(this);backBtn->move(900,730);backBtn->setIcon(QIcon(":/res/back.png"));//信号和槽 跳转到第一个页面connect(backBtn,&QPushButton::clicked,[=](){this->close();GameHall* gameHall = new GameHall;gameHall->show();//加上音效QSound::play(":/res/clicked.wav");});QFont font("华文行楷",24);GameRoom* gameRoom = new GameRoom;QPushButton * simpleBtn = new QPushButton(this);simpleBtn->move(420,160);simpleBtn->setText("简单模式");simpleBtn->setFont(QFont(font));connect(simpleBtn,&QPushButton::clicked,[=](){this->close();gameRoom->show();QSound::play(":/res/clicked.wav");gameRoom->setTimerout(400);});QPushButton * normalBtn = new QPushButton(this);normalBtn->move(420,260);normalBtn->setText("正常模式");normalBtn->setFont(QFont(font));connect(normalBtn,&QPushButton::clicked,[=](){this->close();gameRoom->setGeometry(this->geometry());gameRoom->show();QSound::play(":/res/clicked.wav");gameRoom->setTimerout(200);});QPushButton * difficultBtn = new QPushButton(this);difficultBtn->move(420,360);difficultBtn->setText("困难模式");difficultBtn->setFont(QFont(font));connect(difficultBtn,&QPushButton::clicked,[=](){this->close();gameRoom->setGeometry(this->geometry());gameRoom->show();QSound::play(":/res/clicked.wav");gameRoom->setTimerout(50);});QPushButton * history = new QPushButton(this);history->move(420,460);history->setText("历史战绩");history->setFont(QFont(font));QSound::play(":/res/clicked.wav");connect(history,&QPushButton::clicked,[=](){QWidget * widget = new QWidget;widget->setWindowTitle("历史战绩");widget->setFixedSize(500,300);QTextEdit* edit = new QTextEdit(widget);edit->setFont(font);edit->setFixedSize(500,300);//获取历史战绩  == 获取蛇的长度 -3 就表示吃的食物QFile file("C:/Users/19846/Desktop/greedy_snack/1.txt");file.open(QIODevice::ReadOnly);QTextStream in(&file);int data = in.readLine().toInt();edit->append("得分为:");edit->append(QString::number(data));widget->show();});
}
void GameSelect::paintEvent(QPaintEvent *event)
{(void) event;//实例化 画家对象QPainter painter(this);QPixmap pix(":/res/game_select.png");painter.drawPixmap(0,0,this->width(),this->height(),pix);
}

游戏房间页面

• 蛇的绘制、蛇的移动、判断蛇是否会撞到自己
• 积分的累加和绘制
在这⾥我们要考虑几个比较核心的问题:
1. 怎么让蛇动起来?
• 我们可以用⼀个链表表示贪吃蛇,⼀个⼩方块表示蛇的⼀个节点, 我们设置蛇的默认长度为3;
• 向上移动的逻辑就是在蛇的上方加入⼀个小方块, 然后把最后⼀个小方块删除即可;
• 需要用到定时器Qtimer 每100 - 200ms 重新渲染。
2. 怎么判断蛇有没有吃到⻝物?
• 判断蛇头和⻝物的坐标是否相交,Qt 有相关的接口调用。
3. 怎么控制蛇的移动?
• 借助QT的实践机制实现, 重写keyPressEvent即可, 在函数中监控想要的键盘事件即可
• 我们通过绘制四个按钮,使⽤信号和槽的机制控制蛇的上、下、左、右移动⽅向

封装贪吃蛇数据结构

//枚举蛇的移动方向
enum class SnakeDirect{UP = 0,DOWN,LEFT,RIGHT
};class GameRoom : public QWidget
{Q_OBJECT
public:explicit GameRoom(QWidget *parent = nullptr);void paintEvent(QPaintEvent *event);void moveUp(); //蛇向上移动void moveDown();//蛇向下移动void moveLeft(); //蛇向左移动void moveRight();//蛇向右移动bool checkFail(); //判断游戏是否结束void crateNewFood(); //创建食物void setTimerout(int timeout){moveTimeout = timeout;}signals:private:const int kSnakeNodeWidth = 20;  //表示蛇身体节点的宽度const int kSnakeNodeHeight = 20; //表示蛇身体的高度const int kDefaultTimeout = 200; //设默认的移动速度QList<QRectF> snakeList; //表示贪吃蛇链表QRectF foodRect;         //表示食物节点SnakeDirect moveDirect = SnakeDirect::UP;      //默认移动方向是向上QTimer* timer;      //定时器bool isGameStart = false;QSound* sound;int moveTimeout = kDefaultTimeout;
};

初始化游戏房间界面

设置窗口大小、标题、图标等

GameRoom::GameRoom(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);// 初始化窗⼝设置this->setFixedSize(1000, 800);this->setWindowTitle("贪吃蛇游戏");this->setWindowIcon(QIcon(":res/ico.png"));
}

蛇的移动

蛇的移动⽅向为:上、下、左、右。通过在游戏房间中布局四个按钮来控制蛇的移动⽅向。
注意: 这⾥贪吃蛇不允许直接掉头, ⽐如当前是向上的, 不能直接修改为向下。
 QPushButton *Up = new QPushButton(this);QPushButton *Down = new QPushButton(this);QPushButton *Left = new QPushButton(this);QPushButton *Right = new QPushButton(this);Up->move(880,400);Down->move(880,480);Left->move(840,440);Right->move(920,440);Up->setStyleSheet("QPushButton{border:0px;}");Up->setFont(font);Up->setText("↑");Down->setStyleSheet("QPushButton{border:0px;}");Down->setFont(font);Down->setText("↓");Left->setStyleSheet("QPushButton{border:0px;}");Left->setFont(font);Left->setText("←");Right->setStyleSheet("QPushButton{border:0px;}");Right->setFont(font);Right->setText("→");connect(Up,&QPushButton::clicked,this,[=](){if(moveDirect != SnakeDirect::DOWN)moveDirect = SnakeDirect::UP;});connect(Down,&QPushButton::clicked,this,[=](){if(moveDirect != SnakeDirect::UP)moveDirect = SnakeDirect::DOWN;});connect(Left,&QPushButton::clicked,this,[=](){if(moveDirect != SnakeDirect::RIGHT)moveDirect = SnakeDirect::LEFT;});connect(Right,&QPushButton::clicked,this,[=](){if(moveDirect != SnakeDirect::LEFT)moveDirect = SnakeDirect::RIGHT;
})

初始化贪吃蛇本体和食物节点

GameRoom::GameRoom(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{// 初始化贪吃蛇snakeList.push_back(QRectF(this->width() * 0.5, this->height() * 0.5, 
kSnakeNodeWidth, kSnakeNodeHeight));moveUp();moveUp();// 初始化⻝物createNewFood();
}
moveUp() 的功能是将蛇向上移动⼀次, 即在上方新增⼀个节点, 但不删除尾部节点。 createNewFood() 方法的功能是随机创建⼀个食物节点:
void GameRoom::createNewFood()
{foodRect = QRectF(qrand() % (this->width() / kSnakeNodeWidth) * kSnakeNodeWidth ,qrand() % (this->height() / kSnakeNodeWidth) * kSnakeNodeWidth,kSnakeNodeWidth,kSnakeNodeHeight);
}

实现定时器的超时槽函数 定时器的是为了实现每隔⼀段时间能处理移动的逻辑并且更新绘图事件。

• ⾸先, 需要判断蛇头和食物节点坐标是否相交

        ◦ 如果相交, 需要创建新的食物节点, 并且需要更新蛇的长度, 所以 cnt 需要 +1 ;

        ◦ 如果不相交, 那么直接处理蛇的移动即可。

• 根据蛇移动方向 moveDirect 来处理蛇的移动, 处理方法是在前方加⼀个, 并且删除后方节点; • 重新触绘图事件, 更新渲染。

        

GameRoom::GameRoom(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{timer = new QTimer(this);connect(timer, &QTimer::timeout, this, [=](){int cnt = 1;// 判断是否贪吃蛇和⻝物是否相交if (snakeList.front().intersects(foodRect)) {createNewFood();++cnt;}while(cnt--) {// 处理蛇的移动switch (moveDirect) {case SnakeDirect::UP:moveUp();break;case SnakeDirect::DOWN:moveDown();break;case SnakeDirect::LEFT:moveLeft();break;case SnakeDirect::RIGHT:moveRight();break;default:qDebug() << "⾮法移动⽅向";break;}}// 删除最后⼀个节点snakeList.pop_back();update();});
}

实现各个方向的移动

实现向上移动
void GameRoom::moveUp()
{QPointF leftTop; //左上角坐标QPointF rightBottom; //右下角坐标auto snakeNode = snakeList.front(); //头int headX = snakeNode.x();int headY = snakeNode.y();// 头到墙了(穿墙了)if(headY < 0){leftTop = QPointF(headX,this->height() - kSnakeNodeHeight);}else{leftTop = QPointF(headX,headY - kSnakeNodeHeight);}rightBottom = leftTop + QPointF(kSnakeNodeWidth,kSnakeNodeHeight);  //为一个矩形  左上角snakeList.push_front(QRectF(leftTop,rightBottom));
}

实现向下移动
void GameRoom::moveDown()
{QPointF leftTop;//左上角坐标QPointF rightBottom; //右下角坐标        左上角坐标右下角坐标唯一确定一个矩形auto snakeNode = snakeList.front();                  //链表int headX = snakeNode.x();  //蛇头xint headY = snakeNode.y();  //蛇头yif(headY > this->height() ) //蛇头跑到外面了{leftTop =QPointF(headX,0);}else{leftTop = snakeNode.bottomLeft();}rightBottom = leftTop+QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightBottom));}
实现向左移动
void GameRoom::moveLeft()
{QPointF leftTop;QPointF rightButtom;auto snakeNode = snakeList.front();int headX = snakeNode.x();int headY = snakeNode.y();if(headX < 0){leftTop = QPointF(800 - kSnakeNodeWidth,headY);}else{leftTop = QPointF(headX - kSnakeNodeWidth,headY);}rightButtom = leftTop +QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightButtom));}
实现向右移动
void GameRoom::moveRight()
{QPointF leftTop;QPointF rightButtom;auto snakeNode = snakeList.front();int headX = snakeNode.x();int headY = snakeNode.y();if(headX + kSnakeNodeWidth > 780){leftTop = QPointF(0,headY);}else{leftTop = snakeNode.topRight();}rightButtom = leftTop + QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightButtom));
}

重写绘图事件函数进行渲染 重写基类的 paintEvent() 方法进行渲染:

  • 渲染背景图
  • 渲染蛇头
  • 渲染蛇⾝体
  • 渲染蛇尾巴
  • 渲染右边游戏控制区域
  • 渲染食物节点
  • 渲染当前分数
  • 游戏结束渲染 game over!
void gameroom::paintEvent(QPaintEvent *event)
{QPainter painter(this);QPixmap pix;pix.load(":res/simple_room.png");painter.drawPixmap(0,0,800,800,pix);painter.setRenderHint(QPainter::Antialiasing); //设置抗锯⻮// 渲染蛇头if(moveDirect == SnakeDirect::UP) {pix.load(":res/up.png");} else if(moveDirect == SnakeDirect::DOWN) {pix.load(":res/down.png");} else if(moveDirect == SnakeDirect::LEFT) {pix.load(":res/left.png");} else {pix.load(":res/right.png");}auto snakeHead = snakeList.front();painter.drawPixmap(snakeHead.x(), snakeHead.y(), snakeHead.width(), 
snakeHead.height(), pix);//渲染蛇⾝体pix.load(":res/body.png");for (int i = 1; i < snakeList.size() - 1; i++) {
auto node = snakeList.at(i);painter.drawPixmap(node.x(),node.y(),node.width(),node.height(),pix);}// 渲染贪吃蛇尾巴auto snakeTail = snakeList.back();painter.drawPixmap(snakeTail.x(),snakeTail.y(),snakeTail.width(),snakeTail.heig
ht(),pix);//渲染⻝物pix.load(":res/normal_food.bmp");painter.drawPixmap(foodRect.x(), foodRect.y(), foodRect.width(), 
foodRect.height(), pix);//渲染右边区域pix.load(":res/right_area.png");painter.drawPixmap(800, 0, 200, 1000, pix);// 渲染分数pix.load(":res/sorce_bg.png");painter.drawPixmap(this->width() * 0.85, this->height() * 0.02, 90, 40, 
pix);QPen pen;pen.setColor(Qt::black);painter.setPen(pen);QFont font("⽅正舒体", 22, QFont::ExtraLight, false);painter.setFont(font);painter.drawText(this->width() * 0.90, this->height() * 0.06, 
QString("%1").arg(snakeList.size()));// 如果检查失败, 渲染game overif(checkFail()){pen.setColor(Qt::red);painter.setPen(pen);QFont font("⽅正舒体", 50, QFont::ExtraLight, false);painter.setFont(font);painter.drawText(this->width() * 0.5 - 250, this->height() * 0.5, 
QString("GAME OVER!"));timer->stop();QSound::play(":res/gameover.wav");sound->stop();
}
}

检查是否自己会不会撞自己

bool GameRoom::checkFail()
{// 判断头尾是否出现相交for(int i = 0; i < snakeList.size(); i++){for(int j = i + 1; j < snakeList.size(); j++){if(snakeList.at(i) == snakeList.at(j)) {return true;}}}return false;
}

设置游戏开始和游戏暂停按钮

 QPushButton *startbtn = new QPushButton(this);QPushButton *stopbtn = new QPushButton(this);QFont ft("楷体", 20, QFont::ExtraLight, false);//设置按钮的位置startbtn->move(860,150);stopbtn->move(860,200);//设置按钮⽂本startbtn->setText("开始");stopbtn->setText("暂停");//设置按钮样式startbtn->setStyleSheet("QPushButton{border:0px;}");stopbtn->setStyleSheet("QPushButton{border:0px;}");
//设置按钮字体格式startbtn->setFont(ft);stopbtn->setFont(ft);connect(startbtn,&QPushButton::clicked,this,[=](){sound = new QSound(":res/Trepak.wav"); //声⾳路径sound->play(); //播放sound->setLoops(-1); //循环播放isGameStart = true;timer->start(moveTimeout);});connect(stopbtn,&QPushButton::clicked,this,[=](){sound->stop();isGameStart = false;timer->stop();});

设置退出游戏按钮

当我们点击退出游戏按钮时,当前游戏房间窗口不会立即退出,是会弹窗提示,提示我们是否要退出游戏
//退出游戏按钮QPushButton *ExitGame = new QPushButton(this);ExitGame->setStyleSheet("QPushButton{border:0px;}");ExitGame->move(860,750);ExitGame->setFont(ft);ExitGame->setText("退出");//消息提⽰QPushButton *okbtn = new QPushButton("Ok");QPushButton *cancelbtn = new QPushButton("Cancel");QMessageBox *msg = new QMessageBox(this);msg->setWindowTitle("退出游戏"); //设置消息对话框的标题msg->setText("确认退出游戏吗?"); //设置消息对话框内容msg->setIcon(QMessageBox::Question); //设置消息对话框类型msg->addButton(okbtn,QMessageBox::AcceptRole); //Accept Role:接受的⻆⾊msg->addButton(cancelbtn,QMessageBox::RejectRole); //Reject Role:排斥
作⽤connect(ExitGame,&QPushButton::clicked,[=](){//消息提⽰msg->show();QSound::play(":res/clicked.wav");msg->exec(); //阻塞等待⽤⼾输⼊if(msg->clickedButton() == okbtn) //点击了ok按钮{this->close();//如果点击了 Ok 按钮,那么就会跳转到游戏关卡界⾯GameSelect *s = new GameSelect;s->show();s->setGeometry(this->geometry());QSound::play(":res/clicked.wav");sound->stop(); //停⽌背景⾳乐}else{msg->close();QSound::play(":res/clicked.wav");}});

获取历史战绩

int c = snakeList.size();
2 QFile file("C:/Users/Lenovo/Desktop/1.txt");
3 if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
4 QTextStream out(&file);
5 int num = c;
6 out << num; // 将int类型数据写⼊⽂件
7 file.close();

读⽂件:读取写⼊文件中蛇的长度

QFile file("C:/Users/Lenovo/Desktop/1.txt");
2 file.open(QIODevice::ReadOnly);
3
4 QTextStream in(&file); //创建⽂本流对象
5 int data = in.readLine().toInt(); //读取第⼀⾏作为整形数据

相关文章:

简单Qt贪吃蛇项目

目录 先看效果 项目介绍 界面一&#xff1a;游戏大厅界面 界面二&#xff1a;关卡选择界面​编辑 界面三&#xff1a;游戏界面 游戏大厅页面 游戏关卡选择页面 游戏房间页面 封装贪吃蛇数据结构 初始化游戏房间界面 设置窗口大小、标题、图标等 蛇的移动 初始化贪…...

画菱形(曼哈顿距离)

输入一个奇数 nn&#xff0c;输出一个由 * 构成的 nn 阶实心菱形。 输入格式 一个奇数 nn。 输出格式 输出一个由 * 构成的 nn 阶实心菱形。 具体格式参照输出样例。 数据范围 1≤n≤991≤n≤99 输入样例&#xff1a; 5输出样例&#xff1a; * *** ******** * #i…...

CSP初赛知识点讲解(六)

CSP初赛知识点讲解&#xff08;六&#xff09; 运算表达式中缀变后缀表达式求值前缀表达式 例题训练&#xff08;八&#xff09; 运算表达式 运算表达式有三种&#xff0c;前缀表达式&#xff0c;中缀表达式&#xff0c;后缀表达式&#xff0c;我们常用的是中缀表达式&#xf…...

linux rocky 9.2系统安装mysql-wsrep-8.4.2-26.20-linux-x86_64.tar.gz二进制包

1.环境准备&#xff0c; ①装好Rocky linux9.2系统&#xff0c;设置好IP nmcli con mod ens160 ipv4.addresses 192.168.0.106/24 nmcli con mod ens160 ipv4.gateway 192.168.0.2 nmcli con mod ens160 ipv4.dns 114.114.114.114 nmcli con up ens160 nmcli con mod ens…...

QT实现上传服务器功能

代码如下所示&#xff1a; void UploadZipFileToServer(const QString& strPath) {m_pFile new QFile(strPath);// 创建HTTP多部份请求QHttpMultiPart *multiPart new QHttpMultiPart(QHttpMultiPart::FormDataType);QHttpPart keyPart;keyPart.setHeader(QNetworkReques…...

元岳食堂采购供应链系统-智慧食堂数据化解决方案

随着社会的发展和科技的进步&#xff0c;在数字化浪潮的推动下&#xff0c;智慧食堂供应链系统逐渐成为食堂管理的重要工具。在此背景下&#xff0c;元岳食堂采购供应链系统应运而生&#xff0c;该系统通过其独特的数字化和自动化功能&#xff0c;能够对食堂的采购、储存、配送…...

基于Java+SpringBoot+Vue的影城管理系统

基于JavaSpringBootVue的影城管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 哈喽…...

自定义starter

依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 ht…...

Docker 入门全攻略:安装、操作与常用命令指南

目录 Docker 入门全攻略&#xff1a;安装、操作与常用命令指南 一、引言 二、Docker 下载与安装 2.1 Docker 的系统要求 2.2 安装步骤 ①对于 Windows 的安装指南 ②对于 macOS 的安装指南 ③对于 Linux 的安装指南 三、Docker 的基本概念 3.1 镜像&#xff08;Image…...

mstsc被卸载,远程桌面mstsc.exe重装

官网下载地址g卸载和重新安装远程桌面连接 | Microsoft Learn 卸载和重新安装远程桌面连接 | Microsoft Learn 下载地址 https://wwm.lanzouj.com/ioR4y26z7rle 下载后重新安装...

从根儿上学习spring 十一 之run方法启动第四段(5)

图15-AbstractAutowireCapableBeanFactory#doCreateBean方法 我们接着讲doCreateBean方法&#xff0c;之前对循环依赖做了些解释&#xff0c;我们接着往下看populateBean(beanName, mbd, instanceWrapper)方法 图15-572行 这行就是调用populateBean(beanName, mbd, instanceW…...

常见8种数据结构

常见的数据结构包括数组、链表、队列、栈、树、堆、哈希表和图&#xff0c;每种数据结构都有其特点&#xff0c;如下&#xff1a; 常见数据结构 1.数组2.链表3.队列4.栈5.树6.图7.哈希表8.堆 1.数组 特点&#xff1a; 固定大小的线性数据结构支持快速随机访问插入和删除效率…...

黑马Java零基础视频教程精华部分_11_面向对象进阶(3)_抽象类、接口、适配器

《黑马Java零基础视频教程精华部分》系列文章目录 黑马Java零基础视频教程精华部分_1_JDK、JRE、字面量、JAVA运算符 黑马Java零基础视频教程精华部分_2_顺序结构、分支结构、循环结构 黑马Java零基础视频教程精华部分_3_无限循环、跳转控制语句、数组、方法 黑马Java零基础视…...

Promethues Metrics

Metrics Metrics可分为三部分&#xff1a; HELP 描述metric作用TYPE metric类别 TYEP Counter 某个事件发生的次数数字只能增长 Total reuqests Total ExceptionsGauge 描述当前值可以上升或下降 CurrentCPU Utilization Available System Memory Number of concurren…...

公网IP与私网IP具体有哪些区别?

1.接入方式不同 公网IP以公网连接Internet上的非保留地址&#xff0c;私网IP则是局域网上的IP&#xff0c;通过NAT才能够与公网进行通信。 2.特点不同 公网IP由国际互联网络信息中心InterNIC负责,将IP地址分配给注册并向InterNIC提出申请的机构或组织。私网IP则是为节省可分配…...

LeetCode——3143. 正方形中的最多点数

通过万岁&#xff01;&#xff01;&#xff01; 题目&#xff1a;给你一个n*2的数组&#xff0c;然后第i行表示第i个点的坐标&#xff0c;然后还给你了一个字符串s&#xff0c;s[i]则表示第i个点的名称。然后让你找一个中心是&#xff08;0,0&#xff09;的正方形&#xff0c;…...

const重新赋值的问题

问: const haveNextPage false; // 默认没有下一页fetch(historyFullUrl).then(data > {haveNextPage data.data.has_more;这段代码有什么问题吗? 回答: 在你的代码中&#xff0c;有一个潜在的问题涉及到 haveNextPage 的赋值。你定义了 haveNextPage 作为一个常量&am…...

python开发上位机 - PyCharm环境搭建、安装PyQt5及工具

目录 简介&#xff1a; 一、安装PyCharm 1、下载 PyCharm 2、PyCharm安装 1&#xff09;配置安装目录 2&#xff09;安装选项 3、问题及解决方法 二、安装PyQt5 1、打开 Pycharm&#xff0c;新建 Project 2、安装 pyqt5 3、安装很慢怎么办&#xff1f; 4、安装 pyq…...

day02-安装虚拟机

1. 安装配置 前面一直下一步就OK 2. 虚拟机操作系统配置 语言 中文 软件安装&#xff1a; 最小安装&#xff0c;标准&#xff0c;调试工具&#xff0c;开发工具&#xff0c;系统工具&#xff0c;man手册 网络和主机名配置 主机名&#xff0c;自己起名字 网络配置 常规 &g…...

Qt:线程

一个Qt窗口生成后&#xff0c;为什么拖动窗口&#xff0c;窗口可以随着鼠标移动或放大缩小 因为对窗口操作后&#xff0c;都有对应的事件产生&#xff0c;Qt在其框架中对这些事件进行了默认处理 一个Qt程序默认只有一个线程&#xff0c;称为主线程&#xff08;也叫ui线程&#…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...