Qt 实现自定义截图工具
目录
- Qt 实现自定义截图工具
- 实现效果图
- PrintScreen 类介绍
- PrintScreen 类的主要特性
- 逐步实现
- 第一步:类定义
- 第二步:初始化截图窗口
- 第三步:处理鼠标事件
- 第四步:计算截图区域
- 第五步:捕获和保存图像
- 完整代码
- PrintScreen.h
- PrintScreen.cpp
- MainWindow.h
- MainWindow.cpp
- main.cpp
Qt 实现自定义截图工具
本文使用Qt框架从头开始创建一个简单的屏幕截图工具。
实现效果图
截图按钮:

选取截图初始状态:

选取截图区域:

截图保存界面:

PrintScreen 类介绍
PrintScreen 类是一个自定义的 QWidget,允许用户捕捉屏幕上的任意区域。本教程将展示如何利用 Qt 的多功能库来实现这一功能。
PrintScreen 类的主要特性
- 全屏覆盖,用于选择要捕捉的屏幕区域。
- 通过鼠标互动选择定义捕捉区域。
- 拖放调整选定区域。
- 将捕获的区域保存为图片文件。
逐步实现
第一步:类定义
首先定义继承自 QWidget 的 PrintScreen 类。包含必要的 Qt 头文件,并声明我们的函数和成员变量。
#include <QWidget>
#include <QPainter>/*** @brief The PrintScreen class* @param 区域截屏功能*/
class PrintScreen : public QWidget
{Q_OBJECT
public:PrintScreen(QWidget *parent = nullptr);~PrintScreen();private:/*** @brief 初始化截图窗口的背景和尺寸*/void InitWindow();/*** @brief 根据起始点和终止点计算矩形区域* @param beginPoint 矩形区域的起始点* @param endPoint 矩形区域的终止点* @return 返回根据两点计算出的 QRect 对象*/QRect GetRect(const QPoint &beginPoint, const QPoint &endPoint);protected:// 事件处理方法void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent* event);void mouseReleaseEvent(QMouseEvent *event);void keyPressEvent(QKeyEvent *event);void paintEvent(QPaintEvent *event);private:// 成员变量bool m_isMousePress = false; // 是否按下鼠标bool m_captureComplete = false; // 截图是否完成bool m_isDragging = false; // 是否正在拖动截图区域QPixmap m_loadPixmap; // 加载的屏幕截图QPixmap m_capturePixmap; // 截取的屏幕区域int m_screenWidth; // 屏幕宽度int m_screenHeight; // 屏幕高度QPoint m_beginPoint; // 截图开始点QPoint m_endPoint; // 截图结束点QPoint m_originalBegin; // 原始截图开始点QPoint m_originalEnd; // 原始截图结束点QPoint m_dragPosition; // 拖动时的鼠标位置QPainter m_painter; // 绘图器对象
};
第二步:初始化截图窗口
InitWindow 方法设置窗口属性,如全屏模式、无边框窗口提示和鼠标跟踪。它还捕获整个屏幕并存储在 m_loadPixmap 中。
void PrintScreen::InitWindow()
{// 启用鼠标跟踪this->setMouseTracking(true);// 设置无边框窗口this->setWindowFlags(Qt::FramelessWindowHint);// 设置窗口为激活状态和全屏模式setWindowState(Qt::WindowActive | Qt::WindowFullScreen);// 确保关闭时自动删除setAttribute(Qt::WA_DeleteOnClose);// 获取主屏幕QScreen *screen = QApplication::primaryScreen();// 抓取整个屏幕内容m_loadPixmap = screen->grabWindow(QApplication::desktop()->winId());// 设置屏幕宽度、高度m_screenWidth = m_loadPixmap.width();m_screenHeight = m_loadPixmap.height();
}
第三步:处理鼠标事件
鼠标事件对于定义捕获区域至关重要。mousePressEvent、mouseMoveEvent 和 mouseReleaseEvent 处理捕获区域的开始、调整和最终确定。
void PrintScreen::mousePressEvent(QMouseEvent *event)
{// 按下右键 关闭截图窗口if (event->button() == Qt::RightButton){close();}// 按下左键else if (event->button() == Qt::LeftButton){if (m_captureComplete && QRect(m_beginPoint, m_endPoint).contains(event->pos())){m_isDragging = true; // 开始拖动m_dragPosition = event->pos() - m_beginPoint; // 计算开始拖动位置}else{m_isMousePress = true; // 鼠标被按下m_isDragging = false;m_beginPoint = event->pos(); // 记录开始点m_originalBegin = m_beginPoint;}}
}void PrintScreen::mouseMoveEvent(QMouseEvent *event)
{// 鼠标按下且截图未完成if (m_isMousePress && !m_captureComplete){m_endPoint = event->pos(); // 更新结束点}// 正在拖动else if (m_isDragging){QPoint newTopLeft = event->pos() - m_dragPosition;QPoint offset = newTopLeft - m_beginPoint;m_beginPoint += offset;m_endPoint += offset;}update();
}void PrintScreen::mouseReleaseEvent(QMouseEvent *event)
{// 鼠标释放且截图未完成if (m_isMousePress && !m_captureComplete){m_endPoint = event->pos(); // 设置结束点m_isMousePress = false; // 重置鼠标按下状态m_captureComplete = true; // 标记截图完成update();}// 释放时正在拖动else if (m_isDragging){m_isDragging = false;}update();
}
第四步:计算截图区域
GetRect 方法接收两个参数:beginPoint 和 endPoint,这两个点是用户通过鼠标操作定义的截图区域的开始和结束位置。此方法用于计算并返回一个 QRect 对象,该对象表示屏幕上要截取的矩形区域。
QRect PrintScreen::GetRect(const QPoint &beginPoint, const QPoint &endPoint)
{int x = std::min(beginPoint.x(), endPoint.x());int y = std::min(beginPoint.y(), endPoint.y());int width = std::abs(beginPoint.x() - endPoint.x());int height = std::abs(beginPoint.y() - endPoint.y());if (width == 0) width = 1; // 确保宽度至少为1像素if (height == 0) height = 1; // 确保高度至少为1像素return QRect(x, y, width, height);
}
解释:
- 计算 x 和 y 坐标:使用
std::min函数确定矩形的左上角 x 和 y 坐标,这保证了无论用户如何拖动鼠标(从左到右或从右到左),都能正确计算出矩形的位置。 - 计算宽度和高度:使用
std::abs函数计算宽度和高度,确保值总是正数。如果计算结果为0(即起点和终点在同一直线上),则将宽度或高度设为1像素,确保矩形至少有最小的可见尺寸。
第五步:捕获和保存图像
paintEvent 方法在屏幕上绘制捕获的区域。keyPressEvent 监听回车键以触发保存捕获的图像。
void PrintScreen::paintEvent(QPaintEvent *event)
{Q_UNUSED(event)m_painter.begin(this); // 开始绘制QColor shadowColor(0, 0, 0, 100); // 半透明遮罩颜色m_painter.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap)); // 设置画笔m_painter.drawPixmap(0, 0, m_loadPixmap); // 绘制加载的屏幕截图m_painter.fillRect(m_loadPixmap.rect(), shadowColor); // 绘制半透明遮罩QRect selectedRect = GetRect(m_beginPoint, m_endPoint); // 获取选择区域m_capturePixmap = m_loadPixmap.copy(selectedRect); // 截取选择区域的屏幕截图m_painter.drawPixmap(selectedRect.topLeft(), m_capturePixmap); // 绘制截取的区域m_painter.drawRect(selectedRect); // 绘制选择区域的边框m_painter.end(); // 结束绘制
}
void PrintScreen::keyPressEvent(QKeyEvent *event)
{// 按下回车键if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return){// 保存图片QString filePath = QFileDialog::getSaveFileName(nullptr, "保存图片",QString(),"Images (*.png *.jpg)");if(!filePath.isEmpty()){m_capturePixmap.save(filePath); // 保存截图到文件}close();}
}
完整代码
PrintScreen.h
#ifndef PRINTSCREEN_H
#define PRINTSCREEN_H#include <QWidget>
#include <QPainter>/*** @brief The PrintScreen class* @param 区域截屏功能*/
class PrintScreen : public QWidget
{Q_OBJECT
public:PrintScreen(QWidget *parent = nullptr);~PrintScreen();private:/*** @brief 初始化截图窗口的背景和尺寸*/void InitWindow();/*** @brief 根据起始点和终止点计算矩形区域* @param beginPoint 矩形区域的起始点* @param endPoint 矩形区域的终止点* @return 返回根据两点计算出的 QRect 对象*/QRect GetRect(const QPoint &beginPoint, const QPoint &endPoint);protected:// 事件处理方法void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent* event);void mouseReleaseEvent(QMouseEvent *event);void keyPressEvent(QKeyEvent *event);void paintEvent(QPaintEvent *event);private:// 成员变量bool m_isMousePress = false; // 是否按下鼠标bool m_captureComplete = false; // 截图是否完成bool m_isDragging = false; // 是否正在拖动截图区域QPixmap m_loadPixmap; // 加载的屏幕截图QPixmap m_capturePixmap; // 截取的屏幕区域int m_screenWidth; // 屏幕宽度int m_screenHeight; // 屏幕高度QPoint m_beginPoint; // 截图开始点QPoint m_endPoint; // 截图结束点QPoint m_originalBegin; // 原始截图开始点QPoint m_originalEnd; // 原始截图结束点QPoint m_dragPosition; // 拖动时的鼠标位置QPainter m_painter; // 绘图器对象
};#endif // PRINTSCREEN_H
PrintScreen.cpp
#include "PrintScreen.h"#include <QScreen>
#include <QFileDialog>
#include <QMouseEvent>
#include <QApplication>
#include <QDesktopWidget>PrintScreen::PrintScreen(QWidget *parent): QWidget{parent}
{InitWindow();
}PrintScreen::~PrintScreen(){}void PrintScreen::InitWindow()
{// 启用鼠标跟踪this->setMouseTracking(true);// 设置无边框窗口this->setWindowFlags(Qt::FramelessWindowHint);// 设置窗口为激活状态和全屏模式setWindowState(Qt::WindowActive | Qt::WindowFullScreen);// 确保关闭时自动删除setAttribute(Qt::WA_DeleteOnClose);// 获取主屏幕QScreen *screen = QApplication::primaryScreen();// 抓取整个屏幕内容m_loadPixmap = screen->grabWindow(QApplication::desktop()->winId());// 设置屏幕宽度、高度m_screenWidth = m_loadPixmap.width();m_screenHeight = m_loadPixmap.height();
}QRect PrintScreen::GetRect(const QPoint &beginPoint, const QPoint &endPoint)
{int x = std::min(beginPoint.x(), endPoint.x());int y = std::min(beginPoint.y(), endPoint.y());int width = std::abs(beginPoint.x() - endPoint.x());int height = std::abs(beginPoint.y() - endPoint.y());if (width == 0) width = 1; // 确保宽度至少为1像素if (height == 0) height = 1; // 确保高度至少为1像素return QRect(x, y, width, height);
}void PrintScreen::mousePressEvent(QMouseEvent *event)
{// 按下右键 关闭截图窗口if (event->button() == Qt::RightButton){close();}// 按下左键else if (event->button() == Qt::LeftButton){if (m_captureComplete && QRect(m_beginPoint, m_endPoint).contains(event->pos())){m_isDragging = true; // 开始拖动m_dragPosition = event->pos() - m_beginPoint; // 计算开始拖动位置}else{m_isMousePress = true; // 鼠标被按下m_isDragging = false;m_beginPoint = event->pos(); // 记录开始点m_originalBegin = m_beginPoint;}}
}void PrintScreen::mouseMoveEvent(QMouseEvent *event)
{// 鼠标按下且截图未完成if (m_isMousePress && !m_captureComplete){m_endPoint = event->pos(); // 更新结束点}// 正在拖动else if (m_isDragging){QPoint newTopLeft = event->pos() - m_dragPosition;QPoint offset = newTopLeft - m_beginPoint;m_beginPoint += offset;m_endPoint += offset;}update();
}void PrintScreen::mouseReleaseEvent(QMouseEvent *event)
{// 鼠标释放且截图未完成if (m_isMousePress && !m_captureComplete){m_endPoint = event->pos(); // 设置结束点m_isMousePress = false; // 重置鼠标按下状态m_captureComplete = true; // 标记截图完成update();}// 释放时正在拖动else if (m_isDragging){m_isDragging = false;}update();
}void PrintScreen::keyPressEvent(QKeyEvent *event)
{// 按下回车键if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return){// 保存图片QString filePath = QFileDialog::getSaveFileName(nullptr, "保存图片",QString(),"Images (*.png *.jpg)");if(!filePath.isEmpty()){m_capturePixmap.save(filePath); // 保存截图到文件}close();}
}void PrintScreen::paintEvent(QPaintEvent *event)
{Q_UNUSED(event)m_painter.begin(this); // 开始绘制QColor shadowColor(0, 0, 0, 100); // 半透明遮罩颜色m_painter.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap)); // 设置画笔m_painter.drawPixmap(0, 0, m_loadPixmap); // 绘制加载的屏幕截图m_painter.fillRect(m_loadPixmap.rect(), shadowColor); // 绘制半透明遮罩QRect selectedRect = GetRect(m_beginPoint, m_endPoint); // 获取选择区域m_capturePixmap = m_loadPixmap.copy(selectedRect); // 截取选择区域的屏幕截图m_painter.drawPixmap(selectedRect.topLeft(), m_capturePixmap); // 绘制截取的区域m_painter.drawRect(selectedRect); // 绘制选择区域的边框m_painter.end(); // 结束绘制
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QPushButton>#include "PrintScreen.h"class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:QPushButton *m_screenBtn;PrintScreen *m_printScree;// QObject interface
public:bool eventFilter(QObject *watched, QEvent *event);
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "MainWindow.h"
#include <QLayout>
#include <QMouseEvent>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), m_screenBtn(new QPushButton("截图", this))
{// 设置中心窗口setCentralWidget(m_screenBtn);// 安装事件过滤器m_screenBtn->installEventFilter(this);// 隐藏标题栏setWindowFlags(Qt::FramelessWindowHint);resize(150, 50);
}MainWindow::~MainWindow() {}bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{if (watched == m_screenBtn && event->type() == QEvent::MouseButtonPress){QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);if (mouseEvent->button() == Qt::RightButton){close();return true;}else if (mouseEvent->button() == Qt::LeftButton){m_printScree = new PrintScreen();m_printScree->show();return true;}}return QMainWindow::eventFilter(watched, event);
}
main.cpp
#include "MainWindow.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
相关文章:
Qt 实现自定义截图工具
目录 Qt 实现自定义截图工具实现效果图PrintScreen 类介绍PrintScreen 类的主要特性 逐步实现第一步:类定义第二步:初始化截图窗口第三步:处理鼠标事件第四步:计算截图区域第五步:捕获和保存图像 完整代码PrintScreen.…...
第15-05章:获取运行时类的完整结构
我的后端学习大纲 我的Java学习大纲 6.1.第一组方法API: 1.API列表:java.lang.Class 类: 2.代码测试: public class ReflectionUtils{ puvblic static void main(String[] args){}// 第一组Testpublic void api_01{//上面截图的代码......…...
【Kubernetes】K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制
K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制 1.基于属性的访问控制(ABAC 鉴权)2.基于节点的访问控制(node 鉴权)2.1 读取操作2.2 写入操作 3.基于 Webhook 的访问控制3.1 基于 We…...
Java面试、技巧、问题、回复,资源面面观
入门 先了解一下面试流程 复习 Java 基础知识: 温习 Java 编程的核心概念,包括数据类型、变量、循环、数组和面向对象的编程原则。数据结构和算法: 加强您对 Java 编程中使用的基本数据结构和算法的理解。练习编码: 在各种平台上解…...
深入理解Elasticsearch的`_source`字段与索引优化
在Elasticsearch (ES) 中,_source字段是一个关键组件,它不仅决定了数据的存储方式,还影响到查询时返回的内容。在某些场景下,我们可以通过配置_source来优化存储和性能,尤其是当我们希望减少存储空间或避免返回某些字段…...
Pikachu靶场
先来点鸡汤,少就是多,慢就是快。 环境搭建 攻击机kali 192.168.146.140 靶机win7 192.168.146.161 下载zip,pikachu - GitCode 把下载好的pikachu-master,拖进win7,用phpstudy打开网站根目录,.....再用…...
TS axios封装
方式一 service/request/request.ts import axios from axios import { ElLoading } from element-plus import type { AxiosRequestConfig, AxiosInstance, AxiosResponse } from axios import type { ILoadingInstance } from element-plus/lib/el-loading/src/loading.typ…...
学会使用西门子博途Startdrive中的测量功能
工程师在驱动调试过程中,往往需要对驱动系统的性能进行分析及优化,比如说借助于调试软件中的驱动器测量功能,可以得到驱动系统的阶跃响应、波特图等,以此为依据工程师可以调整速度控制器、电流控制器的相关参数,使驱动…...
Spring Security认证与授权
1 Spring Security介绍 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是Spring生态系统中的一员,因此它伴随着整个Spring生态系统不断修正、升级,在spring boot项目中加入springsecurity更是…...
速通GPT:Improving Language Understanding by Generative Pre-Training全文解读
文章目录 速通GPT系列几个重要概念1、微调的具体做法2、任务感知输入变换3、判别式训练模型 Abstract概括分析和观点1. 自然语言理解中的数据问题2. 生成预训练和监督微调的结合3. 任务感知输入变换4. 模型的强大性能 Introduction概括分析和观点1. 自然语言理解的挑战在于对标…...
软件质量保证例题
答案:D 软件质量保证 功能性 适合性 准确性 互操作性 安全保密性 依从性 可靠性 成熟性 容错性 易恢复性 易用性 易理解性 易学性 易操作性 效率 时间特性 资源利用性 维护性 易分析性 易改变性 稳定性 易测试性 可移植性 适应性 易安装性 一致性 易替换…...
动态规划算法---04.斐波那契数列模型_解码方法_C++
题目链接:91. 解码方法 - 力扣(LeetCode)https://leetcode.cn/problems/decode-ways/description/ 一、题目解析 题目: 题目大意:从题目中我们可以知道,解码就是在字符串s中由‘1’到‘26’的字符可以转化…...
crm如何做私域运营?
流量获取的挑战日益增加,客户线索成本高、客户资源流失严重、转化率低,因此,私域流量管理已成为关键。 当前挑战 1、公域流量难以整合:外部流量分散,难以有效汇总和沉淀。 2、私域运营体系缺失:缺乏有效沟…...
基于QGIS 3.16.0 的OSM路网矢量范围裁剪实战-以湖南省为例
目录 前言 一、相关数据介绍 1、OMS路网数据 2、路网数据 3、路网图层属性 二、按省域范围进行路网裁剪 1、裁剪范围制定 2、空间裁剪 3、裁剪结果 三、总结 前言 改革开放特别是党的十八大以来,我国公路发展取得了举世瞩目的成就。国家高速公路网由“7 射…...
WPF 手撸插件 八 依赖注入
本文内容大量参考了:https://www.cnblogs.com/Chary/p/11351457.html 而且这篇文章总结的非常好。 1、注意想使用Autofac,Autofac是一个轻量级、高性能的依赖注入(DI)框架,主要用于.NET应用程序的组件解耦和…...
走进低代码报表开发(一):探秘报表数据源
在前文当中,我们对勤研低代码平台的流程设计功能进行了介绍。接下来,让我们一同深入了解在企业日常运营中另一个极为常见的报表功能。在当今数字化时代,高效的报表生成对于企业的决策至关重要。勤研低代码开发平台能够以卓越的性能和便捷的操…...
代理服务器及其原理
代理服务器的代理可以分为正向代理和反向代理,本篇将讲解这两种代理方式的原理,以及对应的功能特点和应用场景。最后还对比和 NAT 和代理服务器的区别。 目录 正向代理 工作原理 功能特点 应用场景 反向代理 基本原理 应用场景 NAT和代理服务器…...
计算机毕业设计选题推荐-养老院管理系统-Java/Python项目实战
✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...
免费SSL证书正在逐渐被淘汰,证书部署自动化的发展趋势即将到来!
目录 背景解决方案。1.使用自签证书(浏览器报警、免费)2.更换支持自签自续的CA机构(免费)3.付费选择CA机构 免费SSL证书正在逐渐被淘汰,证书部署自动化的发展趋势即将到来免费的SSL证书有以下弊端1.有效期短࿱…...
openVX加速-基本概念和简单代码实现
OpenVX 是一个用于计算机视觉和图像处理的跨平台加速标准库,旨在提高在异构平台(如 CPU、GPU、DSP 等)上的执行效率。OpenVX 提供了一组优化的、可移植的 API,用于加速常见的视觉算法,使开发者能够在不同硬件平台上实现…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
