linux桌面小程序开发日记2(pyqt5+yolov5)

2023-11-16

linux桌面小程序开发日记2

使用Pyqt5 制作一个界面,并连接摄像头

最后一篇博客地址:https://blog.csdn.net/Liuchengzhizhi/article/details/123692365

B站视频:https://www.bilibili.com/video/BV1rZ4y1B7t8?share_source=copy_web

源码:https://gitee.com/wx_b915676bb6/yolo-pyqt.git

前言

承接上回,我们把环境装好啦,那么接下来就要开始我们的UI啦,预计完成连接摄像的内容

项目要求——自己想的

  1. 主要用python语言开发
  2. 能够显示摄像头的内容
  3. 能够显示识别内容的列表
  4. 能够进行计价

那我们就开始新的记录吧

第一步 设计UI界面

我就随手画了一个

在这里插入图片描述

第二步 python连接摄像头

因为我的是虚拟机,所以我首先要把我的摄像头连接到虚拟机上,因为我的是usb摄像头,所以要把对应的服务打开,如下图

在这里插入图片描述

然后我们来连一下

在这里插入图片描述

安装一下我们需要的OpenCV库

#激活虚拟环境
conda activate yolo
#更新pip
python3 -m pip install --upgrade pip
#安装opencv库 该版本是适用于我的pyqt5的
pip3 install opencv-python==4.3.0.36

在这里插入图片描述

这样我们需要的库就安装完成了(我这里出现了问题:我安装好后,我的vscode没有检测到,后来我重启vscode后,就检测到了,所以如果遇到同样的问题,我建议重启一下软件,但是首先要看看自己到底有没有安装成功)

在这里插入图片描述

重启后,引用库就是蓝绿色的,说明vscode检测到了这几个库

在这里插入图片描述

然后我们来测试一下,摄像头到底有没有连上

我复制黏贴了该博客的代码,进行的测试

python3+pyqt5+pycharm 打开摄像头显示_ZJE-CSDN博客_pyqt5 打开摄像头

from PyQt5 import QtCore,QtGui,QtWidgets
import sys
import cv2
import numpy as np 
 
class Ui_MainWindow(QtWidgets.QWidget):
    def __init__(self,parent=None):
        super().__init__(parent) #父类的构造函数
 
        self.timer_camera = QtCore.QTimer() #定义定时器,用于控制显示视频的帧率
        self.cap = cv2.VideoCapture()       #视频流
        self.CAM_NUM = 0                    #为0时表示视频流来自笔记本内置摄像头
 
        self.set_ui()                       #初始化程序界面
        self.slot_init()                    #初始化槽函数
 
    '''程序界面布局'''
    def set_ui(self):
        self.__layout_main = QtWidgets.QHBoxLayout()           #总布局
        self.__layout_fun_button = QtWidgets.QVBoxLayout()      #按键布局
        self.__layout_data_show = QtWidgets.QVBoxLayout()       #数据(视频)显示布局
        self.button_open_camera = QtWidgets.QPushButton('打开相机') #建立用于打开摄像头的按键
        self.button_close = QtWidgets.QPushButton('退出')           #建立用于退出程序的按键
        self.button_open_camera.setMinimumHeight(50)                #设置按键大小
        self.button_close.setMinimumHeight(50)
 
        self.button_close.move(10,100)                      #移动按键
        '''信息显示'''
        self.label_show_camera = QtWidgets.QLabel()   #定义显示视频的Label
        self.label_show_camera.setFixedSize(641,481)    #给显示视频的Label设置大小为641x481
        '''把按键加入到按键布局中'''
        self.__layout_fun_button.addWidget(self.button_open_camera) #把打开摄像头的按键放到按键布局中
        self.__layout_fun_button.addWidget(self.button_close)       #把退出程序的按键放到按键布局中
        '''把某些控件加入到总布局中'''
        self.__layout_main.addLayout(self.__layout_fun_button)      #把按键布局加入到总布局中
        self.__layout_main.addWidget(self.label_show_camera)        #把用于显示视频的Label加入到总布局中
        '''总布局布置好后就可以把总布局作为参数传入下面函数'''
        self.setLayout(self.__layout_main) #到这步才会显示所有控件
 
    '''初始化所有槽函数'''
    def slot_init(self):
        self.button_open_camera.clicked.connect(self.button_open_camera_clicked)    #若该按键被点击,则调用button_open_camera_clicked()
        self.timer_camera.timeout.connect(self.show_camera) #若定时器结束,则调用show_camera()
        self.button_close.clicked.connect(self.close)#若该按键被点击,则调用close(),注意这个close是父类QtWidgets.QWidget自带的,会关闭程序
 
    '''槽函数之一'''
    def button_open_camera_clicked(self):
        if self.timer_camera.isActive() == False:   #若定时器未启动
            flag = self.cap.open(self.CAM_NUM) #参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频
            if flag == False:       #flag表示open()成不成功
                msg = QtWidgets.QMessageBox.warning(self,'warning',"请检查相机于电脑是否连接正确",buttons=QtWidgets.QMessageBox.Ok)
            else:
                self.timer_camera.start(30)  #定时器开始计时30ms,结果是每过30ms从摄像头中取一帧显示
                self.button_open_camera.setText('关闭相机')
        else:
            self.timer_camera.stop()  #关闭定时器
            self.cap.release()        #释放视频流
            self.label_show_camera.clear()  #清空视频显示区域
            self.button_open_camera.setText('打开相机')
 
    def show_camera(self):
        flag,self.image = self.cap.read()  #从视频流中读取
 
        show = cv2.resize(self.image,(640,480))     #把读到的帧的大小重新设置为 640x480
        show = cv2.cvtColor(show,cv2.COLOR_BGR2RGB) #视频色彩转换回RGB,这样才是现实的颜色
        showImage = QtGui.QImage(show.data,show.shape[1],show.shape[0],QtGui.QImage.Format_RGB888) #把读取到的视频数据变成QImage形式
        self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))  #往显示视频的Label里 显示QImage
