学习记录:QT5 界面设计的踩坑记录

  • 前言
  • 一、Qlabel显示视频与图片
    • 1. 图片显示
      • 1.1 显示格式
      • 1.2 label随界面缩放
      • 1.3 界面刷新
    • 2. 视频显示
  • 二、常见控件的StyleSheet设置
    • 1. 控件结构
    • 2. 控件样式表
      • 2.1 样式表格式
      • 2.2样式表示例
  • 三、界面关闭程序仍旧运行
    • 1. 守护进程
    • 2. 强制退出
    • 3. 标志位退出
  • 四、界面退出确认
  • 五、cv2摄像头调用与释放
    • 1. cv2调用摄像头
    • 2. cv2释放摄像头
  • 致谢
  • 参考

前言

本博客仅为记录Pyqt5学习之用,记录在过程所遇到的问题及解决措施,目的在于后续相关的内容有资可查。所包含的大致内容: Qlabel显示视频与图片;界面关闭程序仍旧运行;常见控件的StyleSheet设置;窗口退出确认

一、Qlabel显示视频与图片

1. 图片显示

本文是基于yolox-tiny的检测,下面介绍其中的重要语句。

image = Image.open(pic_path)
r_image, _, _, _ = yolo.detect_image(image)
frame = np.array(r_image)
showImage = QImage(frame.data, frame.shape[1], frame.shape[0], 3*frame.shape[1], QImage.Format_RGB888)
self.label_2.setPixmap(QPixmap.fromImage(showImage))
QApplication.processEvents()
self.label_2.setScaledContents(True)

1.1 显示格式

label.setPixmap(QPixmap.fromImage(showImage))
#若采用下面的语句,有时候导致图片不能显示完整或者被斜着划分为两部分。故QImage参数加上 3*frame.shape[1] 很重要。
showImage = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)

1.2 label随界面缩放

label.setScaledContents(True)

1.3 界面刷新

QApplication.processEvents()

2. 视频显示

capture = cv2.VideoCapture(0) # 获取摄像头
capture = cv2.VideoCapture(video_path) # 打开video_path
while (Ture):ref, frame = capture.read() #得到一帧图像if ref:frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) #BGR转RGBframe = Image.fromarray(np.uint8(frame))   # 转变成Imageframe, _, _, _ = yolo.detect_image(frame)frame = np.array(frame)height, width, bytesPerComponent = frame.shapebytesPerLine = bytesPerComponent * width # 格式设置q_image = QImage(frame.data, width, height, bytesPerLine,QImage.Format_RGB888).scaled(self.label_2.width(), self.label_2.height())self.label_2.setPixmap(QPixmap.fromImage(q_image))QApplication.processEvents() #刷新界面self.label_2.setScaledContents(True)# 缩放else: # 到达最后一帧capture.release() # 释放capturecv2.destroyAllWindows() #释放窗口break

二、常见控件的StyleSheet设置

先上效果图,效果如下

1. 控件结构


此处选择了4个QFrame,使得各部分各自属于一个QFrame,可以更好的设置效果。利用不同的分布以及layoutstretch调整不同的比例。

2. 控件样式表

2.1 样式表格式

样式表格式 示例 作用
控件类型#控件名 QWidget#Form 指定该对象名的控件,避免影响其他的控件
.控件类型 .QRadioButton 选择该类型的控件全体,以便批量设置同一类型的样式
控件类型[属性选择] QPushButton[flat=“false”] 选择所有flat属性值为false的 QPushButton类型
目前接触的内容较少,后续可继续补充… 待补充 待补充
控件属性 示例 作用
color color:black; 设置控件文字颜色,如黑色
border-image border-image: url(:function.png); 设置控件的边缘图片,如function.png
font font:12pt “楷体”; 设置字体和字号,如12个像素的楷体
border border:1px groove gray; 设置边缘,如一个像素的灰线
border-radius border-radius:10px or border-radius:1px 2px 3px 4px; 设置边缘圆角半径,一个值就是四个半径一样;四个值意味着左上角、右上角、右下角、左下角(顺时针顺序)如10个像素为半径;顺时针依次为1,2,3,4像素半径
padding padding:2px 4px; or padding:1px 2px 3px 4px; 设置填充宽度或者称留白距离,也是有以top为起始的顺时针四个值; 如上下2像素,左右4像素,顺时针1 2 3 4像素
目前接触的内容较少,后续可继续补充… 待补充 待补充

2.2样式表示例

当一个控件的样式被多层设置,最靠近控件设置生效,也就是说其优先级越高。

