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

QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现

一、编码问题

        在计算机编程中,Stream)是一种抽象的概念,用于表示数据的输入或输出。根据处理数据的不同方式,可以分为字节流Byte Stream)和字符流Character Stream)两大类。

1. 字节流(Byte Stream)

        字节流是处理数据的基本单位是字节(8位二进制数据)的流。它不考虑数据的具体内容,只是简单地将数据视为字节序列进行读取或写入。字节流主要用于处理二进制数据,例如图片、视频、音频文件等,或者当你不确定数据的内容时(比如,当你正在读取一个可能是文本也可能是其他格式的文件时)。

        Qt通过QByteArray为我们提供了一个字节数组容器(它是可变长的)。主要用来存储原始的字节流。

QByteArray仍可以表示字符串,类似与unsigned char buf[ ],但是QT中多用QString来表示字符串。

QByteArray一般结合其它类使用,比如QIODevice类的QByteArray QIODevice::readAll()

QByteArray(const char *data, int size = -1)  //构造
char   at(int i) const //返回第i个元素
void   clear()  //清空
bool   contains(const char * str) const  //是否包含字符串  ==strstr
bool   contains(char ch) const //是否包含字符
char   *data()  //从QByteArray类型转化为char *//查找从from开始第一次匹配str的位置
int indexOf(const char *str, int from = 0)
QByteArray & append(char ch)  //尾部增加
QByteArray & prepend(char ch) //头部增加
int length() const //返回长度
QByteArray &remove(int pos, int len)  //删除

2.字符流(Character Stream)

1) 概念

        字符流则是处理数据的基本单位是字符。字符流主要用于处理文本数据。QT通过QString类为我们提供了字符串类。

2) QString相关方法
//数字转字符串, QString静态方法
QString   number(long n, int base = 10) [static]
QString   number(double n, char format = 'g', int precision = 6) [static]

例:

long a = 63;
QString s = QString::number(a, 10);             // s == "63"
QString t = QString::number(a, 16).toUpper();     // t == "3F"
//字符串转为数字
short	toShort(bool * ok = 0, int base = 10) const
float	toFloat(bool * ok = 0) const
long	toLong(bool * ok = 0, int base = 10) const

例:

QString str1 = "1234.56";
str1.toFloat();             // returns 1234.56
//从 QString 转化到 QByteArray
QByteArray toLocal8Bit() const //转成本地编码的字节流
QByteArray toUtf8() const//转成utf8编码的字节流

例:把一个QString转为char *(QString没有直接转换为char *的方法,需要中间经过一层QByteArray的过渡)

QString str1 = "hello";
char *s = str1.toLocal8Bit().data();

总结:字符流一定是字节流, 而字节流不一定是字符流。


问题:有时候数据写入文件,打开文件会出现乱码的情况,这是为什么,如何解决呢?

答:这个是涉及到编码的问题, 如果字节流的编码是UTF8, 而文件中按照GBK编码解析,可能就是乱码。


二、字符集

字符编码的集合


三、字符编码

1. 概念

        我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。

        因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111 = 十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295

        由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122

        但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

        你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

        因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间

注意:QT界面的编码是UTF8的


2. QString转为字节流相关的方法

QByteArray   toLocal8Bit() //把QString按照本地编码转换成QByteArray
QByteArray   toUtf8() //把QString按照utf-8编码转换成QByteArrayQString   fromLocal8Bit(const QByteArray & str)  //将QByteArray按照本地编码转换为QString
QString    fromUtf8(const QByteArray & str) //将QByteArray按照utf-8编码转换为QString


四、其他容器

QList

QVector

QMap

... ...


五、定时器

QTime: 时间类

QTimer: 定时器类

QDateTime: 日期时间类


1. 常用方法

//parent可以传界面的指针,但是没有父子窗体关系,作用仅剩内存管理
QTimer(QObject * parent = 0) 
void   start(int msec)  //参数为ms  定时一次,永久生效
void   stop()  //停止定时器
Signal:
Void  timeout();//一次定时
void QTimer::singleShot(int msec, const QObject * receiver, const char * member) [static]receiver:接收者member:执行函数     1s=1000ms 1ms=1000us  1us=1000ns

每次时间到达后会发出 timeout() 信号


2. 编程步骤

QTimer *timer = new QTimer(this);  //实例化
connect(timer, SIGNAL(timeout()), this, SLOT(update()));  //绑定超时处理函数
timer->start(1000);
...
timer->stop();  //停止定时器