if __name__ =='__main__':
    app = QtWidgets.QApplication(sys.argv)  #固定的,表示程序应用
    ui = Ui_MainWindow()                    #实例化Ui_MainWindow
    ui.show()                               #调用ui的show()以显示。同样show()是源于父类QtWidgets.QWidget的
    sys.exit(app.exec_())                   #不加这句,程序界面会一闪而过

然后就成功啦,还是很开心哒( * *)

在这里插入图片描述

问题

点击启动,发现有报错,提示已放弃(核心已转储),我就参考了这篇博客,将opencv降版本,如果该版本还是报错,那就再把版本降低

(38条消息) Uuntu20.04出现“qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in…已放弃 (核心已转储)”问题解决记录_消灭BUG鸭的博客-CSDN博客

还有一个问题是,我第一次运行的时候,上面的这个界面是很卡,而且打开相机发现直接无响应。我以为有错误,但是我第二遍运行的时候,就成功了,所以第一次不成功的话,就看看运行第二次有没有问题,有问题再看报错。

同时这个需要检测你的摄像头,如果打开摄像头,提示找不到摄像头,就需要你去修改一下你的摄像头的编号。就是下面注释的地方。至于这个编号怎么改,可以一个一个试,也可以去搜一下如何查看摄像头编号(我默认的这个0是可以的)(可以自己搜一下如何查看摄像头编号)

在这里插入图片描述

第三步 设计界面 完成功能

首先,我们把上面复制的代码自己学习解读一下,好方便我们接下来自己做一个类似的,看代码方面就不多做赘述了。

参考的文章有下面这几个

(38条消息) PyQt5高级界面控件之QTimer(十一)_jia666666的博客-CSDN博客_pyqt5 qtimer

槽函数是什么 - 搜索 (bing.com)

利用设计工具画图

里面用到了布局的组件

左边是一张表,右边就是视频,下面是对应的按钮

在这里插入图片描述

完成视频暂停的功能

简单来说,释放掉视频流时,我不清空视频显示区域,这样显示的图片就停在最后一张,就像是截取了一样

(因为我的项目与物体识别有关,所以我的设想是点击确认后,视频暂停,用户确认表中信息与图片中的信息是否有误,无误,再点击成交,所以我的设想中需要这一功能,但到后期,还需要修改,改为处理后的显示图片)

