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

YOLOv5实战记录05 Pyside6可视化界面

个人打卡,慎看。

指路大佬:【手把手带你实战YOLOv5-入门篇】YOLOv5 Pyside6可视化界面_哔哩哔哩_bilibili

零、虚拟环境迁移路径后pip报错解决

yolov5-master文件夹我换位置后,无法pip install了。解决如下:

  • activate.bat中修改:@set "VIRTUAL_ENV=D:\yolov5-master\venv"
  • activate中修改:VIRTUAL_ENV='D:\yolov5-master\venv'
  • 更新pip:python -m pip install --upgrade pip

参考:Python 虚拟环境迁移路径后pip报错解决记录_pybot移动路径后-CSDN博客

【建议挂v,速度会快】

一、环境安装

  • 下载Pyside6:  pip install pyside6

我的pyside6不在Python.exe的上级文件夹的子目录下,packages和python.exe的位置也不同,发现解释器的位置设置错了,之前一直提示我Invalid,我也没有注意。

一般python.exe和site-packages的位置关系是,python.exe和它的上级在同一文件夹下。

比如anaconda下python.exe, lib

lib下site-packages ,也可以输入以下命令,查找site-packages的位置。

import site
print(site.getsitepackages())

以后安装了包,但是无法import,也可以查找site-packages的位置,很有可能这里面没有那个包。是python.exe选取的错误,修改为对应的python.exe即可。

  • 找到pyside6/designer.exe,将快捷方式发送到桌面。
  • up主用vscode安装了qt for python插件,但是我使用的是Pycharm,vscode不熟练,在pycharm中,设置setting->tools->external tools,点击+ ,添加,在Program中,输入designer.exe的位置。name和group随便设置,点击ok。

二、设计UI

  1. 新建mainwindow
  2. 把两个textlabel拖到mainwindow中【存放图片】,用vertical line隔离他们。拖两个pushbutton【按钮】。
  3. 勾选scaledcontents可以实现label中存放内容缩放。将alignment设置水平中心对齐。
  4. 修改对象的名字,便于记忆。比如label1改成input
  5. 保存到yolov5-master文件夹下,修改名字为main_window

三、将ui转换成py

添加external tool

我的血泪教训,改这个错改了40min:

  1. program不要选site-packages\Pyside6\uic.exe 这样转换出来的结果可能是C++代码。
  2. 选\Scripts\pyside6-uic.exe这个文件

  • Program: D:\anaconda\Scripts\pyside6-uic.exe 【输入自己的pyside6-uic.exe文件路径】
  • Arguments: $FileName$ -o $FileNameWithoutExtension$.py
  • working directory: $FileDir$

四、调用mainwindow

import sysfrom PySide6.QtWidgets import QMainWindow, QApplicationfrom main_window import Ui_MainWindow
#这里的main_window是你的ui转换成的py名字
#Ui_MainWindow是main_window里的class名字class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()   #self后不要加(),我加了()报错无法调用mainwindowself.setupUi(self)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

运行上面的指令即可弹出UI设计界面。

五、关联按钮和代码

bing_slots()函数负责绑定。det_image和pushButton_2【忘改了】是那两个按钮的名字。

import sysfrom PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from main_window import Ui_MainWindowclass MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.bind_slots()  #不要忘记调用,不写这句话无法显示。def open_image(self):print("点击显示图片!")def open_video(self):print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

六、获取图片

  • 一开始无法显示,我设置QPixmap("./datasets/images/train/30.jpg")发现可以显示,于是判断是filepath格式的问题;
  • QPixmap的参数是string类型的。打印file_path[0]发现打印出来的仍然是list格式。
  • 于是转换list为string类型。filePath=','.join(file_path[0])
#与上个代码省略了相同的部分,方便理解。from PySide6.QtGui import QPixmap
#显示图片def open_image(self):file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])print(file_path[0])print(filePath)self.input.setPixmap(QPixmap(filePath))  #图片显示

七、训练图片

  • 首先,遇到了问题,我运行页面卡住了,一直在下载某个包,经查找,发现是下面这行代码的问题。我运行提示卡在了“'Downloading torch-2.2.2-cp310-cp310-win_amd64.whl (198.6 MB)”,
  • model = torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",trust_repo=True, source="local") 运行这行代码时卡住了,其他代码不会卡。
  • 已解决:下载几个包即可:pip install torch torchvision torchaudio
  • 参考:通过pip安装pytorch超时问题解决 - 知乎 (zhihu.com)

运行代码:

import sys
import torch
from PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from PySide6.QtGui import QPixmap,QImage
#显示图片from main_window import Ui_MainWindowdef convert2QImage(img):height,width,channel=img.shapereturn QImage(img,width,height,width*channel,QImage.Format_RGB888)class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.model=torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",source="local")self.bind_slots()  #不要忘记调用,不写这句话无法显示def image_pred(self,filePath):results=self.model(filePath)image=results.render()[0]return convert2QImage(image)#检测后的图片def open_image(self):file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])qimage=self.image_pred(filePath)self.input.setPixmap(QPixmap(filePath))self.output.setPixmap(QPixmap.fromImage(qimage))def open_video(self):print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

八、训练视频

仍然遇到了报错:Traceback (most recent call last):
  File "D:\yolov5-master\yolov5-master\base_ui.py", line 57, in open_video
    self.input.setPixmap(QPixmap(convert2QImage(filePath)))
  File "D:\yolov5-master\yolov5-master\base_ui.py", line 13, in convert2QImage
    height,width,channel=imag.shape
AttributeError: 'str' object has no attribute 'shape'

但是我训练图片时, height,width,channel=imag.shape这行代码就没有出现问题,于是查找包含改行代码的函数调用的参数,果然写错了self.input.setPixmap(QPixmap(convert2QImage(frame)))是frame不是filePath。 一定要细心!!!

import sys
import cv2
import torch
from PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from PySide6.QtGui import QPixmap,QImage
#显示图片from main_window import Ui_MainWindowdef convert2QImage(imag):height,width,channel=imag.shapereturn QImage(imag,width,height,width*channel,QImage.Format_RGB888)class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.model=torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",source="local")self.bind_slots()  #不要忘记调用,不写这句话无法显示def image_pred(self,filePath):results=self.model(filePath)image=results.render()[0]return convert2QImage(image)#检测后的图片def video_pred(self,img):results=self.model(img)image=results.render()[0]return convert2QImage(image)def open_image(self):file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])qimage=self.image_pred(filePath)self.input.setPixmap(QPixmap(filePath))self.output.setPixmap(QPixmap.fromImage(qimage))def open_video(self):#视频检测是一帧一帧地检测,利用opencv抽帧。file_path = QFileDialog.getOpenFileNames(self, dir="./datasets", filter="*.mp4")if file_path[0]:filePath=','.join(file_path[0])print(filePath)video = cv2.VideoCapture(filePath)while True:ret,frame=video.read()if not ret:breakframe = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)qimage=self.video_pred(frame)self.input.setPixmap(QPixmap(convert2QImage(frame)))self.output.setPixmap(QPixmap.fromImage(qimage))print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

不过我运行后很慢,并且只显示了视频最后一帧的检测结果和原图片。

问题:界面刷新不及时。

解决:加入计时器from PySide6.QtCore import QTimer
 

import sys
import cv2
import torch
from PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from PySide6.QtGui import QPixmap,QImage
#显示图片
from PySide6.QtCore import QTimer
#计时器from main_window import Ui_MainWindowdef convert2QImage(imag):height,width,channel=imag.shapereturn QImage(imag,width,height,width*channel,QImage.Format_RGB888)class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.model=torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",source="local")self.timer=QTimer()self.timer.setInterval(100) #时间间隔。默认单位毫秒ms ,可以设置的小一点儿,视频更加丝滑。self.bind_slots()  #不要忘记调用,不写这句话无法显示def image_pred(self,filePath):results=self.model(filePath)image=results.render()[0]return convert2QImage(image)#检测后的图片def video_pred(self):ret, frame = self.video.read()if not ret:self.timer.stop()else:frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)self.input.setPixmap(QPixmap.fromImage(convert2QImage(frame)))#放在这儿而不是self.output上面,因为可能受检测的图像影响。在检测之前先显示出来。results=self.model(frame)image=results.render()[0]self.output.setPixmap(QPixmap.fromImage(convert2QImage(image)))def open_image(self):file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])qimage=self.image_pred(filePath)self.input.setPixmap(QPixmap(filePath))self.output.setPixmap(QPixmap.fromImage(qimage))def open_video(self):#视频检测是一帧一帧地检测,利用opencv抽帧。file_path = QFileDialog.getOpenFileNames(self, dir="./datasets", filter="*.mp4")if file_path[0]:filePath=','.join(file_path[0])print(filePath)self.video = cv2.VideoCapture(filePath)self.timer.start()# while True:#     ret,frame=video.read()##     if not ret:#         break#     frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)#     qimage=self.video_pred(frame)#     self.input.setPixmap(QPixmap(convert2QImage(frame)))#     self.output.setPixmap(QPixmap.fromImage(qimage))print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)self.timer.timeout.connect(self.video_pred)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

