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

OpenCV-PyQT项目实战(7)项目案例03:鼠标框选

欢迎关注『OpenCV-PyQT项目实战 @ Youcans』系列,持续更新中
OpenCV-PyQT项目实战(1)安装与环境配置
OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门
OpenCV-PyQT项目实战(3)信号与槽机制
OpenCV-PyQT项目实战(4)OpenCV 与PyQt的图像转换
OpenCV-PyQT项目实战(5)项目案例01:图像模糊
OpenCV-PyQT项目实战(6)项目案例02:滚动条应用
OpenCV-PyQT项目实战(7)项目案例03:鼠标框选

文章目录

  • OpenCV-PyQT项目实战(7)项目案例03:鼠标框选
    • 1. OpenCV实现鼠标框选
    • 2. PyQt实现鼠标框选
      • 2.1 支持鼠标事件的自定义 Label 类
      • 2.2 例程7-2:支持鼠标事件的自定义 MyLabel 类
    • 3. 项目实战:PyQt 鼠标框选
      • 3.1 使用 QtDesigner 开发 PyQt5 图形界面
      • 3.2. 项目主程序的开发
        • 3.2.1 实例化 MyLabel 类
        • 3.2.2 框选图像槽函数
        • 3.2.3 信号与槽的连接
      • 3.3 完整例程 OpenCVPyqt08.py


OpenCV-PyQT项目实战(7)项目案例03:鼠标框选

本节介绍OpenCV和PyQt 实现鼠标框选的方法和案例,通过案例学习PyQt中的鼠标动作。


1. OpenCV实现鼠标框选

OpenCV中的函数 cv.selectROI 可以通过鼠标在图像上选择感兴趣的矩形区域(ROI,region of interest)。

函数原型:

cv.selectROI(windowName, img[, showCrosshair=true, fromCenter=false]) → retval

函数cv.selectROI创建一个显示窗口,允许用户使用鼠标选择ROI,按Space或Enter键完成选择,按c键取消选择。

参数说明:

● img:选择矩形区域的图像

● windowName:图像显示窗口的名称

● showCrosshair:默认值true,显示选择矩形的中心十字线

● fromCenter:默认值false,表示鼠标初始位置作为矩形的角点;true表示鼠标初始位置作为矩形的中心点

● retval:返回值为Rect矩形类,格式为元组 (x , y, w, h)

注意问题:

⒈函数的返回值是Rect矩形类,元组 (x , y, w, h) 分别表示矩形左上角顶点坐标 (x,y)、矩形的宽度w和高度h。

⒉函数创建一个窗口设置自己的鼠标回调,完成后将为使用的窗口设置一个空回调。

例程7-1:OpenCV鼠标框选

    # 1.17 图像的裁剪 (ROI)img1 = cv2.imread("../images/imgLena.tif", flags=1)  # flags=1 读取彩色图像(BGR)roi = cv2.selectROI(img1, showCrosshair=True, fromCenter=False)xmin, ymin, w, h = roi  # 矩形裁剪区域 (ymin:ymin+h, xmin:xmin+w) 的位置参数imgROI = img1[ymin:ymin+h, xmin:xmin+w].copy()  # 切片获得裁剪后保留的图像区域cv2.imshow("DemoRIO", imgROI)cv2.waitKey(0)

在这里插入图片描述


总结:OpenCV实现鼠标框选非常简单,但无法与 PyQt5 的 GUI 集成,只能在 OpenCV GUI 进行简单的操作。



2. PyQt实现鼠标框选

PyQt 中实现鼠标框选,本质上是鼠标动作的响应。

2.1 支持鼠标事件的自定义 Label 类

基本的 QLabel 类并不支持鼠标动作,因此需要自定义一个支持鼠标动作的 Label 类。

PyQt中,每个事件类型都被封装成相应的事件类,如鼠标事件为QMouseEvent,键盘事件为QKeyEvent等。而它们的基类是QEvent。

QMouseEvent 鼠标事件:

mousePressEvent (self, event):鼠标按下事件
mouseReleaseEvent (self, event):鼠标释放事件
mouseDoubieCiickEvent (self, event):双击鼠标事件
mouseMoveEvent(self,event):鼠标移动事件
enterEvent (self, event):鼠标进入控件事件
leaveEvent (self, event):鼠标离开控件事件
wheelEvent (self, event):滚轮滚动事件

QMouseEvent 鼠标方法:

ignore():让父控件继续收到鼠标事件
accept():不让父控件继续收到鼠标事件
x()、y():返回相对于控件空间的鼠标坐标值
pos():返回相对于控件空间的QPoint对象
localPos():返回相对于控件空间的QPointF对象
globalX()、globalY():返回相对于屏幕的x,y 坐标值
globalPos():返回相对于屏幕的QPoint对象
windowPos():返回相对于窗口的QPointF对象
screenPos():返回相对于屏幕的QPointF对象
timestamp():返回事件发生的时间;

QMouseEvent 鼠标事件的具体内容:
按下并释放鼠标按钮时,将调用以下方法:

mousePressEvent (self, event) - 鼠标键按下时调用;
mouseReleaseEvent (self, event) - 鼠标键公开时调用;
mouseDoubieCiickEvent (self, event) - 双击鼠标时调用。必须注意,在双击之前的其他事件。双击时的事件顺序如下:

- MouseButtonPress
- MouseButtonRelease
- MouseButtonDblClick
- MouseButtonPress
- MouseButtonRelease

2.2 例程7-2:支持鼠标事件的自定义 MyLabel 类

class MyLabel(QLabel):def __init__(self,parent=None):super(MyLabel, self).__init__(parent)self.x0 = 0self.y0 = 0self.x1 = 1self.y1 = 1self.flag = False# 鼠标点击事件def mousePressEvent(self, event):self.flag = True  # 鼠标点击状态self.x0 = event.x()self.y0 = event.y()# 鼠标释放事件def mouseReleaseEvent(self, event):self.flag = False  # 鼠标释放状态self.x1 = event.x()self.y1 = event.y()# 鼠标移动事件def mouseMoveEvent(self, event):if self.flag:self.x1 = event.x()self.y1 = event.y()self.update()# 绘制事件def paintEvent(self, event):super().paintEvent(event)rect = QRect(self.x0, self.y0, abs(self.x1 - self.x0), abs(self.y1 - self.y0))painter = QPainter(self)painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))painter.drawRect(rect)


3. 项目实战:PyQt 鼠标框选

本项目基于 PyQt5 GUI,使用鼠标框选 ROI 区域,在窗口中显示 ROI 区域,并对 ROI 进行处理。



3.1 使用 QtDesigner 开发 PyQt5 图形界面

本例的 UI 集自 uiDemo4.ui :


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SzG6cP8y-1676360319630)(D:\OpenCVPyQt\images\OpenCV_20.png)]

于是,我们就完成了本项目的图形界面设计,将其保存为 uiDemo7.ui文件。

在 PyCharm中,使用 PyUIC 将选中的 uiDemo7.ui 文件转换为 .py 文件,就得到了 uiDemo7.py 文件。



3.2. 项目主程序的开发

3.2.1 实例化 MyLabel 类

自定义的 MyLabel 类不能在 QtDesigner 中创建,要在主程序中定义如下。

        self.label_1 = MyLabel(self.centralwidget)self.label_1.setGeometry(QRect(20, 20, 400, 320))self.label_1.setAlignment(Qt.AlignCenter)self.label_1.setObjectName("label_1")

3.2.2 框选图像槽函数

