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;…...
神经网络基础部件-卷积层详解
前言 在全连接层构成的多层感知机网络中,我们要通过将图像数据展平成一维向量来送入模型,但这会忽略了每个图像的空间结构信息。理想的策略应该是要利用相近像素之间的相互关联性,将图像数据二维矩阵送给模型中学习。 卷积神经网络(convolu…...
【计算机网络】HTTPS协议原理
文章目录一、认识HTTPS协议二、为什么要发明HTTPS三、HTTP与HTTPS的区别四、常见的加密方式1. 对称加密2. 非对称加密3. 数据摘要4. 数字签名五、HTTPS的原理探究方案1:只使用对称加密方案2:只使用非对称加密方案3:双方都使用非对称加密方案4…...
21岁,华科博士在读,我的赛事Top经验
Datawhale干货 作者:vaew,华中科技大学,博士二年级在读简介笔者vaew,21岁,现为华中科技大学机械科学与工程学院陶波教授课题组博士二年级学生。主要研究方向是基于视触融合的机器人灵巧操作。学业之余的研究兴趣包括图…...
基于ThinkPHP6.0+Vue+uni-app的多商户商城系统好用吗?
likeshop多商户商城系统适用于B2B2C、多商户、商家入驻、平台商城场景。完美契合平台自营联营加盟等多种经营方式使用,系统拥有丰富的营销玩法,强大的分销能力,支持官方旗舰店,商家入驻,平台抽佣商家独立结算ÿ…...
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、要完成的任务 目标:结合SQL和excel实现餐饮业日销售情况分析仪,如下表: 认识分析仪: 切片器:店面 分为四部分:KPI 、组合图、饼图、数…...
电商导购CPS,京东联盟如何跟单实现用户和订单绑定
前言 大家好,我是小悟 做过自媒体的小伙伴都知道,不管是发图文还是发短视频,直播也好,可以带货。在你的内容里面挂上商品,你自己都不需要囤货,如果用户通过这个商品下单成交了,自媒体平台就会…...
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、心跳机制简介 在分布式系统中,分布在不同主机上的节点需要检测其他节点的状态,如服务器节点需要检测从节点…...
python3.9安装和pandas安装踩坑处理
0、先决条件:系统内最好先安装有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. 转置矩阵
每日一题题目描述解题核心解法一:二维表示 模拟解法二:一维表示 模拟题目描述 题目链接:867. 转置矩阵 给你一个二维整数数组 matrix, 返回 matrix 的 转置矩阵 。 矩阵的 转置 是指将矩阵的主对角线翻转,交换矩阵…...
【人脸识别】Partial-FC:让你在一台机器上训练1000万个id人脸数据集成为可能!
论文题目:”Killing Two Birds with One Stone: Efficient and Robust Training of Face Recognition CNNs by Partial FC“ -CVPR 2022 代码地址:https://arxiv.org/pdf/2203.15565.pdf 代码地址: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学习记录:分布式锁
一、基本原理和实现方式对比 分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行…...
对React-Fiber的理解,它解决了什么问题?
对React-Fiber的理解,它解决了什么问题?Fiber用来解决什么问题?Fiber是什么?Fiber是如何解决问题的?Fiber用来解决什么问题? JavaScript引擎和页面渲染引擎两个线程是互斥的,当其中一个线程执行…...
【Linux】初学Linux你需要掌握这些基本指令(二)
目录 1.man指令 2.cp指令 3.mv指令 4.tree指令 5.echo指令 6.more指令 7.less指令(重要) 8.head与tail指令 9.date指令 显示时间常用参数: 设置时间常用参数: 10.cal指令 11.find & whereis & which指令 …...
Linux中VI/VIM 编辑器
1、概述所有Linux系统都会内置vi文本编辑器vim是vi的升级版,可以主动以字体颜色分辨语法的正确性,代码补完和编译,错误跳转等功能。2、vi和vim的三种模式基本上 vi/vim 共分为三种模式,分别是一般模式、编辑模式、命令模式2.1、一…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