代码如下

这里我将函数名称也修改了,变量名称也修改了注意一下(就微改了改了几行代码)

  1. 我将打开摄像头放在了初始化上,一运行摄像头就是打开状态
  2. 修改了定义按钮的名称,同时将清空视频显示区域代码删除,完成截图效果
from PyQt5 import QtCore,QtGui,QtWidgets
import sys
import cv2
import numpy as np 
 
class Ui_MainWindow(QtWidgets.QWidget):
    def __init__(self,parent=None):
        super().__init__(parent) #父类的构造函数
 
        self.timer_camera = QtCore.QTimer() #定义定时器,用于控制显示视频的帧率
        self.cap = cv2.VideoCapture()       #视频流
        self.CAM_NUM = 0                    #为0时表示视频流来自笔记本内置摄像头
 
        self.set_ui()                       #初始化程序界面
        ''' Check whether the camera is connected and started'''
        self.open_camera()
        self.slot_init()                    #初始化槽函数
        

 
    '''程序界面布局'''
    def set_ui(self):
        self.__layout_main = QtWidgets.QHBoxLayout()           #总布局
        self.__layout_fun_button = QtWidgets.QVBoxLayout()      #按键布局
        self.__layout_data_show = QtWidgets.QVBoxLayout()       #数据(视频)显示布局
        self.button_confirm = QtWidgets.QPushButton('重新确认') #建立用于打开摄像头的按键
        self.button_close = QtWidgets.QPushButton('退出')           #建立用于退出程序的按键
        self.button_confirm.setMinimumHeight(50)                #设置按键大小
        self.button_close.setMinimumHeight(50)
     
        self.button_close.move(10,100)                      #移动按键  这句话去掉好像也没关系
        '''信息显示'''
        self.label_show_camera = QtWidgets.QLabel()   #定义显示视频的Label
        self.label_show_camera.setFixedSize(641,481)    #给显示视频的Label设置大小为641x481
        '''把按键加入到按键布局中'''
        self.__layout_fun_button.addWidget(self.button_confirm) #把打开摄像头的按键放到按键布局中
        self.__layout_fun_button.addWidget(self.button_close)       #把退出程序的按键放到按键布局中
        '''把某些控件加入到总布局中'''
        self.__layout_main.addLayout(self.__layout_fun_button)      #把按键布局加入到总布局中
        self.__layout_main.addWidget(self.label_show_camera)        #把用于显示视频的Label加入到总布局中
        '''总布局布置好后就可以把总布局作为参数传入下面函数'''
        self.setLayout(self.__layout_main) #到这步才会显示所有控件
 
    '''初始化所有槽函数'''
    def slot_init(self):
        self.button_confirm.clicked.connect(self.open_camera)    #若该按键被点击,则调用button_confirm()
        self.timer_camera.timeout.connect(self.show_camera) #若定时器结束,则调用show_camera()
        self.button_close.clicked.connect(self.close) #若该按键被点击,则调用close(),注意这个close是父类QtWidgets.QWidget自带的,会关闭程序
 
    '''槽函数之一'''
    def open_camera(self):
        if self.timer_camera.isActive() == False:   #若定时器未启动
            flag = self.cap.open(self.CAM_NUM) #参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频
            if flag == False:       #flag表示open()成不成功
                msg = QtWidgets.QMessageBox.warning(self,'warning',"请检查相机于电脑是否连接正确",buttons=QtWidgets.QMessageBox.Ok)
            else:
                self.timer_camera.start(30)  #定时器开始计时30ms,结果是每过30ms从摄像头中取一帧显示
                self.button_confirm.setText('确定')
        else:
            self.timer_camera.stop()  #关闭定时器
            self.cap.release()        #释放视频流
            # self.label_show_camera.clear()  #清空视频显示区域
            self.button_confirm.setText('重新确认')
 
    def show_camera(self):
        flag,self.image = self.cap.read()  #从视频流中读取
 
        show = cv2.resize(self.image,(640,480))     #把读到的帧的大小重新设置为 640x480
        show = cv2.cvtColor(show,cv2.COLOR_BGR2RGB) #视频色彩转换回RGB,这样才是现实的颜色
        showImage = QtGui.QImage(show.data,show.shape[1],show.shape[0],QtGui.QImage.Format_RGB888) #把读取到的视频数据变成QImage形式
        self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))  #往显示视频的Label里 显示QImage
        