实例需求:做一个时间显示Label,增加“开始”和“结束”按钮,点击开始,lab每1s记录一次时间。(或者通过数码管显示)

QTime:可以获取到系统当前时间

QDateTime:获取系统时间和日期

提示:时间处理用QDateTime

QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间
QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd");//设置系统时间显示格式  

代码:

mytime.h

#ifndef MYTIME_H
#define MYTIME_H#include <QObject>
#include <QDebug>
#include <QThread>
#include <QDateTime>
class MyTime : public QObject
{Q_OBJECT
public:explicit MyTime(QObject *parent = nullptr);void thread_time();void set_flag(int flag);
signals:void my_signal(QString datatime);
public slots:private:int flag = 1;
};#endif // MYTIME_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QDebug>
#include <QThread>
#include "mytime.h"namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();private:Ui::Widget *ui;QThread *thread;MyTime *time;
};#endif // WIDGET_H

mytime.cpp

#include "mytime.h"MyTime::MyTime(QObject *parent) : QObject(parent)
{}void MyTime::thread_time()
{while(flag){QDateTime currentTime = QDateTime::currentDateTime();QString formattedTime = currentTime.toString("hh:mm:ss");qDebug() << formattedTime;emit my_signal(formattedTime);QThread::sleep(1);}
}void MyTime::set_flag(int flag)
{this->flag = flag;
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);thread = new QThread(this);time = new MyTime; // 不能指定父对象ui->lcdNumber->setDigitCount(8);time->moveToThread(thread); // 移动到thread线程中connect(thread,&QThread::started,time,&MyTime::thread_time);connect(this,&Widget::destroyed,this,&Widget::on_pushButton_2_clicked); // 直接点击 X 也能销毁线程connect(time,&MyTime::my_signal,this,[=](QString datatime){ // 只能在主线程对界面进行操作this->ui->lcdNumber->display(datatime);});
}
Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{thread->start();
}void Widget::on_pushButton_2_clicked()
{thread->quit();time->set_flag(0);thread->wait();
}

输出:


六、事件

        由窗口系统或QT自身以及外部外设产生的动作,称为事件。

        比如当按下鼠标或释放鼠标时,会产生鼠标事件,按下键盘时,出现按键事件。

        当某个事件发生时,某个控件要做出响应实现具体业务逻辑,这个操作可以在对应的事件处理函数中实现。


捕捉并处理一个事件的步骤

总目标:所有的事件处理都是通过重写某个事件方法来实现的,可按照如下步骤实现

1. 从逻辑角度判断事件类型,比如你要处理鼠标动作,那肯定是鼠标事件

2. 查找QEvent类的帮助文档,找到enum QEvent::Type中对应的事件,比如QEvent::KeyPress

3. 根据帮助文档,找到相应的事件属于的类,比如QKeyEvent

4. 通过帮助文档的详细介绍部分,找到应该重写的方法,比如QWidget::keyPressEvent()

5. 分析是否可以直接重写事件方法(看能不能修改类的源代码),如果不能,自定义一个类,继承于某个控件类,然后在自定义类中重写其事件方法。

6. void QWidget::​keyPressEvent(QKeyEvent * event),根据具体的需求,通过参数event所属的类,具体分析需要获取的数据,然后进行业务逻辑处理

7. 不需要的事件,交由父类做默认处理(如调用父类的keyPressEvent()方法


案例需求:

1、完善原登录模块。要求用户输入完后按回车键触发登录事件,ESC键退出登录界面

2、界面中添加一个单行输入框,当输入字符为某些特殊字符时候,提示用户并禁止输入。

提示小技巧:QToolTip::showText(this->mapToGlobal(this->pos()), "不能使用特殊字符", this);

代码:

myline.h

#ifndef MYLINE_H
#define MYLINE_H#include <QWidget>
#include <QtWidgets>class myline : public QLineEdit
{Q_OBJECT
public:explicit myline(QWidget *parent = nullptr);void keyPressEvent(QKeyEvent *event);
signals:public slots:
};#endif // MYLINE_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QtWidgets>
namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = nullptr);~Widget();private slots:void on_exit_button_clicked();private:Ui::Widget *ui;void keyPressEvent(QKeyEvent *event);
};#endif // WIDGET_H

myline.cpp