click_pushButton槽函数,由 pushButton_3.clicked 按钮信号触发。

    def click_pushButton_3(self):  # 点击 pushButton_3 触发 框选图像print("pushButton_3")self.label_1.setGeometry(QRect(20, 20, 400, 320))hImg, wImg = self.img1.shape[:2]wLabel = self.label_1.width()hLabel = self.label_1.height()x0 = self.label_1.x0 * wImg//wLabely0 = self.label_1.y0 * hImg//hLabelx1 = self.label_1.x1 * wImg//wLabely1 = self.label_1.y1 * hImg//hLabelprint("hImg,wImg=({},{}), x1,y1=({},{})".format(hImg, wImg, hLabel, wLabel))print("x0,y0=({},{}), x1,y1=({},{})".format(x0, y0, x1, y1))self.img2 = np.zeros((self.img1.shape), np.uint8)self.img2[y0:y1, x0:x1, :] = self.img1[y0:y1, x0:x1, :]self.refreshShow(self.img2, self.label_2)  # 刷新显示return

3.2.3 信号与槽的连接

        # 通过 connect 建立信号/槽连接,点击按钮事件发射 triggered 信号,执行相应的子程序 click_pushButtonself.pushButton_1.clicked.connect(self.click_pushButton_1)  # 按钮触发:导入图像self.pushButton_2.clicked.connect(self.click_pushButton_2)  # # 按钮触发:灰度显示self.pushButton_3.clicked.connect(self.click_pushButton_3)  # # 按钮触发:框选图像self.pushButton_4.clicked.connect(self.trigger_actHelp)  # # 按钮触发:调整色阶self.pushButton_5.clicked.connect(self.close)  # 点击 # 按钮触发:关闭

3.3 完整例程 OpenCVPyqt08.py

