文章目录

  • 前言
  • 正文
    • 1.界面设计
    • 2.界面开发进阶
    • 3.在线程中不能直接更新界面
    • 4.pyqt播放音频
    • 5.dialog弹窗
  • 小结

前言

由于原生的python不能做出漂亮的界面,发现很多人都选择使用qt.
参考资料:
pyqt 教程 http://code.py40.com/pyqt5/16.html
pyqt进阶教程 https://blog.csdn.net/la_vie_est_belle/category_9279128.html
网络案例 https://blog.csdn.net/DerrickRose25/article/details/86744787
发现一个好用的查询 api的工具 代码中编辑help(xxx)

正文

1.界面设计

通过网络案例,我们得到一个初始框架.同时知道了opencv读出的帧如何绘制在pyqt控件上.

    # 核心代码-绘制def show_camera(self):flag, self.image = self.cap.read()show = cv2.resize(self.image, (640, 480))show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))# 核心代码-更新  (利用定时器重复绘制)self.timer_camera = QtCore.QTimer()  # 初始化定时器self.timer_camera.timeout.connect(self.show_camera)

由于界面不是重点,相关功能简单实现,没有单页跳转,没有动画.

第一个界面,左边是4个小的视频通道预览,右边是检测出的人脸列表,列表可以上下滚动
点击其中一个视频通道,进入第二个界面,左边是1个大的视频预览,右边是检测出的人脸列表,列表可以上下滚动

问题1:让界面适配屏幕

#获取屏幕宽高,screenGeometry(0)就是主屏幕,1的话是分屏1,以此类推
self._screen_width =  int(QApplication.desktop().screenGeometry(0).width())
self._screen_height = int(QApplication.desktop().screenGeometry(0).height())#设置window
# move()方法是移动窗口在屏幕上的位置
self.resize(box_s[0], box_s[1])
self.move(self._screen_offset, self._screen_offset)#设置layout
#设置widget
label_show_camera = QtWidgets.QLabel()
label_show_camera.setFixedSize(page1_preview_s[0], page1_preview_s[1])
label_show_camera.setAutoFillBackground(False)

2.界面开发进阶

pycharm + Qt Designer
参考:https://blog.csdn.net/crazy696/article/details/88721688

问题1:如何调整gridLayout
https://blog.csdn.net/yxy244/article/details/96278255
先打破,然后摆放,然后再组合

问题2: listview如何添加item

1)简单文本列表

item_list = ['item %s' % i for i in range(660)]model = QtCore.QStringListModel(self)model.setStringList(item_list)self.listView.setModel(model)

2)复杂布局列表

实现方法大概有这么三种:
1)如果使用QListWidget的话,我们直接调用 setItemWidget 即可。
void setItemWidget(QListWidgetItem *item, QWidget *widget)

2)QListWidget和QListView都可以通过调用 setIndexWidget 实现。但是该方法只适合做静态数据的显示,不适合做一些插入、更新、删除操作的数据显示。
void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)

3)我们针对QListView实现自己的ItemDelegate。重写ItemDelegate的paint函数。

首先了解下view/model 参考:https://www.cnblogs.com/hangxin1940/archive/2012/04/23/2806444.html

知道什么是Delegate后,参考这位大哥的c++写法
https://blog.csdn.net/a844651990/article/details/84324560
改了一个python版本

# 重新定义数据结构
class ListData(object):def __init__(self,  name, image):self.name = nameself.image= imageclass MyDelegate(QStyledItemDelegate):"""自定义的委托用来在Model获取后,view显示前,再将数据渲染一次"""def paint(self, painter, option, index):if index.isValid():painter.save()# 首先,从索引获取数据,这里获取当前索引角色为DisplayRole的数据item_var = index.data(QtCore.Qt.DisplayRole)  # [QVariant]if not item_var:return# item区域rect = QRectF()rect.setCoords(option.rect.x(),option.rect.y(),option.rect.x()+option.rect.width(),option.rect.y()+option.rect.height())# 图像区域imageRect = QRect(rect.x()+10,rect.y()+10, 80, 80)# 绘制图像show = cv2.cvtColor(item_var.image, cv2.COLOR_BGR2RGB)showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)painter.drawImage(imageRect,showImage)# 文本区域nameRect = QRect(imageRect.right()+10,imageRect.top(), rect.width()-10-imageRect.width(), 40)painter.setPen(QtGui.QPen(QtCore.Qt.black))painter.setFont(QFont("Microsoft Yahei",12))painter.drawText(nameRect, 0, "视频源:%s" % item_var.name)painter.restore()# 需要指定item宽高def sizeHint(self, option: 'QStyleOptionViewItem', index: QtCore.QModelIndex) -> QtCore.QSize:return QSize(option.rect.width(), 100);