仍然存在问题,如果再点击“图片检测”按钮,不会停下,这是因为计时器没有停。

解决方案:在打开图片时,关闭计时器,def open_image(self): self.timer.stop()

全部代码:

import sys
import cv2
import torch
from PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from PySide6.QtGui import QPixmap,QImage
#显示图片
from PySide6.QtCore import QTimer
#计时器from main_window import Ui_MainWindowdef convert2QImage(imag):height,width,channel=imag.shapereturn QImage(imag,width,height,width*channel,QImage.Format_RGB888)class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.model=torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",source="local")self.timer=QTimer()self.timer.setInterval(1) #默认单位毫秒msself.bind_slots()  #不要忘记调用,不写这句话无法显示def image_pred(self,filePath):results=self.model(filePath)image=results.render()[0]return convert2QImage(image)#检测后的图片def video_pred(self):ret, frame = self.video.read()if not ret:self.timer.stop()else:frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)self.input.setPixmap(QPixmap.fromImage(convert2QImage(frame)))# 放在这儿而不是self.output上面,因为可能受检测的图像影响。在检测之前先显示出来。results=self.model(frame)image=results.render()[0]self.output.setPixmap(QPixmap.fromImage(convert2QImage(image)))def open_image(self):self.timer.stop()file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])qimage=self.video_pred(filePath)self.input.setPixmap(QPixmap(filePath))self.output.setPixmap(QPixmap.fromImage(qimage))def open_video(self):#视频检测是一帧一帧地检测,利用opencv抽帧。file_path = QFileDialog.getOpenFileNames(self, dir="./datasets", filter="*.mp4")if file_path[0]:filePath=','.join(file_path[0])print(filePath)self.video = cv2.VideoCapture(filePath)self.timer.start()# while True:#     ret,frame=video.read()##     if not ret:#         break#     frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)#     qimage=self.video_pred(frame)#     self.input.setPixmap(QPixmap(convert2QImage(frame)))#     self.output.setPixmap(QPixmap.fromImage(qimage))print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)self.timer.timeout.connect(self.video_pred)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

九、复盘

  1. 首先利用Pyside6的designer设计了UI界面。两个button,两个label,一条线。导出生成ui文件。将ui文件编译生成成py文件,注意external tool选的是pyside6-uic.exe,不是uic.exe!!!
  2. 构建程序,设计函数:初始化;绑定按键与函数事件;打开图片;打开视频;图片预测;视频预测【预测部分利用了torch.hub,实际上是对每一帧的图片进行预测,利用了计时器】

 效果如下:【我之前标注的label很草率,所以效果很差,不过迈出了从0到1的步子,我很开心了。】

pyside6可视化页面预测


今天最大的收获就是可以平静地对待报错了,之前从大一开始每次改报错都特别烦躁,今天竟然可以平静地坐着改几个小时的bug。我之前特别怵头以后做机器学习、python相关的研究,现在不怕了。

要相信你遇到的问题,别人也遇到过,并且他们解决了。

如果别人没有遇到过,那正好,你会是第一个发现问题并解决的人,之后的人都会借鉴你的解决方案。

相关文章:

YOLOv5实战记录05 Pyside6可视化界面

个人打卡,慎看。 指路大佬:【手把手带你实战YOLOv5-入门篇】YOLOv5 Pyside6可视化界面_哔哩哔哩_bilibili 零、虚拟环境迁移路径后pip报错解决 yolov5-master文件夹我换位置后,无法pip install了。解决如下: activate.bat中修改…...

HTML5.Canvas简介

1. Canvas.getContext getContext(“2d”)是Canvas元素的方法,用于获取一个用于绘制2D图形的绘图上下文对象。在给定的代码中,首先通过getElementById方法获取id为"myCanvas"的Canvas元素,然后使用getContext(“2d”)方法获取该Ca…...

excel统计分析——多项式回归

参考资料:生物统计学 多项式回归属于单变量曲线回归,但其形式和求解方法与多元线性回归相似。多项式回归的数学模型为: 令,,,,则 由于X不可逆,两边同时乘以X得,&#xff…...

SQLyog连接数据库8.0版本解析错误问题解决方案

问题描述: 解决方案: alter userrootlocalhostidentified with mysql_native_password by 密码; 再次连接就可以了。...

【数据库】SQL简介

SQL(Structured Query Language,结构化查询语言)是一种用于管理关系型数据库管理系统(RDBMS)的标准化语言。它用于访问和操作数据库中的数据,执行各种任务,如插入、更新、删除和检索数据&#x…...

AWS入门实践-利用S3构建一个静态网站