# OpenCVPyqt08.py
# Demo07 of GUI by PyQt5
# Copyright 2023 Youcans, XUPT
# Crated:2023-02-12import sys
import cv2 as cv
import numpy as np
from PyQt5.QtCore import QObject, pyqtSignal, QPoint, QRect, qDebug, Qt
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from uiDemo8 import Ui_MainWindow  # 导入 uiDemo8.py 中的 Ui_MainWindow 界面类class MyLabel(QLabel):def __init__(self,parent=None):super(MyLabel, self).__init__(parent)self.x0 = 0self.y0 = 0self.x1 = 1self.y1 = 1self.flag = False# 鼠标点击事件def mousePressEvent(self, event):self.flag = True  # 鼠标点击状态self.x0 = event.x()self.y0 = event.y()# 鼠标释放事件def mouseReleaseEvent(self, event):self.flag = False  # 鼠标释放状态self.x1 = event.x()self.y1 = event.y()# 鼠标移动事件def mouseMoveEvent(self, event):if self.flag:self.x1 = event.x()self.y1 = event.y()self.update()# 绘制事件def paintEvent(self, event):super().paintEvent(event)rect = QRect(self.x0, self.y0, abs(self.x1 - self.x0), abs(self.y1 - self.y0))painter = QPainter(self)painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))painter.drawRect(rect)class MyMainWindow(QMainWindow, Ui_MainWindow):  # 继承 QMainWindow 类和 Ui_MainWindow 界面类def __init__(self, parent=None):super(MyMainWindow, self).__init__(parent)  # 初始化父类self.setupUi(self)  # 继承 Ui_MainWindow 界面类self.label_1 = MyLabel(self.centralwidget)self.label_1.setGeometry(QRect(20, 20, 400, 320))self.label_1.setAlignment(Qt.AlignCenter)self.label_1.setObjectName("label_1")# 菜单栏self.actionOpen.triggered.connect(self.openSlot)  # 连接并执行 openSlot 子程序self.actionSave.triggered.connect(self.saveSlot)  # 连接并执行 saveSlot 子程序self.actionHelp.triggered.connect(self.trigger_actHelp)  # 连接并执行 trigger_actHelp 子程序self.actionQuit.triggered.connect(self.close)  # 连接并执行 trigger_actHelp 子程序# 通过 connect 建立信号/槽连接,点击按钮事件发射 triggered 信号,执行相应的子程序 click_pushButtonself.pushButton_1.clicked.connect(self.click_pushButton_1)  # 按钮触发:导入图像self.pushButton_2.clicked.connect(self.click_pushButton_2)  # # 按钮触发:灰度显示self.pushButton_3.clicked.connect(self.click_pushButton_3)  # # 按钮触发:框选图像self.pushButton_4.clicked.connect(self.trigger_actHelp)  # # 按钮触发:调整色阶self.pushButton_5.clicked.connect(self.close)  # 点击 # 按钮触发:关闭# 初始化self.img1 = np.ndarray(())  # 初始化图像 ndarry,用于存储图像self.img2 = np.ndarray(())  # 初始化图像 ndarry,用于存储图像self.img1 = cv.imread("../images/Lena.tif")  # OpenCV 读取图像self.refreshShow(self.img1, self.label_1)# self.refreshShow(self.img1, self.label_2)returndef click_pushButton_1(self):  # 点击 pushButton_1 触发self.img1 = self.openSlot()  # 读取图像self.img2 = self.img1.copy()print("click_pushButton_1", self.img1.shape)self.refreshShow(self.img1, self.label_1)  # 刷新显示returndef click_pushButton_2(self):  # 点击 pushButton_2 触发print("pushButton_2")self.img2 = cv.cvtColor(self.img2, cv.COLOR_BGR2GRAY)  # 图片格式转换:BGR -> Grayself.refreshShow(self.img2, self.label_2)  # 刷新显示returndef click_pushButton_3(self):  # 点击 pushButton_3 触发 框选图像print("pushButton_3")self.label_1.setGeometry(QRect(20, 20, 400, 320))hImg, wImg = self.img1.shape[:2]wLabel = self.label_1.width()hLabel = self.label_1.height()x0 = self.label_1.x0 * wImg//wLabely0 = self.label_1.y0 * hImg//hLabelx1 = self.label_1.x1 * wImg//wLabely1 = self.label_1.y1 * hImg//hLabelprint("hImg,wImg=({},{}), x1,y1=({},{})".format(hImg, wImg, hLabel, wLabel))print("x0,y0=({},{}), x1,y1=({},{})".format(x0, y0, x1, y1))self.img2 = np.zeros((self.img1.shape), np.uint8)self.img2[y0:y1, x0:x1, :] = self.img1[y0:y1, x0:x1, :]print(self.img2.shape)# cv.imshow("Demo", self.img2)# key = cv.waitKey(0)  # 等待下一个按键命令# self.gRightLayout.removeWidget(self.label_2)  # 删除原有 labelCover 控件及显示图表# sip.delete(self.labelCover)  # 删除控件 labelCover# self.img2 = np.zeros(self.img1.shape, np.int8)self.refreshShow(self.img2, self.label_2)  # 刷新显示returndef refreshShow(self, img, label):print(img.shape, label)qImg = self.cvToQImage(img)  # OpenCV 转为 PyQt 图像格式# label.setScaledContents(False)  # 需要在图片显示之前进行设置label.setPixmap((QPixmap.fromImage(qImg)))  # 加载 PyQt 图像returndef openSlot(self, flag=1):  # 读取图像文件# OpenCV 读取图像文件fileName, _ = QFileDialog.getOpenFileName(self, "Open Image", "../images/", "*.png *.jpg *.tif")if flag==0 or flag=="gray":img = cv.imread(fileName, cv.IMREAD_GRAYSCALE)  # 读取灰度图像else:img = cv.imread(fileName, cv.IMREAD_COLOR)  # 读取彩色图像print(fileName, img.shape)return imgdef saveSlot(self):  # 保存图像文件# 选择存储文件 dialogfileName, tmp = QFileDialog.getSaveFileName(self, "Save Image", "../images/", '*.png; *.jpg; *.tif')if self.img1.size == 1:return# OpenCV 写入图像文件ret = cv.imwrite(fileName, self.img1)if ret:print(fileName, self.img.shape)returndef cvToQImage(self, image):# 8-bits unsigned, NO. OF CHANNELS=1if image.dtype == np.uint8:channels = 1 if len(image.shape) == 2 else image.shape[2]if channels == 3:  # CV_8UC3# Create QImage with same dimensions as input MatqImg = QImage(image, image.shape[1], image.shape[0], image.strides[0], QImage.Format_RGB888)return qImg.rgbSwapped()elif channels == 1:# Create QImage with same dimensions as input MatqImg = QImage(image, image.shape[1], image.shape[0], image.strides[0], QImage.Format_Indexed8)return qImgelse:qDebug("ERROR: numpy.ndarray could not be converted to QImage. Channels = %d" % image.shape[2])return QImage()def qPixmapToCV(self, qPixmap):  # PyQt图像 转换为 OpenCV图像qImg = qPixmap.toImage()  # QPixmap 转换为 QImageshape = (qImg.height(), qImg.bytesPerLine() * 8 // qImg.depth())shape += (4,)ptr = qImg.bits()ptr.setsize(qImg.byteCount())image = np.array(ptr, dtype=np.uint8).reshape(shape)  # 定义 OpenCV 图像image = image[..., :3]return imagedef trigger_actHelp(self):  # 动作 actHelp 触发QMessageBox.about(self, "About","""数字图像处理工具箱 v1.0\nCopyright YouCans, XUPT 2023""")returnif __name__ == '__main__':app = QApplication(sys.argv)  # 在 QApplication 方法中使用,创建应用程序对象myWin = MyMainWindow()  # 实例化 MyMainWindow 类,创建主窗口myWin.show()  # 在桌面显示控件 myWinsys.exit(app.exec_())  # 结束进程,退出程序

