Qt_绘图

目录

1、绘图核心类

2、QPainter类的使用

2.1 绘制线段 

2.2 绘制矩形 

2.3 绘制圆形 

2.4 绘制文本 

3、QPen类的使用

3.1  使用画笔

4、QBrush类的使用 

4.1 使用画刷

5、绘制图片 

5.1 测试QPixmap

5.1.1 图片移动

5.1.2 图标缩小 

5.1.3 旋转图片 

5.1.4 将QPixmap作为绘图设备 

5.2 测试QImage 

5.3 测试QPicture

结语 


前言:

        Qt提供了DIY度极强的绘图功能,目的就是解决在特殊场景时,使用系统提供的控件无法达到预期的效果。Qt的绘图功能提供了相关的方法,允许开发者在界面中绘制任意的图形形状,以完成更复杂的界面设计。

1、绘图核心类

         要想使用绘图功能,则必须用Qt提供的与绘图相关的类来实例化出对象,常用的核心类介绍如下(通过以下类的直译也可以看出其作用):

QPainter(画家)
进行绘图操作的最基本的类,该类提供了⼀系列drawXXX方法,允许在界面中绘制各种图形
QPen(画笔)
描述用QPainter画出来的线的样式
QBrush(画刷)
用来填充用QPainter画出来区域
QPaintDevice(画板)
描述用QPainter画出来图形在哪个对象上,比如画在QWidget上,则QWidget就是画板,而且QWidget本身就继承自QPaintDevice,所以他本就可以作为被画对象

        值得注意的是:绘图操作不能直接在界面的构造函数处执行,比如不能在QWidget构造函数中进行绘图,原因很简单,可以理解为绘图的前提是必须得有画板,而执行到QWidget构造函数时,还没有生成完整的画板,因此哪怕此时绘图了也不能在最终的界面上显示出来,因为“画快了”

        所以把绘图操作放到Qt提供的paintEvent事件中(即重写该事件,实现绘图功能),而paintEvent事件会在以下情况自动触发并执行对应的动作:

1、控件首次创建的时候。

2、控件被遮挡后再解除遮挡的时候。(比如用一个界面去挡住另一个界面,然后将他们分开,他们不会影响彼此的界面内容,原因就是paintEvent的执行动作在重新绘图)

3、将窗口最小化的时候。(然后恢复窗口,窗口的内容不会受到影响(注:窗口实际上就是控件))

4、将控件进行放大缩小的时候。

5、在代码中主动调用repaint()或者update()函数。(这两个函数都是QWidget提供的)

        因此当paintEvent事件触发时就会重新进行绘图,这也是为什么在计算机屏幕中可以不断的来回切换各种图形界面,给人的感觉是计算机如同一本书一样可以来回翻页,实际上是计算机强大的计算能力在不断的重新绘图。

2、QPainter类的使用

        介绍QPainter类中的系列函数drawxxx的使用,即进行一些基本的绘图。

2.1 绘制线段 

        使用QPainter提供的函数drawLine进行绘制线段,该函数介绍如下:

void drawLine(const QPoint &p1, const QPoint &p2);
//p1:绘制起点坐标
//p2:绘制终点坐标

        在widget.h中声明paintEvent事件,代码如下:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void paintEvent(QPaintEvent *event);//重写paintEvent事件private:Ui::Widget *ui;
};
#endif // WIDGET_H

        在widget.cpp中重写paintEvent事件,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{//this表示在当前窗口中绘画QPainter painter(this);//在20,20坐标到200,20坐标画一条线painter.drawLine(QPoint(20,20),QPoint(200,20));
}

        运行结果如下:

2.2 绘制矩形 

        使用QPainter提供的函数drawRect进行绘制线段,该函数介绍如下:

void QPainter::drawRect(int x, int y, int width, int height);
//x:矩形左上角横坐标;
//y:矩形左上角纵坐标;
//width:矩形的宽度;
//height:矩形的⾼度

        widget.h代码依旧是声明paintEvent事件,因此不再展示widget.h代码,直接展示widget.cpp代码:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{//this表示在当前窗口中绘画QPainter painter(this);//在坐标(20,20)处绘制一个长200宽200的矩形painter.drawRect(20,20,200,200);
}

        运行结果:

2.3 绘制圆形 

        使用QPainter提供的函数drawEllipse进行绘制线段,该函数介绍如下:

void QPainter::drawEllipse(const QPoint &center, int rx, int ry)
//center:中⼼点坐标
//rx:圆的宽度
//ry:圆的高度

        widget.cpp代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{//this表示在当前窗口中绘画QPainter painter(this);//将绘画颜色改成红色painter.setPen(Qt::red);//在坐标(100,100)处换一个宽50高50的红色圆形painter.drawEllipse(QPoint(100,100),50,50);
}

        运行结果:

2.4 绘制文本 

         QPainter不仅可以绘图,还可以绘制文本,这样在界面上写字时就不再需要QLabel作为文本的载体了。使用drawText()函数来绘制文章,还可以配合setFont()函数来设置字体样式,让字体看起来更加饱满。drawText函数介绍如下:

void drawText(const QPoint &position, const QString &text)
//position表示文本的坐标
//text表示文本内容

        值得注意的是,这里文本坐标是指文本最左侧的基线出的位置,如下图:

        测试代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{//this表示在当前窗口中绘画QPainter painter(this);//设置字体样式painter.setFont(QFont("华文行楷",30));//设置画笔painter.setPen(Qt::green);painter.drawText(QPoint(150,200),"雨打蕉叶又潇潇了几夜");}

         运行结果:

3、QPen类的使用

        使用QPainter绘图时,默认有一个画笔(没有画笔则无法绘图,只不过默认画笔就是最普通的文本样式),当然也可以自定义画笔。在Qt中,QPen类表示画笔,该类定义了QPainter绘图的颜色,线条宽度、线条样式。同时通过QPen类提供的函数来设置上述属性,常用函数如下:

QPen(const QColor &color)通过QPen构造函数来设置画笔颜色
void setWidth(int width)设置画笔画出线条的宽度
void setStyle(Qt::PenStyle style)设置画笔画出线条的样式

        其中Qt::PenStyle提供了以下的风格:

        将上述的枚举常量传给setStyle,则画笔就可以画出不同的样式。

3.1  使用画笔

        对上述画矩形的代码进行画笔修饰,代码如下: 

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{//this表示在当前窗口中绘画QPainter painter(this);//自定义画笔QPen pen(QColor(0,255,0));//设置画笔宽度pen.setWidth(30);//设置画笔样式pen.setStyle(Qt::DotLine);//将画笔设置到画家中painter.setPen(pen);//在坐标(20,20)处绘制一个长200宽200的矩形painter.drawRect(20,20,200,200);
}

        运行结果:

4、QBrush类的使用 

         QBrush类表示画刷,作用是填充图形,可以通过QBrush提供的函数,对填充样式进行更改,比如颜色、风格等。常用函数介绍如下:

QPen(const QColor &color)设置画刷的颜色
void setStyle(Qt::BrushStyle style)设置画刷的风格

        其中Qt::BrushStyle是一个枚举类型,他提供了多个枚举常量供开发者选择画刷的风格,如下图:

4.1 使用画刷

        对上述画笔代码进行添加画刷,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{//this表示在当前窗口中绘画QPainter painter(this);//自定义画笔QPen pen(QColor(0,255,0));//设置画笔宽度pen.setWidth(30);//设置画笔样式pen.setStyle(Qt::DotLine);//将画笔设置到画家中painter.setPen(pen);//自定义画刷QBrush brush(Qt::cyan);//设置画刷的风格brush.setStyle(Qt::Dense1Pattern);//将画刷设置到画家中painter.setBrush(brush);//在坐标(20,20)处绘制一个长200宽200的矩形painter.drawRect(20,20,200,200);
}

         运行结果:

5、绘制图片 

        上文的例子说明了如何在界面中手动绘图,然而Qt还提供了对现有图片进行处理的类,分别是QImage、QPixmap、QBitmap和QPicture,这些都是Qt封装好的绘图设备。其中,QImage可以对图片进行像素级别的操作,QPixmap可以将图片显示到屏幕上,QBitmap是QPixmap的子类,只能显示黑白两种颜色,QPicture用来记录并重演QPainter命令。

5.1 测试QPixmap

        QPainter提供了drawPixmap函数,该函数可以将QPixmap中的资源显示在界面上,该函数介绍如下:

void drawPixmap(int x, int y, const QPixmap &pm)
//x表示图片左上角的横坐标
//y表示图片左上角的纵坐标
//pm表示图片资源

         首先需要创建一个虚拟目录(虚拟目录详细见:Qt_控件的QWidget属性介绍-第五点),如下图:

        代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);//创建QPixmap对象QPixmap map(":/kklt.png");//将图片设置在坐标20,20处painter.drawPixmap(20,20,map);
}

         运行结果:

5.1.1 图片移动

        将上述图片进行移动操作,移动的本质是将QPainter进行移动,而不是直接对QPixmap进行移动,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);//创建QPixmap对象QPixmap map(":/kklt.png");//移动画家painter.translate(100,100);//将图片设置在坐标20,20处painter.drawPixmap(20,20,map);
}

        运行结果:

5.1.2 图标缩小 

        将上述图片进行缩小,函数仍然使用drawPixmap,该函数也拥有缩小的功能,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);//创建QPixmap对象QPixmap map(":/kklt.png");//    //移动画家
//    painter.translate(100,100);//将图片设置在坐标20,20处,尺寸不变painter.drawPixmap(20,20,map);//将图片设置在坐标500,20处,尺寸为50*50像素painter.drawPixmap(650,20,50,50,map);
}

         运行结果:

5.1.3 旋转图片 

        旋转图片的逻辑稍微复杂点,使用QPainter类中的rotate()函数进行旋转,并且旋转的不是图片,而是QPainter本身,所以会导致一种情况,即旋转之后的QPainter不在当前窗口中,然后我们在该QPainter上显示的图片也不会在当前窗口中显示,如下图:

        从这里也可以得到一个结论:QPainter是一种类似于”附在“窗口界面上的媒介,我们往窗口中写入的资源实际上是写到该QPainter中,然后QPainter再写入至窗口中,即QPainter和窗口界面是相互独立的,且QPainter可以移动,但是当QPainter超出了窗口,则QPainter就不能将超出部分的资源写入窗口中了。因此要将旋转之后的QPainter再进行移动,将其移动回窗口界面中,注意旋转过后的原点位置以及坐标系都变了


        测试代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);//创建QPixmap对象QPixmap map(":/kklt.png");//旋转QPainter,顺时针旋转90°painter.rotate(90);//将QPainter移回窗口界面中painter.translate(0,-500);//将图片设置在坐标20,20处,尺寸不变painter.drawPixmap(20,20,50,50,map);}

        运行结果:

5.1.4 将QPixmap作为绘图设备 

        上述中的QPixmap是作为图片载体,然而QPixmap还可以作为绘图的对象,即将QPixmap作为画板。测试代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QPixmap>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//将QPixmap作为画板,尺寸为500*500pxQPixmap pixmap(300,300);//将pixmap的背景色调成白色pixmap.fill(Qt::white);//让画家在QPixmap上绘画QPainter painter(&pixmap);//在QPixmap上画一个圆painter.drawEllipse(QPoint(100,100),50,50);//为了观察是否画在QPixmap上,将QPixmap上的内容保存到文件中pixmap.save("D:\\Qt_code\\QPixmap\\pix.png");
}Widget::~Widget()
{delete ui;
}

        运行结果:

5.2 测试QImage 

        QImage也可以像QPixmap一样作为画板,并且也可以保存到磁盘的文件夹中,此功能就不再测试了。主要测试QImage更改像素的功能,首先重写paintEvent事件,通过函数setPixel来设置某个像素的颜色值,使用qRgb表示⼀个具体的颜色值,测试代码如下: 

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);QImage image;image.load(":\kklt.jpg");//修改像素点for(int i = 0;i<200;i++)for(int j = 0;j<200;j++){QRgb rgb = qRgb(0,255,255);image.setPixel(i,j,rgb);}painter.drawImage(20,20,image);
}

        运行结果:

5.3 测试QPicture

        QPicture最重要的功能是能够记录QPainter的操作步骤,他跟上述几个类不一样,上述的类是作为QPainter的画板,QPainter将最终的成品绘制在面板中呈现给用户看。而QPicture是记录QPainter绘制的操作,然后将该操作进行复盘,再将复盘的结果呈现给用户看,他们本质上大同小异。


        首先需要将QPicture实例作为参数传递给QPainter::begin()函数,以便告诉系统开始记录,记录完毕后使用QPainter::end()命令终止。测试代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QPicture>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPicture picture;QPainter painter;painter.begin(&picture);painter.drawEllipse(20,20,50,50);//画一个圆painter.end();//此时picture中存放的就是QPainter的操作步骤,将picture保存到磁盘上picture.save("D:\\Qt_code\\QPicture\\pic.pic");
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter1(this);//从磁盘上加载到picture1中QPicture picture1;picture1.load("D:\\Qt_code\\QPicture\\pic.pic");//将picture1的内容用painter1画出来,此时picture1里面存放的并不是图形painter1.drawPicture(30,30,picture1);}

        测试结果:

结语 

        以上就是关于Qt绘图的讲解,Qt内部提供了许多功能齐全的部分供我们使用,因此在大部分的场景下很少用到绘图功能,但是不排除一些特别场景,并且这些内置控件的底层也是由绘图一步步画出来的,因此了解绘图也可以更好的了解这些控件的原理。其次就是绘图可以让开发者进行界面开发时拥有很高的自由度,设计一些样式时不再依赖控件作为载体。

        最后如果本文有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!!   

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【四】Spring Cloud OpenFeign原理分析

Spring Cloud OpenFeign原理分析 概述 Spring Cloud 微服务实践也有挺多年了&#xff0c;一直想着总结一下这系列的知识点&#xff0c;最近终于下定决心来出一个Spring Cloud 系列文章了。本文主要围绕fegin组件来进行讲解&#xff0c;文中将会给出基础使用的示例&#xff0c;还…

docker-compose 快速部署clickhouse集群

在本教程中&#xff0c;我们将学习如何使用 Docker Compose 部署一个带有三节点的 ClickHouse 集群&#xff0c;并使用 ZooKeeper 作为分布式协调服务。 前提条件 注意事项&#xff1a; 镜像版本号注意保持一致 [zookeeper:3.7, clickhouse/clickhouse-server:22.5.4]config…

uniapp微信小程序使用ucharts遮挡自定义tabbar的最佳解决方案

如图所示&#xff1a; 使用的ucharts遮挡住了我自定义的tabbar&#xff08;如果不是提需求的有病&#xff0c;我才不会去自定义tabbar&#xff09; 查阅了不少文档&#xff0c;说是开启 ucharts 的 canvas2d 即可&#xff1a; 官网文档地址&#xff1a; uCharts官网 - 秋云…

资源《Arduino 扩展板1-LED灯》说明。

资源链接&#xff1a;Arduino 扩展板1-LED灯 1.文件明细&#xff1a; 2.文件内容说明 包含&#xff1a;AD工程、原理图、PCB。 3.内容展示 4.简述 该文件为PCB工程&#xff0c;采用AD做的。 该文件打板后配合Arduino使用&#xff0c;属于Arduino的扩展板。 该文件主要有…

深度学习自编码器 - 分布式表示篇

序言 深度学习作为人工智能领域的重要分支&#xff0c;其核心在于表示学习&#xff08; Representation Learning \text{Representation Learning} Representation Learning&#xff09;&#xff0c;尤其是分布式表示&#xff08; Distributed Representation \text{Distribut…

netty之基础aio,bio,nio

前言 在Java中&#xff0c;提供了一些关于使用IO的API&#xff0c;可以供开发者来读写外部数据和文件&#xff0c;我们称这些API为Java IO。IO是Java中比较重要知识点&#xff0c;且比较难学习的知识点。并且随着Java的发展为提供更好的数据传输性能&#xff0c;目前有三种IO共…

Go基础学习06-Golang标准库container/list(双向链表)深入讲解;延迟初始化技术;Element;List;Ring

基础介绍 单向链表中的每个节点包含数据和指向下一个节点的指针。其特点是每个节点只知道下一个节点的位置&#xff0c;使得数据只能单向遍历。 示意图如下&#xff1a; 双向链表中的每个节点都包含指向前一个节点和后一个节点的指针。这使得在双向链表中可以从前向后或从后…

无人机之数据提取篇

一、无人机平台与传感器 无人机是进行数据采集的基础设施&#xff0c;其稳定性、可靠性、灵活性和负载能力直接影响到数据采集的效果。根据实际需求&#xff0c;需选择适合的无人机类型&#xff0c;如固定翼无人机适合大范围、长时间的数据采集&#xff0c;而多旋翼无人机则更适…

HTML基础用法介绍一

VS code 如何快速生成HTML骨架注释是什么&#xff1f;为什么要写注释&#xff1f;注释的标签是什么&#xff1f;标题标签段落标签换行标签与水平线标签 (都是单标签&#xff09;文本格式化标签图片标签超链接标签音频标签视频标签 &#x1f698;正片开始 VS code 如何快速生成…