使用Amazon S3托管静态网站是一个流行的选择,因为它简单、成本效益高,并且易于维护。静态网站由不含服务器端脚本的文件组成,如HTML、CSS和JavaScript文件。下面是使用S3托管静态网站的操作步骤: 如果大家没有AWS免费账号&#x…...

使用Linux strace追踪系统调用: 一个详细指南

使用Linux strace追踪系统调用: 一个详细指南 Linux strace是一个强大的命令行工具,用于监视和调试进程中发生的系统调用和信号。它对于系统管理员和开发人员来说是理解程序行为和解决问题的重要工具。 什么是strace? strace是一种跟踪运行中的进程执…...

python 笔记

文章目录 pdbpdb开始调试pythonpdb设置断点单步执行进入到函数的内部执行到下一个断点或程序结束调用栈查看命令查看当前函数调用堆栈向上一层函数查看调用堆栈查看源代码 importimport 用法 numpy导入numpy模块numpy常用函数np.argmaxnp.sum range生成连续序列生成不连续序列 …...

软考 系统架构设计师系列知识点之数据库基本概念(4)

接前一篇文章:软考 系统架构设计师系列知识点之数据库基本概念(3) 所属章节: 第6章. 数据库设计基础知识 第1节 数据库基本概念 6.1.3 数据库管理系统 DBMS(DataBase Management System,数据库管理系统&am…...

Vue - 3( 15000 字 Vue 入门级教程)

一:初识 Vue 1.1 收集表单数据 收集表单数据在Vue.js中是一个常见且重要的任务,它使得前端交互变得更加灵活和直观。 Vue中,我们通常使用v-model指令来实现表单元素与数据之间的双向绑定,从而实现数据的收集和更新。下面总结了…...

上位机图像处理和嵌入式模块部署(qmacvisual图像清晰度)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 做过isp的同学都知道,图像处理里面有一个3A,即自动曝光、自动白平衡和自动对焦。其中自动对焦这个,就需要用输入…...

数据结构和算法:分治

分治算法 分治(divide and conquer),全称分而治之,是一种非常重要且常见的算法策略。分治通常基于递归实现,包括“分”和“治”两个步骤。 1.分(划分阶段):递归地将原问题分解为两个…...

增强Java技能:使用OkHttp下载www.dianping.com信息

在这篇技术文章中,我们将探讨如何使用Java和OkHttp库来下载并解析www.dianping.com上的商家信息。我们的目标是获取商家名称、价格、评分和评论,并将这些数据存储到CSV文件中。此外,我们将使用爬虫代理来绕过任何潜在的IP限制,并实…...

用友 NC saveXmlToFIleServlet 任意文件上传漏洞复现

0x01 产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。 0x02 漏洞概述 用友 NC saveXmlToFIleServlet接口处存在…...

JS第九天

今天是第九天,学习了JS中的设置日期和倒计时,计时器以及验证码倒计时,那么话不多说我们开始今天的学习吧 一、日期设置 1.1日期创建 调用 new Date() 来创建一个新的 Date 对象。在调用时可以带有一些参数,创建一个 Date 对象&…...

CSS设置字体样式

目录 前言: 1.font-family: 2.font-style: 3.font-weight: 4.font-size: 5.font-variant: 6.font: 前言: 在网页中字体是重要的组成部分,使用好字体可以让网页更…...

[Java线程池]ExecutorService|CompletionService的区别与选择

这段时间对业务系统做了个性能测试,其中使用了较多线程池的技术,故此做一个技术总结。 这次总结的内容比较多,主要是四个: ExecutorServiceCompletionServiceRunnableCallable 前两个是线程池相关接口,后两个是多线…...

MySQL-SQL编写练习:基本的SELECT语句

基本的SELECT语句 1. SQL的分类 DDL:数据定义语言。CREATE \ ALTER \ DROP \ RENAME \ TRUNCATEDML:数据操作语言。INSERT \ DELETE \ UPDATE \ SELECT (重中之重)DCL:数据控制语言。COMMIT \ ROLLBACK \ SAVEPOINT \ GRANT \ REVOKE 学习技巧&#xf…...

C++经典面试题目(十九)

1、什么是析构函数?它有什么作用? 析构函数是类的特殊成员函数,用于在对象被销毁时执行清理工作。它的名称与类名相同,前面加上波浪号(~)。析构函数的作用在于确保在对象被销毁时释放占用的资源&#xff0…...

acwing算法提高之图论--SPFA找负环

目录 1 介绍2 训练 1 介绍 本专题用来记录使用spfa算法来求负环的题目。 2 训练 题目1&#xff1a;904虫洞 C代码如下&#xff0c; #include <cstring> #include <iostream> #include <algorithm> #include <queue>using namespace std;typedef p…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...