if __name__ =='__main__':
    app = QtWidgets.QApplication(sys.argv)  #固定的,表示程序应用
    ui = Ui_MainWindow()                    #实例化Ui_MainWindow
    ui.show()                               #调用ui的show()以显示。同样show()是源于父类QtWidgets.QWidget的
    sys.exit(app.exec_())                   #不加这句,程序界面会一闪而过

添加显示表格功能

参考的文章有下面面几篇

python GUI库图形界面开发之PyQt5控件QTableWidget详细使用方法与属性 - 云+社区 - 腾讯云 (tencent.com)

在这里我重新修改了我的代码,使其成为为上面设计的图纸。同时我将表格的内容设为不可编辑

代码如下

关于摄像头的代码没有修改,所以就没有黏贴上来

修改的内容有:

  • 将总布局改为栅格布局
  • 添加了表格布局
  • 又增加了一个按键布局
  • 将表格改为不可编辑
  • 删除了退出按钮
  • 设置了label的大小
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtWidgets import QHeaderView 
from PyQt5.QtWidgets import QAbstractItemView

import sys
import cv2
import numpy as np 
 
class Ui_MainWindow(QtWidgets.QWidget):
    def __init__(self,parent=None):
        super().__init__(parent) #父类的构造函数
 
        self.timer_camera = QtCore.QTimer() #定义定时器,用于控制显示视频的帧率
        self.cap = cv2.VideoCapture()       #视频流
        self.CAM_NUM = 0                    #为0时表示视频流来自笔记本内置摄像头
 
        self.set_ui()                       #初始化程序界面
        ''' Check whether the camera is connected and started'''
        self.open_camera()
        self.slot_init()                    #初始化槽函数


    '''程序界面布局'''
    def set_ui(self):
        self.__layout_main = QtWidgets.QGridLayout()           #总布局
        self.__layout_fun_button1 = QtWidgets.QHBoxLayout()      #按键布局1
        self.__layout_fun_button2 = QtWidgets.QHBoxLayout()      #按键布局2
        self.__layout_data_show = QtWidgets.QVBoxLayout()       #数据(视频)显示布局
        self.__layout_list_show  = QtWidgets.QVBoxLayout()          #表格布局

        self.button_confirm = QtWidgets.QPushButton('重新确认') #建立用于打开摄像头的按键
        # self.button_close = QtWidgets.QPushButton('退出')               #建立用于退出程序的按键
        self.button_settle_accounts = QtWidgets.QPushButton('结账') #建立结账的按钮
        self.list_show =  QtWidgets.QTableWidget(6,3)                          #建立表格
        self.label_account = QtWidgets.QLabel("总价")                          #建立label

        '''set butten size '''
        self.button_confirm.setMinimumHeight(50)                #设置按键大小
        # self.button_close.setMinimumHeight(50)
        self.button_settle_accounts.setMinimumHeight(50)
        self.label_account.setMinimumHeight(50)
        

        # self.button_close.move(10,100)                      #移动按键  这句话去掉好像也没关系
        '''set label font'''
        font = QtGui.QFont()
        font.setPixelSize(18)
        self.label_account.setFont(font)

        '''set list'''
        self.list_show.setHorizontalHeaderLabels(["名称","数量","单价"])
        self.list_show.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)# adaptive size
        self.list_show.setEditTriggers(QAbstractItemView.EditTrigger(False))    #将表格的内容设为不可编辑
        '''信息显示'''
        self.label_show_camera = QtWidgets.QLabel()   #定义显示视频的Label
        self.label_show_camera.setFixedSize(641,481)    #给显示视频的Label设置大小为641x481
        '''把按键加入到按键布局中'''
        self.__layout_fun_button1.addWidget(self.button_confirm) #把重新确认的按键放到按键布局中
        # self.__layout_fun_button1.addWidget(self.button_close)       #把退出程序的按键放到按键布局中
        self.__layout_fun_button2.addWidget(self.button_settle_accounts) #把结账的按键放到按键布局中
        '''把表格加入到表格布局中'''
        self.__layout_list_show.addWidget(self.list_show)           #将表格添加到表格布局中
        self.__layout_list_show.addWidget(self.label_account) #将总价label添加到表格布局中


        '''把某些控件加入到总布局中'''
        self.__layout_main.addLayout(self.__layout_list_show,0,0)            #将表格布局添加到总布局中
        self.__layout_main.addLayout(self.__layout_fun_button1,1,1)      #把按键布局加入到总布局中
        self.__layout_main.addLayout(self.__layout_fun_button2,1,0)      #把按键布局加入到总布局中
        self.__layout_main.addWidget(self.label_show_camera,0,1)        #把用于显示视频的Label加入到总布局中
        
        '''总布局布置好后就可以把总布局作为参数传入下面函数'''
        self.setLayout(self.__layout_main) #到这步才会显示所有控件
 
    '''初始化所有槽函数'''
    def slot_init(self):
        self.button_confirm.clicked.connect(self.open_camera)    #若该按键被点击,则调用button_confirm()
        self.timer_camera.timeout.connect(self.show_camera) #若定时器结束,则调用show_camera()

