PyQt5+QtDesigner编写摄像头界面程序(三)——主程序的编写
文章目录
前言
上一节中,我们已经完成了程序的界面设计,并初步编写了主函数可以生成程序的界面。这一节将介绍如何编写各控件的调用函数,实现摄像头参数的调控,并通过time函数实现摄像头的实时图像显示。
在上一节中,我们通过QtDesigner生成了程序界面的ui文件,然后通过PyUIC将该ui文件转换成了py文件。在PyCharm中打开pyuic生成的py文件:“QtTest.py”,该文件的主要内容如下所示:
该文件中定义了一个界面类Ui_CamShow,在该类中定义了两个函数setupUi和retranslateUi。展开setupUi函数可以发现,该函数的内容正是我们在QtDesigner中进行的各种控件、布局的创建和属性设置。而retranslateUi函数主要实现各控件的显示设置。由于setupUi函数的末尾调用了retranslateUi函数,因此我们在主函数中只需要调用setupUi函数就可以生成程序界面。
在上一节中,为了观察程序界面的运行效果,我们简单编写了一下主函数,内容如下图所示。首先,我们从创建好的QtTest中导入界面类Ui_CamShow,然后导入程序需要的各种库函数。接下来,我们定义了一个新的类CamShow,用来实现程序的主要功能。程序的最后一段,“if name == ‘main’:”后面的内容是程序的主函数,它的内容很少,在后续工作中也不再进行修改,其功能就是控制程序的开始和结束,实例化CamShow类。我们的主要代码内容都放在CamShow类中。
目前,在CamShow类中,我们只定义了一个初始化函数“init(self,parent=None):”,在实例化CamShow类时,会自动调用它的初始化函数,因此,我们把想要让程序自动实现的程序功能都放在该函数下。目前,该函数下调用了两个函数:super函数实现了类的继承,将QMainWindow,Ui_CamShow的各种属性过继给CamShow类;setupUI函数则是从Ui_CamShow中继承过来的函数,用来实现程序界面的创建和属性设置。
super(CamShow,self).__init__(parent) self.setupUi(self)
接下来,我们在初始化函数“init(self,parent=None):”中继续添加新的函数,来实现程序的功能。我们添加的函数如下图所示,根据我们程序的需要,一共添加六个函数,函数PrepSliders用来实现各个slider和对应的spinbox的关联,保证两个控件的值始终相等;函数PrepWidgets用来初始化各个控件,由于某些控件需要在其它控件背后的函数运行后才能工作,因此需要先将它“disable”,例如,“保存”功能,必须在我们点击“开始”按钮开始取图后才有效,因此在程序最开始的时候,需要将“保存”按钮“disable”;PrepParameters用来定义并初始化程序运行过程中会用到的变量;CallBackFunctions则是各个控件背后的功能函数的集合,它定义了我们在程序界面上进行某项操作后实际执行的代码;最后两行,则是计时器的定义和调用,它定义了一个定时器,等我们执行计时器开始的代码后,该计时器就开始计时,每次计时结束都会调用一次函数TimerOutFun,我们用计时器实现对摄像头图像的循环读取和显示。当然,这些函数都是我们自己定义的函数,我们后面的工作就是编写代码实现这些函数的功能。
def __init__(self,parent=None): super(CamShow,self).__init__(parent) self.setupUi(self)self.PrepSliders() self.PrepWidgets() self.PrepParameters() self.CallBackFunctions() self.Timer = QTimer() self.Timer.timeout.connect(self.TimerOutFun)
另外,由于我们定义了很多新的函数,这些函数会调用到很多新的库函数,我们需要把对应的库全部import进来。我们需要导入的所有库函数如下所示:
from QtTest import Ui_CamShow import sys from PyQt5.QtWidgets import QApplication,QMainWindow,QFileDialog from PyQt5.QtCore import QTimer,QCoreApplication from PyQt5.QtGui import QPixmap import cv2 import qimage2ndarray import time
接下来,我们来逐个实现刚才定义的这些函数。
1、Slider和SpinBox
PrepSliders函数的实现代码如下所示,我们一共定义了7对slider和spinbox,我们需要逐个地将它们关联起来。函数的代码其实很容易理解,基本上就像读英语一样。以前两行为例,它们的功能就是一旦RedColorSld的值发生变化后,就调用RedColorSpB的setValue函数,将变化后的值赋给RedColorSpB;反过来,一旦RedColorSpB的值发生变化后,就调用RedColorSld的setValue函数,将变化后的值赋给RedColorSld。这样一来,RedColorSld和RedColorSpB就关联起来了,不管哪一个的值发生改变,另一个也会随之而改变。
def PrepSliders(self): self.RedColorSld.valueChanged.connect(self.RedColorSpB.setValue) self.RedColorSpB.valueChanged.connect(self.RedColorSld.setValue) self.GreenColorSld.valueChanged.connect(self.GreenColorSpB.setValue) self.GreenColorSpB.valueChanged.connect(self.GreenColorSld.setValue) self.BlueColorSld.valueChanged.connect(self.BlueColorSpB.setValue) self.BlueColorSpB.valueChanged.connect(self.BlueColorSld.setValue) self.ExpTimeSld.valueChanged.connect(self.ExpTimeSpB.setValue) self.ExpTimeSpB.valueChanged.connect(self.ExpTimeSld.setValue) self.GainSld.valueChanged.connect(self.GainSpB.setValue) self.GainSpB.valueChanged.connect(self.GainSld.setValue) self.BrightSld.valueChanged.connect(self.BrightSpB.setValue) self.BrightSpB.valueChanged.connect(self.BrightSld.setValue) self.ContrastSld.valueChanged.connect(self.ContrastSpB.setValue) self.ContrastSpB.valueChanged.connect(self.ContrastSld.setValue)
这里需要注意的是,我们需要保证slider和对应的spinbox的取值范围是一致的,也就是它们的最大和最小值必须相等,这一点,我们在QtDesigner设计时可以设置它们的相关属性来保证,在接下来的程序编写过程中,如果涉及到它们的最大或最小值变动时也要保证slider和spinbox同时变动。
2、控件初始化
PrepWidgets函数的内容如下所示,首先要调用一个PrepCamera函数,这个函数我们后面再编写,接下来,就是在开始取图前,将相关的控件都“disable”,设置方法就是调用“setEnabled”函数,并给它赋值为False,类似地,如果赋值为True的话就是将该控件“enable”。
def PrepWidgets(self): self.PrepCamera() self.StopBt.setEnabled(False) self.RecordBt.setEnabled(False) self.GrayImgCkB.setEnabled(False) self.RedColorSld.setEnabled(False) self.RedColorSpB.setEnabled(False) self.GreenColorSld.setEnabled(False) self.GreenColorSpB.setEnabled(False) self.BlueColorSld.setEnabled(False) self.BlueColorSpB.setEnabled(False) self.ExpTimeSld.setEnabled(False) self.ExpTimeSpB.setEnabled(False) self.GainSld.setEnabled(False) self.GainSpB.setEnabled(False) self.BrightSld.setEnabled(False) self.BrightSpB.setEnabled(False) self.ContrastSld.setEnabled(False) self.ContrastSpB.setEnabled(False)
PrepCamera函数的代码内容如下所示,为了防止程序出错退出,我们采用了try…except…语句,它实现的功能是先尝试运行try语句后面的代码,如果没有问题就继续往下运行,如果出错就执行except后面的代码。
def PrepCamera(self): try: self.camera=cv2.VideoCapture(0) self.MsgTE.clear() self.MsgTE.append('Oboard camera connected.') except Exception as e: self.MsgTE.clear() self.MsgTE.append(str(e))
我们先来看try后面的代码,
self.camera=cv2.VideoCapture(0),的功能就是调用OpenCV的VideoCapture函数打开摄像头,并使用变量self.camera代表该摄像头,参数0意味着打开笔记本自带的摄像头。
self.MsgTE.clear():清空文本框MsgTE中的内容。
self.MsgTE.append('Oboard camera connected.'):在文本框MsgTE中显示’Oboard camera connected.’,其中append函数意思是在现有的内容后继续添加内容,除此之外,textedit控件还有setPlainText函数,意识是用括号中的文本覆盖原来的文本。
而except语句后面的内容则是捕获出错内容Exception,并将其内容显示在文本框MsgTE中,这样,当程序出错时,程序就不会自动退出,而且我们可以通过文本框MsgTE查看出错信息,帮助我们找到问题所在。
3、参数初始化
PrepParameters函数的代码如下所示。我们定义了变量self.RecordFlag,该值为0时不保存视频,为1才时开始保存视频。变量self.RecordPath定义了默认的文件存储路径。
self.FilePathLE.setText(self.RecordPath)将路径名显示在文本框FilePathLE中。变量self.Image_num定义了读取图片的次数,self.R、self.G、 self.B为三个颜色通道的强度增益系数。
def PrepParameters(self): self.RecordFlag=0 self.RecordPath='D:/Python/PyQt/' self.FilePathLE.setText(self.RecordPath) self.Image_num=0 self.R=1 self.G=1 self.B=1 self.ExpTimeSld.setValue(self.camera.get(15)) self.SetExposure() self.GainSld.setValue(self.camera.get(14)) self.SetGain() self.BrightSld.setValue(self.camera.get(10)) self.SetBrightness() self.ContrastSld.setValue(self.camera.get(11)) self.SetContrast() self.MsgTE.clear()
后面的内容用来初始化摄像头参数控件的值,即读取摄像头的曝光、增益、亮度、对比度等参数,并将这些值显示在相应的控件上。摄像头参数读取函数为self.camera.get(),括号中的不同序号代表不同的参数,具体的对应关系可见链接cvGetCaptureProperty。
4、控件回调函数
CallBackFunctions函数的代码内容如下所示,它定义了每一个功能控件的触发条件和相应的回调函数。通常来讲,button的触发条件为clicked,即鼠标单击按钮后调用相应的函数;checkbox的触发条件为stateChanged,即单击使其状态发生变化后调用相应函数;slider的触发条件可选择valueChanged、sliderRressed、sliderReleased等,可以根据需要选择触发条件。当然,各个回调函数需要我们后面再分别编写。
def CallBackFunctions(self): self.FilePathBt.clicked.connect(self.SetFilePath) self.ShowBt.clicked.connect(self.StartCamera) self.StopBt.clicked.connect(self.StopCamera) self.RecordBt.clicked.connect(self.RecordCamera) self.ExitBt.clicked.connect(self.ExitApp) self.GrayImgCkB.stateChanged.connect(self.SetGray) self.ExpTimeSld.valueChanged.connect(self.SetExposure) self.GainSld.valueChanged.connect(self.SetGain) self.BrightSld.valueChanged.connect(self.SetBrightness) self.ContrastSld.valueChanged.connect(self.SetContrast) self.RedColorSld.valueChanged.connect(self.SetR) self.GreenColorSld.valueChanged.connect(self.SetG) self.BlueColorSld.valueChanged.connect(self.SetB)
上面代码中,我们一共调用了13个回调函数,程序功能的具体实现的主要通过这些函数来实现,下一节我们将继续介绍这些函数的具体内容。
- PyQt5+QtDesigner编写摄像头界面程序(五)——用pyinstaller将py文件打包成exe
- PyQt5+QtDesigner编写摄像头界面程序(四)——用OpenCV和time读取和设置摄像头
- Qt 不使用Qt Designer纯代码编写界面程序(初学者)总结
- PYQT5+python3.6+QT编写一个带ui的加密解密小程序<凯撒加密><维吉尼亚加密><仿射加密><培根加密>
- 使用PyQT编写界面程序
- 用QTDesigner编写Linux的图形界面程序
- pyqt5 第二个程序——编写编辑fruit简单界面
- python+QT designer 做图形化界面EXE程序
- [PyQt]使用Qt Designer设计师完成PyQt界面图标设计
- VS编写Qt界面程序如何不出现控制台
- Linux下QT图形界面开发 用快速开发工具Qt Designer编写Qt程序(2)
- Python2.7+PyQt4 QtDesigner学习笔记系列——3:QtDesigner第一个小程序
- [1]PyQt学习01-Qt Designer生成的界面UI代码分析
- 在QT下编写带DLL的程序(二)
- Qt程序国际化工具使用和相关代码编写规范
- Qt编写Mplayer前端程序
- QT编写DLL给外部程序调用,提供VC/C#/C调用示例(含事件)good
- Qt实用技巧:在Qt Gui程序中嵌入qml界面(可动态覆盖整个窗口)
- QT编写Windows开机启动程序
- Qt Designer 的插件的编写