#include "myline.h"myline::myline(QWidget *parent) : QLineEdit (parent)
{}void myline::keyPressEvent(QKeyEvent *event)
{qDebug("mylineedit: %x",event->key());if(event->key() == Qt::Key_Slash)QToolTip::showText(this->mapToGlobal(this->pos()), "不能使用特殊字符", this);else{QLineEdit::keyPressEvent(event);}
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "myline.h"
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::keyPressEvent(QKeyEvent *event)
{qDebug("%x",event->key());if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter){ // <CR>QString name = ui->name_edit->text();QString passwd = ui->passwd_edit->text();if(name == "wanghan" && passwd == "123456"){qDebug()<<"ok"<<endl;}}if(event->key() == Qt::Key_Escape){ // escthis->close();}
}void Widget::on_exit_button_clicked()
{this->close();
}

输出:

起始页面

输入特殊字符时


七、绘图事件

void QWidget::paintEvent(QPaintEvent *event);

注意:绘图事件不能直接调用, 当窗口发生变化时,QT内部会自动调用绘图事件,或者调用update方法,也会间接调用。


绘图相关的类

//构造方法, 设置绘制设备
QPainter(QPaintDevice *device)
//设置画笔
void setPen(const QPen &pen)
//设置画刷
void setBrush(const QBrush &brush)
//绘制直线
void drawLine(int x1, int y1, int x2, int y2)
//绘制矩形
void drawRect(const QRectF &rectangle)
void drawRect(int x, int y, int width, int height)
//绘制图片  x,y相对绘制设备的原点, 一般直接传0, 0
void drawPixmap(int x, int y, const QPixmap &pixmap)
void drawPixmap(const QRect &rectangle, const QPixmap &pixmap)
void drawPixmap(int x, int y, int width, int height, const QPixmap &pixmap)
//绘制圆形 或者椭圆
void drawEllipse(int x, int y, int width, int height)
//绘制文本
void drawText(int x, int y, const QString &text)//画笔构造方法
QPen(const QColor &color)
QPen(Qt::PenStyle style)
void setWidth(int width)//设置画刷的宽度//画刷构造方法
QBrush(const QColor &color, Qt::BrushStyle style = Qt::SolidPattern)
QBrush(Qt::BrushStyle style)

相关文章:

QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现

一、编码问题 在计算机编程中&#xff0c;流&#xff08;Stream&#xff09;是一种抽象的概念&#xff0c;用于表示数据的输入或输出。根据处理数据的不同方式&#xff0c;流可以分为字节流&#xff08;Byte Stream&#xff09;和字符流&#xff08;Character Stream&#xff0…...

学习electron

一、开发环境 1、先行安装 node.js 和 npm 2、检查 Node.js 是否正确安装&#xff0c;请在您的终端输入以下命令&#xff1a;检测安装的版本 node -v npm -v 注意 因为 Electron 将 Node.js 嵌入到其二进制文件中&#xff0c;你应用运行时的 Node.js 版本与你系统中运…...

《C++智能合约与区块链底层交互全解析:构建坚实的去中心化应用桥梁》

在区块链技术的广阔天地里&#xff0c;C智能合约扮演着极为关键的角色&#xff0c;而其与区块链底层的交互则是实现各种去中心化应用功能的核心环节。深入理解并掌握这种交互机制&#xff0c;对于区块链开发者来说至关重要&#xff0c;它犹如一座桥梁&#xff0c;将智能合约的业…...

MySQL:事务

什么是事务 事务就是把SQL语句打包成一个整体&#xff0c;在这组SQL执行的时候&#xff0c;要么同时成功&#xff0c;要么同时失败。 事务的ACID特性 事务的ACID特性指的是 Atomicity (原⼦性)&#xff0c; Consistency (⼀致性)&#xff0c; Isolation (隔离 性)和 Durabi…...

Linux——进程间通信之管道

进程间通信之管道 文章目录 进程间通信之管道1. 进程间通信1.1 为什么要进行进程间的通信1.2 如何进行进程间的通信1.3 进程间通信的方式 2. 管道2.1 匿名管道2.1.1 系统调用pipe()2.1.2 使用匿名管道进行通信2.1.1 匿名管道四种情况2.1.2 匿名管道的五大特性2.1.3 进程池 2.2 …...

java-排序算法汇总

排序算法&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09; 选择排序&#xff08;Selection Sort&#xff09; 插入排序&#xff08;Insertion Sort&#xff09; 快速排序&#xff08;Quick Sort&#xff09; 归并排序&#xff08;Merge Sort&#xff09; 堆排序&…...

Vscode进行Java开发环境搭建

Vscode进行Java开发环境搭建 搭建Java开发环境(Windows)1.Jdk安装2.VsCode安装3.Java插件4.安装 Spring 插件5.安装 Mybatis 插件5.安装Maven环境6.Jrebel插件7.IntelliJ IDEA Keybindings8. 收尾 VS Code&#xff08;Visual Studio Code&#xff09;是由微软开发的一款免费、开…...

算法学习笔记(五):二叉树一遍历、DFS

一.遍历二叉树 二叉树TreeNode类 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, Tree…...

#Verilog HDL# Verilog中的generate用法集锦

生成块允许复制模块实例或有条件地实例化任何模块。它提供了基于Verilog参数构建设计的能力。当相同的操作或模块实例需要重复多次,或者当某些代码需要根据给定的Verilog参数有条件地包含时,这些语句特别方便。 生成块不能包含端口、参数、specparam声明或指定块。但是,允许…...

简述C++map容器

pair键值对 std::pair在很多关联容器&#xff08;如std::map、std::multimap、std::set、std&#xff1a;multiset等&#xff09;中被广泛应用。以std::map为例&#xff0c;std::map是一个键值对的容器&#xff0c;其中每个元素都是一个std::pair&#xff0c;键用于唯一标识元…...

Vue 学习随笔系列十七 -- 表格样式修改

表格样式修改 文章目录 表格样式修改一、表格背景颜色修改1、方法一2、方法二 二、多级表头颜色修改 一、表格背景颜色修改 1、方法一 表格外套一个 div &#xff0c;修改div的背景色&#xff0c;并将表格背景色设置为透明 参考代码&#xff1a; <template><div cl…...

08 —— Webpack打包图片

【资源模块 | webpack 中文文档 | webpack中文文档 | webpack中文网】https://www.webpackjs.com/guides/asset-modules/?sid_for_share99125_3 Webpack打包图片以8KB为临界值判断 大于8KB的文件&#xff1a;发送一个单独的文件并导出URL地址 小于8KB的文件&#xff1a;导出一…...

01.Django快速入门

一、Django 快速入门 使用最新版本 Django4.2LTS 版本,3 年内不需要更换版本由浅入深讲解&#xff0c;浅显易懂课程大纲全面包含 Django 框架知识点&#xff0c;内容丰富全面细致知识点结合项目实战实现全栈项目应用 Django 官网(文档): https://docs.djangoproject.com/zh-h…...

【大数据学习 | Spark-Core】spark-shell开发

spark的代码分为两种 本地代码在driver端直接解析执行没有后续 集群代码&#xff0c;会在driver端进行解析&#xff0c;然后让多个机器进行集群形式的执行计算 spark-shell --master spark://nn1:7077 --executor-cores 2 --executor-memory 2G sc.textFile("/home/ha…...

Modern Effective C++ Item 14 如果函数不抛出异常请使用noexcept

C11 noexcept关键字用于指定函数不会抛出异常&#xff0c;有助于提高程序的异常安全性&#xff0c;还能够使编译器生成更加高效的代码。 noexcept 是函数接口的一部分 函数是否声明为 noexcept 是接口设计的一部分&#xff0c;客户端代码可能会依赖这一点。如果一个函数被声明…...

cudatoolkit安装(nvcc -V错误版本解决)

CudaToolKit安装&#xff08;nvcc&#xff09; cudatoolkit 是 CUDA 开发工具包&#xff08;CUDA Toolkit&#xff09; 的核心部分&#xff0c;包含了一系列用于开发和运行 CUDA 应用程序的软件组件。nvcc 是 NVIDIA CUDA 编译器驱动&#xff0c;用于将 CUDA C/C 代码编译成可…...

DTO和VO的区别及使用场景详解

随着互联网的发展&#xff0c;前后端分离的开发模式越来越流行。在前后端数据交互过程中&#xff0c;为了保证数据的安全性和效率&#xff0c;通常会采用 DTO 和 VO 来封装数据。本篇博客将详细介绍 DTO 和 VO 的区别以及使用场景。 大家可能会有个疑问&#xff0c;既然DTO是展…...

百度在下一盘大棋

这两天世界互联网大会在乌镇又召开了。 我看到一条新闻&#xff0c;今年世界互联网大会乌镇峰会发布“2024 年度中国互联网企业创新发展十大典型案例”&#xff0c;百度文心智能体平台入选。 这个智能体平台我最近也有所关注&#xff0c;接下来我就来讲讲它。 百度在下一盘大棋…...

第十六届蓝桥杯模拟赛第二期题解—Java

第十六届蓝桥杯模拟赛/校赛第二期个人题解&#xff0c;有错误的地方欢迎各位大佬指正 问题一(填空题) 【问题描述】 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问&#xff0c; 2024 的最大的质因数是多少&#xff1f; …...

驱动开发笔记:关于3588GPIO

1.概要 2.内容 1.3588GPIO 关于RK3588的GPIO&#xff08;General-Purpose Input/Output&#xff0c;通用输入输出引脚&#xff09;&#xff0c;以下是一些关键信息和操作指南&#xff1a; 一、GPIO基本概念 定义&#xff1a;GPIO是嵌入式系统中常见的通信接口&#xff0c;…...

【RK3588 Linux 5.x 内核编程】-内核线程与Mutex

内核线程与Mutex 文章目录 内核线程与Mutex1、Mutex介绍1.1 竞争条件1.2 Mutex特性2、Linux内核中的Mutex2.1 初始化Mutex2.1.1 静态方式初始化2.1.2 动态方式初始化2.2 互斥锁获取2.3 互斥锁释放3、Mutex使用示例4、驱动验证在前面的文章中,介绍了如何Linux内核中的线程,但是…...

【0342】分配并初始化 Proc Signal 共享内存 (1)

1. Proc Signal (procsignal)共享内存 Postgres内核在启动postmaster守护进程时候, 会通过函数 ProcSignalShmemInit() 去为 Proc Signal 分配并初始化指定大小的共享内存空间。整个调用链路如下。 (gdb) bt #0 ProcSignalShmemInit () at procsignal.c:118 #1 0x000000000…...

管家婆财贸ERP BR035.回款利润明细表

最低适用版本: 财贸系列 23.5 插件简要功能说明: 报表统计销售单/销售退货单/销售发票回款情况更多细节描述见下方详细文档插件操作视频: 进销存类定制插件--回款利润明细表 插件详细功能文档: 1. 应用中心增加报表【回款利润明细表】 a. b. 查询条件: ⅰ. 日期区间:…...

数据库MYSQL——表的设计

文章目录 前言三大范式&#xff1a;几种实体间的关系&#xff1a;一对一关系&#xff1a;一对多关系&#xff1a;多对多关系&#xff1a; 前言 之前的博客中我们讲解的是关于数据库的增删改查与约束的基本操作&#xff0c; 是在已经创建数据库&#xff0c;表之上的操作。 在实…...

netstat -tuln | grep 27017(显示所有监听状态的 TCP 和 UDP 端口,并且以数字形式显示地址和端口号)

文章目录 1. 确定占用端口的进程使用 lsof 命令使用 fuser 命令 2. 结束占用端口的进程3. 修改 MongoDB 配置文件4. 检查 MongoDB 日志文件5. 重新启动 MongoDB 服务6. 检查 MongoDB 服务状态总结 [rootlocalhost etc]# netstat -tuln | grep 27017 tcp 0 0 127.0.…...

非线性控制器设计原理

非线性控制器设计原理 非线性控制器设计旨在解决非线性系统的控制问题&#xff0c;克服传统线性控制器在处理非线性现象&#xff08;如饱和、死区、耦合、时变性等&#xff09;时的不足。其核心在于利用非线性数学工具和设计方法&#xff0c;使控制系统在非线性条件下具备良好…...

MySQL数据库6——SQL优化

一.SQL优化 1.插入优化 优化1&#xff1a;批量插入 insert into 表名 values(记录1),(记录2),……;优化2&#xff1a;手动提交事务 start transaction; insert into 表名 values(记录1),(记录2); insert into 表名 values(记录1),(记录2); …… commit;优化3&#xff1a;主键顺…...

IDEA配置本地maven

因为idea和maven是没有直接关系的。所以使用idea创建maven工程之前需要将本地的maven配置到idea环境中&#xff0c;这样才可以在idea中创建maven工程。配置方法如下&#xff1a; 1.1 配置本地maven 第一步&#xff1a;关闭当前工程&#xff0c;回到idea主界面找到customize--…...

学习日记_20241123_聚类方法(高斯混合模型)续

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…...

SpringMVC——简介及入门

SpringMVC简介 看到SpringMVC这个名字&#xff0c;我们会发现其中包含Spring&#xff0c;那么SpringMVC和Spring之间有怎样的关系呢&#xff1f; SpringMVC隶属于Spring&#xff0c;是Spring技术中的一部分。 那么SpringMVC是用来做什么的呢&#xff1f; 回想web阶段&#x…...