运行结果:

在这里插入图片描述


在这里插入图片描述


【本节完】


版权声明:

Copyright 2023 youcans, XUPT

Crated:2023-2-14


相关文章:

OpenCV-PyQT项目实战(7)项目案例03:鼠标框选

欢迎关注『OpenCV-PyQT项目实战 Youcans』系列,持续更新中 OpenCV-PyQT项目实战(1)安装与环境配置 OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战(3)信号与槽机制 …...

vue2版本《后台管理模式》(上)

后台管理模式项目开发经验总结如下,希望对你们有些帮助: 文章目录一、app 出口位置二 、 index.js 路由配置三、package.json 文件四、 main.js 既然安装插件那就需要引入五、 跨域问题总结首先需要一个完整的v2版本的项目 vue2版本思路:首先…...

C++与C基础重叠部分

Cmake CPP程序开发过程 计算机硬件—>机器语言—>汇编—>cppcpp—>机器(gcc)Make(makefile)—>本地智能批处理翻译机制Cmake—>跨平台生成不同设备上的makefile进行执行 Cpp基础学习 基本知识 基本格式 #include<iostream> using namespace std;…...

神经网络基础部件-卷积层详解

前言 在全连接层构成的多层感知机网络中&#xff0c;我们要通过将图像数据展平成一维向量来送入模型&#xff0c;但这会忽略了每个图像的空间结构信息。理想的策略应该是要利用相近像素之间的相互关联性&#xff0c;将图像数据二维矩阵送给模型中学习。 卷积神经网络(convolu…...

【计算机网络】HTTPS协议原理

文章目录一、认识HTTPS协议二、为什么要发明HTTPS三、HTTP与HTTPS的区别四、常见的加密方式1. 对称加密2. 非对称加密3. 数据摘要4. 数字签名五、HTTPS的原理探究方案1&#xff1a;只使用对称加密方案2&#xff1a;只使用非对称加密方案3&#xff1a;双方都使用非对称加密方案4…...

21岁,华科博士在读,我的赛事Top经验

Datawhale干货 作者&#xff1a;vaew&#xff0c;华中科技大学&#xff0c;博士二年级在读简介笔者vaew&#xff0c;21岁&#xff0c;现为华中科技大学机械科学与工程学院陶波教授课题组博士二年级学生。主要研究方向是基于视触融合的机器人灵巧操作。学业之余的研究兴趣包括图…...

