button能够说是Qt中与用户交互最基本的控件,最简单的就是单击:python
#初始化一个button控件 self.button_inputData = QtWidgets.QPushButton(self.widget) #设置按钮上文本字体 font = QtGui.QFont() font.setPointSize(20) font.setBold(False) font.setWeight(50) self.button_inputData.setFont(font) #设置控件名 self.button_inputData.setObjectName("button_inputData") #设置按钮上显示的文本 self.button_inputData.setText('这是button显示的内容') #设置信号-槽的链接,当用户点击该按钮后调用槽函数,参数为函数名 self.button_inputData.clicked.connect(self.button_inputData_clicked_Event)
QToolButton类的按钮是专门为设计工具栏按钮提供的类,能够设置成单击第一次时按钮按下,触发clicked信号,并保持按下状态,直到用户再次点击此按钮,触发clicked信号,并弹起按钮,在程序运行期间任什么时候候均可检测按钮的“按下/弹起”状态。git
设置setCheckable(True)和setAutoExclusive(True)后按钮可保持按下状态,且状态可查询:
self.button.setCheckable(True)
self.button.setAutoExclusive(True)
查询按钮是按下仍是弹起的方法是:
self.button_openCamera.isChecked()
按钮按下返回值是True,按钮弹起返回值是False。github
应用代码以下:web
#QToolButton的初始化设置 self.button_openCamera = QtWidgets.QToolButton(win_recogFaceInVideo) self.button_openCamera.setGeometry(QtCore.QRect(695, 15, 114, 32)) font = QtGui.QFont() font.setPointSize(13) self.button_openCamera.setFont(font) self.button_openCamera.setCheckable(True) self.button_openCamera.setAutoExclusive(True) self.button_openCamera.setPopupMode(QtWidgets.QToolButton.InstantPopup) self.button_openCamera.setObjectName("button_openCamera") #设置setCheckable(True)和setAutoExclusive(True)后按钮可保持按下状态,且状态可查询 self.button_openCamera.setCheckable(True) self.button_openCamera.setAutoExclusive(True) #设置单击信号的槽函数 self.button_openCamera.clicked.connect(self.recog_in_camera) #clicked槽函数中能够获取按钮“按下/弹起”的状态 def recog_in_camera(self): #若是按钮是按下状态,则执行下面的操做 if self.button_openCamera.isChecked(): #更改此按钮button_openCamera的文本信息 self.button_openCamera.setText('关闭摄像头') #设置另外一个按钮button_openVideoFile不可操做 self.button_openVideoFile.setEnabled(False) else: #若按钮是弹起状态,则更改此按钮的文本信息 self.button_openCamera.setText('打开摄像头')
label显示文字是空间最基本的用法了,以下:app
#初始化一个label控件,参数是父类,也就是承载这个控件的窗口win_recogFaceInVideo self.label = QtWidgets.QLabel(win_recogFaceInVideo) #设置控件大小和位置:宽20,高65,左上角坐标(781,406) self.label.setGeometry(QtCore.QRect(20, 65, 781, 406)) #设置文本字体信息 font = QtGui.QFont() font.setPointSize(30) font.setBold(False) font.setWeight(50) font.setKerning(True) self.label.setFont(font) self.label.setTextFormat(QtCore.Qt.RichText) #缩放对齐:不缩放、居中对齐 self.label.setScaledContents(False) self.label.setAlignment(QtCore.Qt.AlignCenter) #控件名 self.label.setObjectName("label") #文本内容 self.label.setText('这是label显示的内容')
先给出个示例,实如今label控件中按原比例居中显示图片文件。
代码以下:ide
def show_img_in_lable_center( label, fname): #label表示要用来显示图片的那个标签~ #fname表示事先获取到的要打开的图片文件名(含路径),可用QtWidgets.QFileDialog.getOpenFileName()获取哈~ pix_map = QPixmap(fname) img_w = pix_map.width() img_h = pix_map.height() lab_w = label.width() lab_h = label.height() if (img_w > lab_w) | (img_h > lab_h): #若图片宽高大于label宽高,则在label居中显示按图片原始比例缩放后的图片 w_rate = float(img_w) / float(lab_w) h_rate = float(img_h) / float(lab_h) if w_rate >= h_rate: w = lab_w h = int(img_h / w_rate) else: w = int(img_w / h_rate) h = lab_h else: #若图片宽高都小于label宽高,则按图片原始大小显示 w = img_w h = img_h label.setPixmap(pix_map.scaled(w, h))
label显示视频的问题实际就是label定时显示图片,只须要引入一个定时和加入截取视频画面的过程。
网上找到的C++的代码:svg
VideoCapture capture;//声明视频读入类 capture.open(0);//从摄像头读入视频 0表示从摄像头读入 if (!capture.isOpened())//先判断是否打开摄像头 { cout<<"can not open"; cin.get(); return -1; } namedWindow(name); while (1) { Mat cap;//定义一个Mat变量,用于存储每一帧的图像 capture>>cap;//读取当前帧 if (!cap.empty())//判断当前帧是否捕捉成功 **这步很重要 imshow(name, cap);//若当前帧捕捉成功,显示 else cout<<"can not "; waitKey(30);//延时30毫秒 } return 0;
本身写的定时处理视频帧而后显示在label中的代码比较复杂,思路是同样的,详情参考: win_recogFaceInVideo.py。
须要注意:cv2处理图像数据的格式是bgr格式,所以必须注意格式转换。
主要代码以下:函数
# -*- coding: utf-8 -*- # 识别视频中人脸 import face_recognition import cv2 from ui_win_recogFaceInVideo import Ui_win_recogFaceInVideo from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtCore import QTimer import sys import myLib, face_recog from face_recog import * class Win_RecogFaceInVideo(QWidget, Ui_win_recogFaceInVideo): def __init__(self, parent=None ): super(Win_RecogFaceInVideo, self).__init__(parent) self.setupUi(self) ... #创建信号槽链接,点击button_openCamera按钮,启动摄像头,画面显示在label中 self.button_openCamera.clicked.connect(self.recog_in_camera) #创建信号槽链接,点击button_openVideoFile按钮,读取视频文件显示在label中 self.button_openVideoFile.clicked.connect(self.open_video_file) #以上均可以不关心=================================================== #省略无关代码若干=================================================== video_capture = [] def open_video_file(self): ... fname, _ = myLib.loadFile(self,'video')#加载视频文件名,不重要 ... ###==============这里才是重点==============### #初始化读取视频帧的Capture self.video_capture = cv2.VideoCapture(fname) #启动定时器,设置好超时的槽函数,超时时间10ms self.timer_camera = QTimer() self.timer_camera.start(10) self.timer_camera.timeout.connect(self.play1pic) # 链接槽函数 def recog_in_camera(self): if self.button_openCamera.isChecked():#判断是否须要关闭摄像头 #初始化抓取摄像头画面的Capture self.video_capture = cv2.VideoCapture(0) #启动定时器,设置好超时的槽函数,超时时间10ms self.timer_camera = QTimer() self.timer_camera.start(10) # 1000ms == 1s self.timer_camera.timeout.connect(self.play1pic) # 链接槽函数 else: self.close_camera() #关闭摄像头的方法 def close_camera(self): #释放摄像头抓取器 self.video_capture.release() #中止定时器 self.timer_camera.stop() #这是重点->>在label中显示一帧画面的方法play1pic() def play1pic(self): #抓取一帧画面:bgr格式的 ret, frame = self.video_capture.read() if ret:#若是抓取成功,才继续画面处理和显示的操做 #face_recog.recog_in()是根据一帧bgr数据进行人脸识别,并处理画面后,将数据转换成QImage格式后返回的过程,详细在下面 Qimg = face_recog.recog_in(frame, update_features=False, frame_type='bgr', scale_rate=4.0) #将处理事后返回的QImage数据居中的显示在label中, #注意QPixmap.fromImage()方法将QImage数据又转成了QPixmap的格式 #label中只能显示QPixmap格式的图像哈~ myLib.show_img_in_lable_center(self.label,QPixmap.fromImage(Qimg)) else:#若是抓取失败,说明视频文件读完了,或者摄像头故障?,中止抓取 #释放抓取器 self.video_capture.release() #中止定时器 self.timer_camera.stop() #补充两个跟label中显示视频有关的两个函数定义,部分操做与此话题有关,无关部分删去了: def recog_in( frame ,frame_type = 'rgb' ): #预处理,准备好rgb和bgr格式的帧数据 if frame_type == "rgb": rgb_frame= frame bgr_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) #cv2处理图像须要bgr格式 else: rgb_frame = cv2.cvtColor(frame2, cv2.COLOR_BGR2RGB) bgr_frame = frame ###此处省略图像处理代码若干=====emm..不少行 #总之最终要将cv2抓到的数据或者处理过的数据显示出来,这些数据都是bgr格式的 #因此要转成rgb格式的,cv2.cvtColor转出来的数据是np格式的RGB数据 rgb_npImg = cv2.cvtColor(bgr_frame, cv2.COLOR_BGR2RGB) #而后经过QImage把np数据转成QImage格式的 #参数分别是:np数据,图像宽,图像高,图像存储宽(单位byte,R/G/B各一字节,因此是宽乘三),最后一个是数据格式 Qimg = QImage(rgb_npImg[:], rgb_npImg.shape[1], rgb_npImg.shape[0], rgb_npImg.shape[1] * 3, QImage.Format_RGB888) #返回转出来的QImage数据 return Qimg #在指定标签中居中显示指定图像文件 def show_img_in_lable_center( label, pix_map): #如下是计算要居中显示宽高比跟label不同的画面时,显示数据的实际宽高应该是多少 #不重要 img_w = pix_map.width() img_h = pix_map.height() lab_w = label.width() lab_h = label.height() if (img_w > lab_w) | (img_h > lab_h): w_rate = float(img_w) / float(lab_w) h_rate = float(img_h) / float(lab_h) if w_rate >= h_rate: w = lab_w h = int(img_h / w_rate) else: w = int(img_w / h_rate) h = lab_h else: w = img_w h = img_h #下面才是重点,用label.setPixmap()显示出来 #在label中显示缩放后pix_map数据的画面 label.setPixmap(pix_map.scaled(w, h))
QtWidgets提供有相似“打开文件对话”框的类:QFileDialog,用来供用户选择文件或文件夹,获取文件/文件夹路径。工具
单个文件打开 QtWidgets.QFileDialog.getOpenFileName()
多个文件打开 QtWidgets.QFileDialog.getOpenFileNames()
文件夹选取 QtWidgets.QFileDialog.getExistingDirectory()
文件保存 QtWidgets.QFileDialog.getSaveFileName()
重点介绍QFileDialog.getOpenFileName()吧,后面几个的参数相似:字体
为了说明QFileDialog.getOpenFileName函数的用法,先把C++版的QFileDialog::getOpenFileName()的声明放这,便于理解参数类型,使用的时候自行对应到python的格式就好啦:
QString QFileDialog::getOpenFileName ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, Options options = 0 )
参数
第一个参数parent
:用于指定父组件。注意,不少Qt组件的构造函数都会有这么一个parent参数,并提供一个默认值0;这里要把调用资源管理器的Qt类传进去哈~若是是在类定义里调用的就传个self
进去就行。
第二个参数caption
:是对话框的标题;也就是将会显示在对话框上的标题,自行定义,string就行~
第三个参数dir
:是对话框显示时默认打开的目录:.
表明程序运行目录,/
表明当前盘符的根目录(Windows,Linux下/就是根目录了),也能够是平台相关的,好比"C:\“等;例如我想打开程序运行目录下的Data文件夹做为默认打开路径,这里应该写成”./Data/",若想有一个默认选中的文件,则在目录后添加文件名便可:"./Data/teaser.graph"
第四个参数filter
:是对话框的后缀名过滤器;好比咱们使用Image Files(*.jpg *.png)
就让它只能显示后缀名是jpg或者png的文件。若是须要使用多个过滤器,使用;;
分割,好比JPEG Files(*.jpg);;PNG Files(*.png)
;
第五个参数selectedFilter
,是默认选择的过滤器;
第六个参数options
,是对话框的一些参数设定,好比只显示文件夹等等,它的取值是enum QFileDialog::Option
,每一个选项可使用|
运算组合起来。
若是我要想选择多个文件就直接使用Qt提供的getOpenFileNames()
函数咯,其返回值是一个QStringList。能够理解成一个只能存放QString的List。
实际使用中第五、6个参数我没用到,给个python中运用的实例:
from PyQt5 import QtCore, QtGui, QtWidgets from ui_win_inputData import Ui_win_inputData #ui_win_inputData是用QtDesigner画的一个窗口界面文件生成的python文件,界面里有个名字叫button_choosePic的按钮 class Win_InputData(QWidget, Ui_win_inputData): def __init__(self, parent=None): super(Win_InputData, self).__init__(parent) self.setupUi(self) self.button_choosePic.clicked.connect(self.choosePic) def choosePic(self): fname, _ = QtWidgets.QFileDialog.getOpenFileName(self ,#第一个参数,父类 '选择图片文件', #第二个参数,对话框的标题 '/Users/tanyashi/Pictures', #对话框显示时默认打开的目录 'Image files(*.jpg *.gif *.jpeg *.png)') #对话框的后缀名过滤器 #fname就是用户选择好的文件的文件名(含路径),后面就根据需求自行打开这个文件咯~ #============================================== #再看看另外几个相似的方法使用: #从程序运行的路径开始,让用户选择一个文件夹路径 directory1 = QFileDialog.getExistingDirectory(self,"选取文件夹","./") print(directory1) #---------------------------------------------- #从程序运行的路径开始,让用户选择一个全部类型或.txt格式的文件 fileName1, filetype = QFileDialog.getOpenFileName(self,"选取文件","./","All Files (*);;Text Files (*.txt)") #设置文件扩展名过滤,注意用双分号间隔 print(fileName1,filetype) #---------------------------------------------- #从"./"开始,容许用户选择多个文件 files, ok1 = QFileDialog.getOpenFileNames(self,"多文件选择","./","All Files (*);;Text Files (*.txt)") print(files,ok1) #files是一个list,元素是文件名(含路径)的字符串 #---------------------------------------------- #从"./"开始,让用户选择一个用来保存文件的文件名(含路径) fileName2, ok2 = QFileDialog.getSaveFileName(self,"文件保存","./","All Files (*);;Text Files (*.txt)")
本例给出了三种窗口打开的模板。其中主界面打开主界面的方式比较实用,可理解后做为通用模板。
本例来自pyqt5 主界面打开新主界面的实现模板,感谢分享!
import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * ################################################ #######建立主窗口 ################################################ class FirstMainWindow(QMainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('主界面') ###### 建立界面 ###### self.centralwidget = QWidget() self.setCentralWidget(self.centralwidget) self.Layout = QVBoxLayout(self.centralwidget) # 设置顶部三个按钮 self.topwidget = QWidget() self.Layout.addWidget(self.topwidget) self.buttonLayout = QHBoxLayout(self.topwidget) self.pushButton1 = QPushButton() self.pushButton1.setText("打开主界面") self.buttonLayout.addWidget(self.pushButton1) self.pushButton2 = QPushButton() self.pushButton2.setText("打开对话框") self.buttonLayout.addWidget(self.pushButton2) self.pushButton3 = QPushButton() self.pushButton3.setText("打开提示框") self.buttonLayout.addWidget(self.pushButton3) # 设置中间文本 self.label = QLabel() self.label.setText("第一个主界面") self.label.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self.label.setAlignment(Qt.AlignCenter) self.label.setFont(QFont("Roman times", 50, QFont.Bold)) self.Layout.addWidget(self.label) # 设置状态栏 self.statusBar().showMessage("当前用户:一心狮") # 窗口最大化 self.showMaximized() ###### 三个按钮事件 ###### self.pushButton1.clicked.connect(self.on_pushButton1_clicked) self.pushButton2.clicked.connect(self.on_pushButton2_clicked) self.pushButton3.clicked.connect(self.on_pushButton3_clicked) # 按钮一:打开主界面 windowList = [] def on_pushButton1_clicked(self): the_window =SecondWindow() self.windowList.append(the_window) ##注:没有这句,是不打开另外一个主界面的! self.close() the_window.show() # 按钮二:打开对话框 def on_pushButton2_clicked(self): the_dialog = TestdemoDialog() if the_dialog.exec_() == QDialog.Accepted: pass # 按钮三:打开提示框 def on_pushButton3_clicked(self): QMessageBox.information(self, "提示", "这是information框!") #QMessageBox.question(self, "提示", "这是question框!") #QMessageBox.warning(self, "提示", "这是warning框!") #QMessageBox.about(self, "提示", "这是about框!") ################################################ #######第二个主界面 ################################################ class SecondWindow(QMainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('第二主界面') # 设置中间文本 self.label = QLabel() self.label.setText("第二个主界面") self.label.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self.label.setAlignment(Qt.AlignCenter) self.label.setFont(QFont("Roman times", 50, QFont.Bold)) self.setCentralWidget(self.label) # 设置状态栏 self.statusBar().showMessage("当前用户:一心狮") # 窗口最大化 self.showMaximized() ###### 重写关闭事件,回到第一界面 windowList = [] def closeEvent(self, event): the_window = FirstMainWindow() self.windowList.append(the_window) ##注:没有这句,是不打开另外一个主界面的! the_window.show() event.accept() ################################################ #######对话框 ################################################ class TestdemoDialog(QDialog): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('对话框') ### 设置对话框类型 self.setWindowFlags(Qt.Tool) ################################################ #######程序入口 ################################################ if __name__ == "__main__": app = QApplication(sys.argv) the_mainwindow = FirstMainWindow() the_mainwindow.show() sys.exit(app.exec_())