# 选择名字为Form 的QWidget设置样式
QWidget#Form { color: rgb(67, 143, 126);border-image: url(:/content/pic/function.png);
}
# 选择全体的QRadioButton 进行设置
.QRadioButton { background-color: rgba(170, 200, 255, 255) ;color:black;font:12pt "楷体";border-image: url();border:1px groove gray;border-radius:10px;padding:2px 4px;
}
# 选择全体的QPushButton 进行设置,此处有伪状态,停留按键在按键上可实现渐变颜色
.QPushButton { background-color: rgba(156, 214, 255, 255) ;color:black;font:14pt "楷体";border-image: url();border:1px groove gray;border-radius:12px;padding:2px 6px;
}QPushButton:hover{background-color: qlineargradient(spread:pad,  x1:0, x2:1, y1:0, y2:0,  stop: 0 rgba(44,180,255,255),stop: 0.495 rgba(80,237,255,55),stop: 0.505 rgba(172,200,216,20), stop: 1 rgba(23,212,255,255));font: 15pt "楷体";
}
QPushButton:hover{background-color: qlineargradient(spread:pad,  x1:0, x2:1, y1:0, y2:0,  stop: 0 rgba(44,180,255,255),stop: 0.495 rgba(80,237,255,55),stop: 0.505 rgba(172,200,216,20), stop: 1 rgba(23,212,255,255));

以上hover表示鼠标位于按键上方时的样式,其中qlineargradient表示线性渐变,x1==>x2表示水平方向的颜色变化;y1==>y2表示竖直方向的颜色变化。x1=x2,y1 != y2,则竖直方向渐变;x1!=x2,y1=y2则水平方向渐变。都不相等否则是对角线方向渐变。四个stop则是水平和竖直方向的颜色变换范围。

三、界面关闭程序仍旧运行

我们期望当界面关闭后程序也几乎同时停止,但是有时候会发现界面关闭后,程序仍在进行,以本检测为例,界面关闭后笔记本的摄像头仍没有退出,并且还在检测视频,一直占用内存,故关闭界面同时结束进程是很有必要的。

产生原因:多半是代码中具备死循环或者长时间的循环以及长时间的遍历,如 while turefor i in range(0, large-number) 等等, 导致在界面关闭时还没有循环结束。

解决办法大致分3种(鄙见哈):

  1. 利用进程,如守护进程之类的方法,当某进程关闭也关闭子进程。
  2. 不利用进程,在关闭界面时,强制退出当前的程序。
  3. 利用关闭的标志位,进行判断以结束循环。

1. 守护进程

本文没有采取该方法,仅提供一个思路。

2. 强制退出

利用sys.exit(),os._exit()之类的函数强制退出。

sys.exit()(推荐)
此函数通过抛出一个SystemExit异常来尝试结束程序,Python代码可以捕获这个异常来进行一些程序退出前的清理工作,也可以不退出程序。sys.exit函数可以带一个参数(默认为0)来作为程序的退出码。

os._exit() (不推荐)
此函数直接退出python解释器,函数后的所有代码都不执行。

3. 标志位退出

如以 窗体.Hide() = Ture窗体.Visible =Ture 为条件,判断是否当前窗体隐藏,如窗体不可见,可利用标志位结束循环,以退出程序。当然要明确是否是循环导致的无法退出。

四、界面退出确认

退出的确认也是比较重要的,有效地避免因为误操作或者误触摸导致的关闭。与此同时相比较前面所提到的结束进程的方法中,可直接利用sys.exit() 等强制退出,简单粗暴。
对于多个窗口,也可以在此对其余界面进行简单初始化或者恢复到初始条件的设置,如清空qlabel的内容等等。

def closeEvent(self, event):  # 固定函数名,切勿修改reply = QtWidgets.QMessageBox.question(self, u'警告', u'确认退出?', QtWidgets.QMessageBox.Yes,QtWidgets.QMessageBox.No)if reply == QtWidgets.QMessageBox.Yes:event.accept()  # 关闭窗口sys.exit() # 强制退出else:event.ignore()  # 判断为误操作,不关闭窗口

五、cv2摄像头调用与释放

1. cv2调用摄像头

opencv进行摄像头的调用,还算简单。
利用下列语句就可以调用,其中0是代表摄像头编号,只有一个的话默认为0,否则需要修改指定的摄像头编号。

cap = cv2.VideoCapture(0)

利用下列语句进一步得到一帧图像,进行显示或者后续工作,其中frame是图像信息,而正确读取,ref=Ture,类似于标志位。

ref, frame = capture.read()

但是需要注意的是cv2的颜色通道是BGR,一般需要转化为RGB。

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

点击ESC,手动退出

#等待1秒显示图像,若过程中按“Esc”(key=27)退出
c = cv.waitKey(1) & 0xffif c == 27:# 释放所有窗口cv.destroyAllWindows()break

2. cv2释放摄像头

值得一提的是,cv2释放摄像头和调用是成对出现的。一旦没释放很可能造成窗口关闭程序还在运行。利用下列语句可实现摄像头释放。

cv2.VideoCapture.release()

但是一旦前文对调用命名后,必须采取相同的名字才能得以释放,如采用上述的语句会直接抛出错误,所以注意要对应释放。

cap = cv2.VideoCapture(0)
#省略中间代码
cap.release()

致谢

欲尽善本文,因所视短浅,怎奈所书皆是瞽言蒭议。行文至此,诚向予助与余者致以谢意。

参考

  1. 白月黑羽: http://www.byhy.net

【学习记录】QT5界面设计的踩坑记录相关推荐

  1. HuaWei Atlas200 DK交叉编译踩坑记录

    文章目录 HuaWei Atlas200 DK交叉编译踩坑记录 HuaWei Atlas200 DK交叉编译踩坑记录 由于需要用到OpenCV以及CV的一个特征提取的库vlfeat,并且MindStu ...

  2. 双系统Ubuntu22.04深度学习环境配置与踩坑记录

    双系统Ubuntu22.04深度学习环境配置踩坑记录 前言 目录 相关版本 主要参考教程 Ubuntu安装 Nvidia和CUDA安装 踩坑经历 官网安装所遇问题 cuDNN安装 Anaconda安装 ...

  3. AirSim学习和踩坑记录(不定时更新)

    版权声明:本文为博主原创文章,遵循Creative Commons - Attribution-ShareAlike 4.0 International - CC BY-SA 4.0版权协议,转载请附 ...

  4. Qt5.13.2中配置opencv4.5.0踩坑记录

      目录 cmake编译opencv时速度过慢或超时 mingw32-make时报错 错误一 [modules\core\CMakeFiles\opencv_core.dir\build.make:1 ...

  5. MAC-XXL_JOB学习踩坑记录-Failed to create parent directories for [/data/applogs/xxl-job/xxl-job-admin.log

    MAC-XXL_JOB学习踩坑记录 源码下载地址 启动报错 源码下载地址 ①.GitHub:https://github.com/xuxueli/xxl-job ②.码云:https://gitee. ...

  6. cesium给地图添加比例尺学习踩坑记录

    cesium给地图添加比例尺学习踩坑记录 因项目需要在cesium地图中展示比例尺,本来应该是很简单的事,但却碰到了一个引用文件的坑,特此记录: *1.引用依赖文件 相信需要用到cesium比例尺组件 ...

  7. Slam学习笔记——ROS踩坑记录

    Slam学习笔记--ROS踩坑记录 1. 安装 2. ROS文件系统 2.1 工作区 2.2 包package 2.2.1 包的操作 2.2.2 描述文件package.xml 2.3 节点node ...

  8. mybatis学习与踩坑记录

    mybatis resultmap高级映射 应用场景:如果sql查询的列名和pojo的属性名不一致,可以使用resultMap将列名和pojo的属性名作一个对应关系,就可以映射成功了.(如果返回值为i ...

  9. Nvidia Jetson TX2 详细刷机教程及踩坑记录(Jetpack3.3,python2.7,torch1.2,torchvision0.2.2)

    本文总结了自带系统安装cuda等深度学习环境和使用jetpack3.3刷机的步骤,虽然自己的代码没用上,但有需要的人可以参考一下. PS:Jetpack4.5的刷机教程请移步另一篇文章: xyl-50 ...

最新文章

  1. R语言安装.tar.gz包
  2. HTTP协议03-http特点及请求方式
  3. c++中多线程传递参数原理分析
  4. php 二维sort,php 二维数组排序
  5. 什么是E1接口,E1的使用注意事项
  6. c++函数为什么带imp_二次函数含参最值问题,老师怎么讲学生都不明白,试试这九张动图...
  7. 前端改变窗口大小内容不变形_10个前端灵魂拷问丨吃透这些就能摆脱初级前端工程师...
  8. python编译:setup.py添加.h头文件或者库的搜索路径
  9. delphi制作上下开幕效果_显示产业国际盛会开幕,广州新型显示产值将突破2500亿...
  10. mplab java失败_【超菜鸟求助】编译时失败,以下是显示内容。
  11. 学习在layui中input、select、date日历的onchange事件无效解决方法
  12. python股票回测_用Python徒手撸一个股票回测框架
  13. 平行四边形不等式优化详解
  14. hdu2154跳舞毯(dp)
  15. python中的translate函数_Python:内置函数makestrans()、translate()
  16. 浙江大学【面板数据分析与STATA应用】——第一讲短面板数据分析
  17. 【angular学习】自定义实现双向绑定
  18. 计算机信息检索的常用位置算符有,计算机信息检索基本算符?含义
  19. Android Studio使用签名打包发布APP(安卓生成apk文件)
  20. c语言中gets 、getchar 、fgets 、scanf的用法

热门文章

  1. 互联网时代个人信息安全的重要性
  2. JavaScript操作DOM对象 Day05
  3. React 接入 Ueditor + xiumi
  4. 【NOI2006】 生日快乐
  5. axis.jar的应用
  6. python画自定义颜色的坐标图
  7. word页码与行号怎么统一设置字体
  8. 【论文阅读】6-Automatic 3D Model Construction for Turn-Table Sequences
  9. linux信号函数signal(SIGCHLD, SIG_IGN)
  10. 2023华为软件精英挑战赛,探寻软件人才与科技创新的最优解