最后再外部调用,这里好像并不用实现model,用QStandardItemModel就好了

 # 初始化列表数据self.list_model = QtGui.QStandardItemModel()self.listView.setModel(self.list_model)# 新建一个委托(Delagate)delegate = MyDelegate()# 设置view的delegateself.listView.setItemDelegate(delegate)

当数据更新,需要刷新界面时

        for d in list_data:item = QtGui.QStandardItem()item.setData(d, QtCore.Qt.DisplayRole)self.list_model.appendRow(item)self.listView.update()self.listView.scrollToBottom()

这样,一个简单的界面就差不多了

3.在线程中不能直接更新界面

需要配合QThread, 内置信号,通过信号让主线程更新界面.否则会出现界面不更新的奇景,这bug我调了大半天,一直以为是视频解码出错,结果…(泪奔)

# 1)定义线程
class decodeThread(QtCore.QThread):# 通过类成员对象定义信号对象,传递要刷新的图像signal = QtCore.pyqtSignal(QtGui.QPixmap)def __init__(self):super(decodeThread, self).__init__()def run(self):...self.signal.emit(pixmap)# 2)调用线程
self.thread = decodeThread(target=self._init_camera)
#指定收到信号后要执行的方法
self.thread.signal.connect(self._refresh_pic)
self.thread.start()

ps:这里注意thread不能是临时变量,否则会出现另一个神bug

4.pyqt播放音频

pyqt5的QtMultimedia模块找不到,为了不影响系统,这里用pygame

安装pip install pygame

import pygameclass MyPlayer(object):def __init__(self):pygame.mixer.init()  # 初始化def play(self, filename):if not pygame.mixer.music.get_busy():pygame.mixer.music.load(filename)  # 加载音乐pygame.mixer.music.play()  # 播放audioPlayer = MyPlayer()

ps: 结果我的程序跑到半路挂掉了.折腾了1小时发现pygame.mixer.music.load这个方法只能放在主线程中调用,放到多线程中调用会报错:PyEval_SaveThread: NULL tstate
另外,该方法同一时刻仅能播放一个音频

5.dialog弹窗

点击按钮弹出窗口,怎么写.
1)先用qt designer 新建dialog . 一样往里面写控件,然后一样的ui转py,生成Ui_Dialog类
2)实现dialog子类继承该Ui_Dialog类


class childWindow(QDialog,ui_dialog_mask.Ui_Dialog):def __init__(self):QDialog.__init__(self)self.set_ui()def set_ui(self):self.setupUi(self)

3)主窗口调用

 App = QApplication(sys.argv)win = Ui_MainWindow()child = childWindow()# 通过toolButton将两个窗体关联btn = win.pushButtonbtn.clicked.connect(child.show)win.show()sys.exit(App.exec_())

小结

1)Qt Designer制作界面生成.ui文件
2)QtUIC将.ui文件转换为.py文件
3)继承该.py文件
class Ui_MainWindow(QtWidgets.QMainWindow, Ui_Page1Window):
则可以通过self访问其中的控件

这一套下来有点像当年开发android了.确实美观便捷

一些问题:
1)pyqt使用png图片时有时会失真,改用jpg