基于Spring框架的分层解耦详解

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;Java Web关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Java Web 三层架构&#xff1a; Java Web可以大致被分为三层架构&#xff1a;…

成都睿明智科技有限公司抖音电商服务靠谱吗?

在这个电商风起云涌的时代&#xff0c;抖音作为短视频直播的超级流量池&#xff0c;正深刻改变着人们的购物习惯。无数商家蜂拥而至&#xff0c;渴望在这片蓝海中找到属于自己的岛屿。而提及抖音电商服务&#xff0c;成都睿明智科技有限公司无疑是一个备受瞩目的名字。那么&…

Linux 进程的基本概念及描述

目录 0.前言 1. 什么是进程 1.1 进程的定义与特性 1.2 进程与线程的区别 2.描述进程 2.1 PCB (进程控制块) 2.2 task_struct 3.查看进程 3.1 查看进程信息 3.1.1 /proc 文件系统 3.1.2 ps 命令 3.1.2 top 和 htop 命令 3.2 获取进程标识符 3.2.1使用命令获取PID 3.2.2 使用C语言…

加密与安全_HTOP 一次性密码生成算法

文章目录 HOTP 的基础原理HOTP 的工作流程HOTP 的应用场景HOTP 的安全性安全性增强措施Code生成HOTP可配置项校验HOTP可拓展功能计数器&#xff08;counter&#xff09;计数器在客户端和服务端的作用计数器的同步机制客户端和服务端中的计数器表现服务端如何处理计数器不同步计…

AIGC学习笔记—minimind详解+训练+推理

前言 这个开源项目是带我的一个导师&#xff0c;推荐我看的&#xff0c;记录一下整个过程&#xff0c;总结一下收获。这个项目的slogan是“大道至简”&#xff0c;确实很简。作者说是这个项目为了帮助初学者快速入门大语言模型&#xff08;LLM&#xff09;&#xff0c;通过从零…

vue3学习记录-computed

vue3学习记录-computed 1.为什么要用computed2.使用方法2.1 基本实例2.2 可写计算属性 1.为什么要用computed 写个购物车的案例 <script setup> import { ref, reactive,computed } from "vue" const tableData reactive([{ name: 商品1, price: 10, num: 1…

3. 轴指令(omron 机器自动化控制器)——>MC_MoveRelative

机器自动化控制器——第三章 轴指令 5 MC_MoveRelative变量▶输入变量▶输出变量▶输入输出变量 功能说明▶指令详情▶时序图▶重启运动指令▶多重启动运动指令▶异常 MC_MoveRelative 指定自指令当前位置起的移动距离&#xff0c;进行定位。 指令名称FB/FUN图形表现ST表现MC…

JVM(HotSpot):字符串常量池(StringTable)

文章目录 一、内存结构图二、案例讲解三、总结 一、内存结构图 JDK1.6 JDK1.8 我们发现&#xff0c;StringTable移入了Heap里面。所以&#xff0c;应该想到&#xff0c;StringTable将受到GC管理。 其实&#xff0c;1.6中&#xff0c;在方法区中的时候&#xff0c;也是受GC管…

从底层理解为什么常量区中的代码不能被修改?

目录 前言&#xff1a;一、了解虚拟地址二、页表映射三、常量区不能被修改的原理四、常量区不可修改的意义 前言&#xff1a; 平时我们在编写代码时都会用到或遇到所谓的常量区或者不可修改的代码&#xff0c;比如说用双引号包起来字符串&#xff08;“Hello World”&#xff…

微服务SpringSession解析部署使用全流程

目录 1、SpringSession简介 2、实现session共享的三种方式 1、修改Tomcat配置文件 2、Nginx负载均衡策略 3、redis统一存储 0、准备工作 1、本地服务添加依赖 2、修改本地服务配置文件 3、添加application.properties文件 4、添加nacos - redis配置 5、修改本地项目…

Linux启动mysql报错

甲方公司意外停电&#xff0c;所有服务器重启后&#xff0c;发现部署在Linux上的mysql数据库启动失败.再加上老员工离职&#xff0c;新接手项目&#xff0c;对Linux系统了解不多&#xff0c;解决起来用时较多&#xff0c;特此记录。 1.启动及报错 1.1 启动语句1 启动语句1&a…