基于ThinkPHP6.0+Vue+uni-app的多商户商城系统好用吗?

likeshop多商户商城系统适用于B2B2C、多商户、商家入驻、平台商城场景。完美契合平台自营联营加盟等多种经营方式使用&#xff0c;系统拥有丰富的营销玩法&#xff0c;强大的分销能力&#xff0c;支持官方旗舰店&#xff0c;商家入驻&#xff0c;平台抽佣商家独立结算&#xff…...

Linux中断

文章目录 前言一、Linux 中断介绍二、中断上文和中断下文三、中断相关函数1 获取中断号相关函数2.申请中断3.释放中断4.中断处理函数四.中断下文之 tasklet1.概念2.Linux 内核中的 tasklet 结构体:3.使用步骤4.相关函数a.初始化 tasklet结构体b.调度 taskletc.杀死 tasklet总结…...

Excel+SQL实战项目 - 餐饮业日销售情况分析仪

目录1、要完成的任务2、认识数据3、SQL数据加工4、excel形成分析仪1、要完成的任务 目标&#xff1a;结合SQL和excel实现餐饮业日销售情况分析仪&#xff0c;如下表&#xff1a; 认识分析仪&#xff1a; 切片器&#xff1a;店面 分为四部分&#xff1a;KPI 、组合图、饼图、数…...

电商导购CPS,京东联盟如何跟单实现用户和订单绑定

前言 大家好&#xff0c;我是小悟 做过自媒体的小伙伴都知道&#xff0c;不管是发图文还是发短视频&#xff0c;直播也好&#xff0c;可以带货。在你的内容里面挂上商品&#xff0c;你自己都不需要囤货&#xff0c;如果用户通过这个商品下单成交了&#xff0c;自媒体平台就会…...

Redis学习【6】之BitMap、HyperLogLog、Geospatial操作命令 (1)

文章目录前言BitMap 操作命令1.1 BitMap 简介1.2 setbit1.3 getbit1.4 bitcount1.5 bitpos[pos:position]1.6 bitop1.7 应用场景二 HyperLogLog 操作命令2.1 HyperLogLog 简介2.2 pfadd2.3 pfcount2.4 pfmerge2.5 应用场景三 Geospatial【地理空间】操作命令3. 1 Geospatial 简…...

JAVA实现心跳检测【长连接】

文章目录1、心跳机制简介2、心跳机制实现方式3、客户端4 、服务端5、代码实现5.1 KeepAlive.java5.2 MyClient.java5.3 MyServer5.4 测试结果1、心跳机制简介 在分布式系统中&#xff0c;分布在不同主机上的节点需要检测其他节点的状态&#xff0c;如服务器节点需要检测从节点…...

python3.9安装和pandas安装踩坑处理

0、先决条件&#xff1a;系统内最好先安装有gcc、libffi-devel等 1、安装包下载 https://www.python.org/downloads/source/ 2、解压安装包并上传到/usr/local/python3.9 3、打开shell cd /usr/local/python3.9要先把python3.9的所有文件复制到/usr/local/python3.9才会成功…...

2023.2.15每日一题——867. 转置矩阵

每日一题题目描述解题核心解法一&#xff1a;二维表示 模拟解法二&#xff1a;一维表示 模拟题目描述 题目链接&#xff1a;867. 转置矩阵 给你一个二维整数数组 matrix&#xff0c; 返回 matrix 的 转置矩阵 。 矩阵的 转置 是指将矩阵的主对角线翻转&#xff0c;交换矩阵…...

【人脸识别】Partial-FC:让你在一台机器上训练1000万个id人脸数据集成为可能!

论文题目&#xff1a;”Killing Two Birds with One Stone: Efficient and Robust Training of Face Recognition CNNs by Partial FC“ -CVPR 2022 代码地址&#xff1a;https://arxiv.org/pdf/2203.15565.pdf 代码地址&#xff1a;https://github.com/deepinsight/insightfac…...

递归方法读取任意深度的 JSON 对象的键值