pyqt制作简单的摄像头监控界面相关推荐

  1. php简单网页制作代码,用HTML和CSS以及JS制作简单的网页菜单界面的代码

    这篇文章主要介绍了使用HTML+CSS+JS制作简单的网页菜单界面,这个ABROAD项目所使用的JavaScript部分代码非常简单,需要的朋友可以参考下 写ABROAD项目用到了标签这个东东,其实标 ...

  2. 【python/qt】Python+Qt实现简单的视频监控界面

    DATE: 2018.12.9 1.前言 这个界面是之前读研时候学习QT时写的一个简单的界面,主要实现了人脸检测部分的功能,比较简单. 从今年3月份就开始写这个视频监控的功能,一直拖到了11月份.找工 ...

  3. php开发路由器界面,PHP制作简单仿路由器登录界面

    在php中,可以使用Header函数用户验证: Header('WWW-Authenticate: Basic realm="USER LOGIN"'); Header('HTTP ...

  4. PHP制作简单仿路由器登录界面

    在php中,可以使用Header函数用户验证: Header('WWW-Authenticate: Basic realm="USER LOGIN"'); Header('HTTP ...

  5. js怎么制作html的主题,用HTML和CSS以及JS制作简单的网页菜单界面的代码

    写ABROAD项目用到了标签这个东东,其实标签在WEB上到处可见,图中就依次显示了DCC文章发布器.ABROAD后台添加数据.百度图片搜索.sf发布博客文章时贴标签的样式--标签就像浏览器里原生的ch ...

  6. android页面布局计算机,Android Studio制作简单计算器App

    Android Studio制作简单计算器App 计算机界面如图: 程序设计步骤: (1)在布局文件中声明编辑文件框EditText,按钮Button等组件. (2)在MainActivity中获取组 ...

  7. arduino摄像头监控_如何使用Arduino和Pusher制作实时光监控器

    arduino摄像头监控 by Neo Ighodaro 由新Ighodaro 如何使用Arduino和Pusher制作实时光监控器 (How to make a realtime light mon ...

  8. android监控摄像头,监控其实很简单 给摄像头装个安卓系统

    如果你认为家庭监控摄像机和马路上专门拍车牌的摄像机一样,那你就错了.尽管这两种产品都被叫做监控摄像机,其功能和效果上还是有很大区别.如何给家庭监控摄像机一个更清晰.直观的定义?今天笔者就来跟您聊一聊. ...

  9. [OpenCv]简单摄像头监控Demo

    最近发现一篇报道,十分好玩,有兴趣的可以点击下面的链接 公安部门的摄像头每天都拍到了啥? 然后就写了这个小视频或者摄像头监控Demo玩玩. 1.主要使用OpenCv 2.帧差法与Cascade相结合 ...

最新文章

  1. MVVM开发模式MVVM Light Toolkit中使用事件和参数传递
  2. 工业相机参数之帧率相关知识详解
  3. c语言嵌入式开发单片机,嵌入式开发|单片机基础
  4. eclipse代码补全
  5. leetcode101. 对称二叉树(两种做法)
  6. Waymo自动驾驶数据集介绍与使用教程
  7. xsi:schemaLocation有何作用
  8. ajax 表格删除,jQuery AJAX删除只捕获第一个表格
  9. 获取登录域帐号信息方式之 —-IIS(VB)
  10. 【Python】基于Python的百度迁徙3——城内出行强度(附代码)
  11. 3DSMAX 中的CS 骨骼动画插件初探
  12. 电路分析第三章 电容与电感
  13. Linux AHCI驱动分析之块设备层
  14. 时间管理之-----《暗时间》-刘未鹏
  15. 打开.pos文件--ProcessOn
  16. tcp ip通讯协议测试软件6,实验6 TCPIP协议属性设置
  17. 上海计算机一级优秀率,数据 | 上海初中哪家强?2020四校八大预录数据告诉你!...
  18. 财税SaaS行业格局再变,慧算账为何能受资本“偏爱”?
  19. LED圆柱屏、波浪屏、飘带屏等异形屏是由柔性软模组构成的创意LED显示屏
  20. 谈谈事件委托的理解?

热门文章

  1. 深入了解电容(三):陶瓷电容MLCC
  2. 图灵 | 一站式图应用平台
  3. 企业搬迁至直线50公里新地点,员工不去被要求集中办理离职,请各位大佬支招如何保证自身权益?
  4. python写cdr插件_(如何(用Python)写一个(Lisp)解释器(下))
  5. 如何在IDEA中连接mysql数据库
  6. JS学习20:for..in 循环遍历对象
  7. RK3568平台开发系列讲解(安卓篇)Android Telephony框架介绍
  8. 用matlab求解线性方程组
  9. 手撸Spring系列10:Spring AOP(实战篇)
  10. 如何实现扫描二维码自动跳转到网页