整体的效果看下图,它是可以自由放大缩小的
在这里插入图片描述

可能遇到的问题,就是找了很长时间才找到如何让表格禁止编辑。

还有就是需要稍稍会一些界面的布局的东西。

ok,这第二集的日记就结束啦。下一章,我们就要尝试连接yolo,让yolov5处理后,在显示画面。

最后

总结一下:真的是什么都不会,就做完这些东西我花了两个上午的时间。有很多查的东西也看不懂,也是到了最后,才慢慢摸到了我想要的功能。真不知道,以后真的坐上了开发,这个英文开发文档看不懂会怎么办(>_<)。真的是一看到这些全英文的东西脑袋就大。

不过还是做出来了我想要的效果,还是要鼓励一下自己的嘛。

那么我们就开始我们第三章日记的记录吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux桌面小程序开发日记2(pyqt5+yolov5) 的相关文章

随机推荐

  • 最新VLC命令行参数大全(一)

    用法 vlc 选项 流 您可以在命令行中指定多个流 它们将被加入播放列表队列 指定的首个项目将被首先播放 选项风格 选项 用于设置程序执行期间的全局选项 选项 单字母版本的全局 选项 选项 仅对此选项之前的单条流生效 且优先级高于先前的设置
  • 细说三极管

    文章目录 前言 一 什么是三极管 二 三极管是哪三级 1 基极 2 集电极 3 发射极 三 三极管的分类 1 根据材料 2 根据结构 3 根据功率 4 根据工作频率 5 根据制作工艺 6 根据制外形封装 7 根据用途 四 三极管的工作原理
  • Adobe新的AI产品开放公测!Firefly带来全新的制图体验,让你效率翻倍!

    随着midjourney 还是Stable Diffusion 以及各式各样的AI绘图网站的出现 Adobe也推出AI绘图工具 Firefly 这款产品目前免费开放公测 未来将结合Photoshop Illustrator 等Adobe软件
  • 合宙Air101+蓝牙模块,实现手机控制舵机转动

    器材 蓝牙模块JDY33 合宙Air101 接线 JDY33的串口接Air101的串口1 TX U1 RX PB 07 RX U1 TX PB 06 舵机信号线接Air101PWM0 PB 00 main lua LuaTools需要PRO
  • MIPI入门——DCS介绍

    DCS Display Command Set 即显示 控制 命令集 是DSI协议中所使用的相关 控制 命令的一个集合 显示设备 如LCD 厂商可以选择性地部分 或全部 实现DCS文档中规定的命令 为了便于理解下面的内容 首先介绍一下DSI
  • sqli-labs(24)

    这个关卡可能有时候会出现一些小问题 有时候登陆后是没有修改密码的选项的 这是因为有时候解压时logged in php文件解压不正确 重新解压即可 本关卡为二次注入 其产生原因是 服务器端虽然对用户的直接输入做了一些过滤或者将一些字符进行转
  • 数字经济专家高泽龙谈“金融元宇宙”与“元宇宙金融”

    开始聊所有话题之前 必须先说说 金融元宇宙 或者 元宇宙金融 的概念和定义 当然 前提是搞清楚 金融 和 元宇宙 百度百科中 金融 的定义 金融 Finance Finaunce 是市场主体利用金融工具将资金从资金盈余方流向资金稀缺方的经济
  • Python读取文件时出现UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position xx: 解决方案

    Python在读取文件时 with open article txt as f 打开新的文本 text new f read 读取文本数据 出现错误 UnicodeDecodeError gbk codec can t decode byt
  • electron autoUpdater热更新

    最近创建了一个electron vue项目 用到了热更新 先看效果图 话不多说 直接上代码 main目录下创建update js 代码如下 安装包helatest yml所在服务器地址 const uploadUrl http 127 0
  • 金山WPS暑期实习招聘笔试题2013-7-28

    C 试卷B卷 应聘职位1 2 姓 名 性 别 学 位 所在院校 所学专业 联系电话 电子邮件 毕业时间 获知招聘信息渠道 说明 答题时间为 100 分钟 自我判断题 请选择最符合您本人意愿的一项 1 你
  • 从项目实施层面解析STEAM教育

    转自 https baijiahao baidu com s id 1614434815561381532 wfr spider for pc 一 引言 近几年大家常常听到STEAM教育这个词 似乎一夜之间所有的培训机构的课程都变成了STE
  • 第9章_瑞萨MCU零基础入门系列教程之SCI I2C

    本教程基于韦东山百问网出的 DShanMCU RA6M5开发板 进行编写 需要的同学可以在这里获取 https item taobao com item htm id 728461040949 配套资料获取 https renesas do
  • Android-SharedPreferences实现记住密码和自动登录

    效果图 第一次进入进来 勾选记住密码和自动登录成功后 第二次进来 说明 中间存在的图片或者多余的其他部分可删掉 留下最主要的填写部分和登陆按钮即可 功能还是可以实现的 XML文件
  • QQ飞车手游设计分析

    腾讯系竞速手游的逆袭 QQ飞车手游设计分析 前言 这是中山大学数据科学与计算机学院软件工程2019年3D游戏编程与设计的作业1 导语 在中国巨大的游戏市场下 手游战场上的战火从未熄灭 其中以王者荣耀为首的MOBA类手游与以PUBG 现改名和
  • 【Flink Rest-ful API 】

    Flink 有了一些查询job状态指标的API 这些监控 API is a REST ful API 接受 HTTP 请求并返回JSON data 这些监控API以jobManager中web server 为基础 默认其监听端口为8081
  • PHPstudy安装教程

    首先简单介绍一下PHPStudy PHPStudy是一个Windows下的Apache Nginx php MYSQL的集成开发环境 PHPStudy比较适合快速的在windows下部署一个Web开发环境 而且便于安装 部署方便 服务器本身
  • linux环境下安装nginx

    一 准备安装环境 安装nginx需要系统相关插件 所以在安装前先检查哈是否有这些插件 如果没有 则要先安装这些插件 由于笔者是新的虚拟机环境 所以这些插件都没有 都需要安装 读者可以根据自己实际情况进行相关操作 1 安装 gcc gcc c
  • HTML引用公共组件

    在test html引用footer html 效果图 代码 test html div 我是頁面 div div class footer div
  • 《再也不怕elasticsearch》REST API调用

    REST API调用 大家好我是迷途 一个在互联网行业 摸爬滚打的学子 热爱学习 热爱代码 热爱技术 热爱互联网的一切 再也不怕elasticsearch系列 帅途会慢慢由浅入深 为大家剖析一遍 各位大佬请放心 虽然这个系列帅途有时候更新的
  • linux桌面小程序开发日记2(pyqt5+yolov5)

    linux桌面小程序开发日记2 使用Pyqt5 制作一个界面 并连接摄像头 最后一篇博客地址 https blog csdn net Liuchengzhizhi article details 123692365 B站视频 https w