有以下json字符串 {"name":"John","age":30,"address":{"city":"New York","state":"NY","zip":"10001","coordinates":{"latitude":40.712776,&q…...

黑马redis学习记录:分布式锁

一、基本原理和实现方式对比 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁&#xff0c;只要大家使用的是同一把锁&#xff0c;那么我们就能锁住线程&#xff0c;不让线程进行&#xff0c;让程序串行…...

对React-Fiber的理解,它解决了什么问题?

对React-Fiber的理解&#xff0c;它解决了什么问题&#xff1f;Fiber用来解决什么问题&#xff1f;Fiber是什么&#xff1f;Fiber是如何解决问题的&#xff1f;Fiber用来解决什么问题&#xff1f; JavaScript引擎和页面渲染引擎两个线程是互斥的&#xff0c;当其中一个线程执行…...

【Linux】初学Linux你需要掌握这些基本指令(二)

目录 1.man指令 2.cp指令 3.mv指令 4.tree指令 5.echo指令 6.more指令 7.less指令&#xff08;重要&#xff09; 8.head与tail指令 9.date指令 显示时间常用参数&#xff1a; 设置时间常用参数&#xff1a; 10.cal指令 11.find & whereis & which指令 …...

Linux中VI/VIM 编辑器

1、概述所有Linux系统都会内置vi文本编辑器vim是vi的升级版&#xff0c;可以主动以字体颜色分辨语法的正确性&#xff0c;代码补完和编译&#xff0c;错误跳转等功能。2、vi和vim的三种模式基本上 vi/vim 共分为三种模式&#xff0c;分别是一般模式、编辑模式、命令模式2.1、一…...

PDF怎么转换成Word?两种PDF免费转Word方法推荐

不知道你们有没有发现&#xff0c;我们在网上下载的很多资料都是PDF格式的&#xff0c;尽管PDF文件也可以通过专门的PDF编辑器来编辑&#xff0c;但是PDF文档作为版式文档&#xff0c;编辑起来还是存在很多局限性&#xff0c;所有当我们需要大量编辑修改文档的时候&#xff0c;…...

极兔一面:Dockerfile如何优化?注意:千万不要只说减少层数

说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;面试题是一个非常、非常高频的交流话题。 最近&#xff0c;有小伙伴面试极兔时&#xff0c;遇到一个面试题&#xff1a; 如果优化 Dockerfile&#xff1f; 小伙伴没有回答好&#xff0c;只是提到了减少镜像层数。…...

SpringBoot+Vue实现酒店客房管理系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏…...

自适应多因素认证:构建不可破解的企业安全防线|身份云研究院

打开本文意味着你理解信息安全的重要性&#xff0c;并且希望获取行业最佳实践来保护你所在组织的信息安全。本文将带你了解多因素认证&#xff08;MFA&#xff1a;Multi-Factor-Authentication&#xff09;对于企业信息安全的重要性以及实施方法。 多因素认证&#xff08;MFA&…...

阶段二8_集合ArrayList_学生管理系统_详细步骤

一.学生管理系统案例 1.需求&#xff1a; 针对目前我们的所学内容&#xff0c;完成一个综合案例&#xff1a;学生管理系统&#xff01; 该系统主要功能如下&#xff1a; 1.添加学生&#xff1a;通过键盘录入学生信息&#xff0c;添加到集合中 2.删除学生&#xff1a;通过键盘录…...

一篇解决Linux 中的负载高低和 CPU 开销并不完全对应

负载是查看 Linux 服务器运行状态时很常用的一个性能指标。在观察线上服务器运行状况的时候&#xff0c;我们也是经常把负载找出来看一看。在线上请求压力过大的时候&#xff0c;经常是也伴随着负载的飙高。 但是负载的原理你真的理解了吗&#xff1f;我来列举几个问题&#x…...

关于IDM下载器,提示:一个假冒的序列号被用来注册……idea项目文件路径报红

关于IDM下载器&#xff0c;提示&#xff1a;一个假冒的序列号被用来注册……到C:\Windows\System32\drivers\etc 修改目录下面的hosts文件&#xff08;如果没有修改的权限就右键属性hosts文件修改user的权限为完全控制&#xff09;&#xff0c;在hosts里面增加以下内容&#xf…...

JVM - 高效并发

目录 Java内存模型和内存间的交互操作 Java内存模型 内存间的交互操作 内存间交互操作的规则 volatile特性 多线程中的可见性 volatile 指令重排原理和规则 指令重排 指令重排的基本规则 多线程中的有序性 线程安全处理 锁优化 锁优化之自旋锁与自适应自旋 锁优…...

中小学智慧校园电子班牌系统源码 Saas云平台模式

智慧电子班牌区别于传统电子班牌&#xff0c;智慧校园电子班牌系统更加注重老师和学生的沟通交流和及时数据交互。学校为每个教室配置一台智能电子班牌&#xff0c;一般安装于教室门口&#xff0c;用来实时显示学校通知、班级通知&#xff0c;可设置集中分布式管理&#xff0c;…...

记录一次服务器被攻击的经历

突然收到阿里云发过来的异常登陆的信息&#xff1a; 于是&#xff0c;急忙打开电脑查看对应的ECS服务器的记录&#xff1a; 发现服务器的cpu占用率异常飙升&#xff0c;所以可以大概断定服务器已经被非法入侵了。 通过自己的账号登陆后&#xff0c;发现sshd服务有异常的链接存…...

做塑胶原料用什么网站好/网站用户体验优化

AWS - 弹性计算云( Elastic Compute Cloud)Amazon EC2 (Elastic Compute Cloud)是一种Web服务接口&#xff0c;可在AWS云中提供可调整大小的计算容量。 它专为开发人员设计&#xff0c;可以完全控制Web扩展和计算资源。可以调整EC2实例的大小&#xff0c;并根据我们的要求按比例…...

网站建设与管理实训总结/百度数据分析工具

1、修改物理内存 使用jmeter进行压力测试时遇到一段时间后报内存溢出outfmenmory错误&#xff0c;导致jmeter卡死了&#xff0c;先尝试在jmeter.bat中增加了JVM_ARGS"-Xmx2048m -Xms2048m -Xmn256m -XX:PermSize128m -Xss256k"&#xff0c;但结果运行时间增加了&…...

手机网站大全12345/站长工具域名查询社区

&#xfeff;&#xfeff;1.高斯日记 大数学家高斯有个好习惯&#xff1a;无论如何都要记日记。他的日记有个与众不同的地方&#xff0c;他从不注明年月日&#xff0c;而是用一个整数代替&#xff0c;比如&#xff1a;4210后来人们知道&#xff0c;那个整数就是日期&#xff0…...

面试网站建设问题/电话营销销售系统

“云计算”这个词在今年颇为流行&#xff0c;以至于我终于不能再继续厚着脸皮当作没看到了。最初&#xff0c;我以为云计算就是一堆客户端计算机紧密的团结在一起&#xff0c;为一个共同的伟大的问题而献出自己的业余时间。后来某男告诉我&#xff0c;那叫网格计算&#xff0c;…...

可以做动画的网站都有哪些/百度账号管理

精彩网址大全——生活资讯&文体娱乐卷 中国铁道出版社 随着网络的普及&#xff0c;网络上的信息以空前的速度膨胀&#xff0c;网络也从信息集散地变成的信息垃圾场。从前在网络上寻找信息时&#xff0c;可能找不到所需要的信息&#xff0c;要想找到所需要的有用信息就变得…...

网站设计案例公司/阳西网站seo

今天晚上十点才下班。找了一晚上 bug。最后发现代码压缩之后&#xff0c;在 IE 下出现报错。测试数次之后&#xff0c;转而怀疑工具有问题。匆匆证明是代码压缩过程中出现的问题&#xff0c;但回家路上发现论证有误。等待明天再战。 上午阅读&#xff0c;改代码。中午翻译了小半…...