def openCamera(self): if self.databaseConnection is None: QMessageBox(QMessageBox.Warning, '警告', '请先连接到数据库').exec_() return chooseOrgWidget = ChooseOrgWidget(self.databaseConnection, self) chooseOrgWidget.exec_() if self.organization == "": QMessageBox(QMessageBox.Warning, '警告', '未选择组织,请重新选择').exec_() return # 将摄像头部件附加到主界面上 self.cameraWidget = CameraWidget(self.cameraView) # 设置摄像头获取到图像后的回调函数 self.cameraWidget.setonGetFrameFunc(self.onGetFrameFunc) # 设置摄像头图像显示前的回调函数 self.cameraWidget.setBeforeDisplayFrame(self.beforeDisplayFrame) self.openCameraBtn.hide() # 开启开始检测人脸的标志 self.start_detect = True
class GetDataDialog(QDialog): def __init__(self, userName, parent=None): super(GetDataDialog, self).__init__(parent) self.userName = userName self.picturesLeft = 5 self.cameraDevice = CameraDevice() self.cameraWidget = CameraWidget(self.cameraDevice, self) self.mainLayout = QVBoxLayout(self) self.mainLayout.addWidget(self.cameraWidget) self.setLayout(self.mainLayout) self.getPictureButton = QPushButton("Zrób zdjęcie", self) self.getPictureButton.clicked.connect(self.pictureButtonClicked) self.picturesLeftLabel = QLabel("Pozostało zdjęć: {}".format(self.picturesLeft), self) self.secondLayout = QHBoxLayout(self) self.secondLayout.addWidget(self.getPictureButton) self.secondLayout.addWidget(self.picturesLeftLabel) self.mainLayout.addLayout(self.secondLayout) self.checkUserName() @pyqtSlot() def pictureButtonClicked(self): if self.picturesLeft == 0: self.close() frame = self.cameraWidget.getFaceRectangle() if frame is not None: frame.save("./dane/{}/{}.bmp".format(self.userName, self.picturesLeft)) self.picturesLeft -= 1 self.picturesLeftLabel.setText("Pozostało zdjęć: {}".format(self.picturesLeft)) if self.picturesLeft == 0: self.getPictureButton.setText("Zamknij") def checkUserName(self): self.picturesLeft = 0 if os.path.exists("./dane/{}".format(self.userName)) else 5 if self.picturesLeft == 0: self.getPictureButton.setDisabled(True) if self.picturesLeft == 5: os.makedirs("./dane/{}".format(self.userName))
def __init__(self, userName, parent=None): super(GetDataDialog, self).__init__(parent) self.userName = userName self.picturesLeft = 5 self.cameraDevice = CameraDevice() self.cameraWidget = CameraWidget(self.cameraDevice, self) self.mainLayout = QVBoxLayout(self) self.mainLayout.addWidget(self.cameraWidget) self.setLayout(self.mainLayout) self.getPictureButton = QPushButton("Zrób zdjęcie", self) self.getPictureButton.clicked.connect(self.pictureButtonClicked) self.picturesLeftLabel = QLabel("Pozostało zdjęć: {}".format(self.picturesLeft), self) self.secondLayout = QHBoxLayout(self) self.secondLayout.addWidget(self.getPictureButton) self.secondLayout.addWidget(self.picturesLeftLabel) self.mainLayout.addLayout(self.secondLayout) self.checkUserName()
def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(1592, 552) self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog) self.verticalLayout_2.setObjectName("verticalLayout_2") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.verticalLayout_3 = QtWidgets.QVBoxLayout() self.verticalLayout_3.setObjectName("verticalLayout_3") self.horizontalLayout_6 = QtWidgets.QHBoxLayout() self.horizontalLayout_6.setObjectName("horizontalLayout_6") self.frame = QtWidgets.QFrame(Dialog) self.frame.setMinimumSize(QtCore.QSize(640, 480)) self.frame.setMaximumSize(QtCore.QSize(640, 480)) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.videoLive = CameraWidget(self.frame) self.videoLive.setGeometry(QtCore.QRect(0, 0, 640, 480)) self.videoLive.setMinimumSize(QtCore.QSize(640, 480)) self.videoLive.setMaximumSize(QtCore.QSize(640, 480)) self.videoLive.setObjectName("videoLive") self.horizontalLayout_6.addWidget(self.frame) self.frame_2 = QtWidgets.QFrame(Dialog) self.frame_2.setMinimumSize(QtCore.QSize(640, 480)) self.frame_2.setMaximumSize(QtCore.QSize(640, 480)) self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_2.setObjectName("frame_2") self.videoFiltered = CameraWidget(self.frame_2) self.videoFiltered.setGeometry(QtCore.QRect(0, 0, 640, 480)) self.videoFiltered.setMinimumSize(QtCore.QSize(640, 480)) self.videoFiltered.setMaximumSize(QtCore.QSize(640, 480)) self.videoFiltered.setObjectName("videoFiltered") self.horizontalLayout_6.addWidget(self.frame_2) self.verticalLayout_3.addLayout(self.horizontalLayout_6) self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.label_Status = QtWidgets.QLabel(Dialog) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.label_Status.sizePolicy().hasHeightForWidth()) self.label_Status.setSizePolicy(sizePolicy) self.label_Status.setObjectName("label_Status") self.horizontalLayout_2.addWidget(self.label_Status) self.btnShowHist = QtWidgets.QPushButton(Dialog) self.btnShowHist.setObjectName("btnShowHist") self.horizontalLayout_2.addWidget(self.btnShowHist) self.pushButton_2 = QtWidgets.QPushButton(Dialog) self.pushButton_2.setObjectName("pushButton_2") self.horizontalLayout_2.addWidget(self.pushButton_2) self.verticalLayout_3.addLayout(self.horizontalLayout_2) self.horizontalLayout.addLayout(self.verticalLayout_3) self.filterList = QtWidgets.QListWidget(Dialog) self.filterList.setObjectName("filterList") self.horizontalLayout.addWidget(self.filterList) self.horizontalLayout.setStretch(0, 1) self.verticalLayout_2.addLayout(self.horizontalLayout) self.retranslateUi(Dialog) QtCore.QMetaObject.connectSlotsByName(Dialog)
def __init__(self): super(MainWindow, self).__init__() # noinspection PyCallingNonCallable self._nao = Nao() self._actionQueue = ActionModel(self, self._nao) self._LEDTime = QtCore.QTime.currentTime() Study.setup() #======================================================================= # Create Menus #======================================================================= menubar = self.menuBar() #-----------------------------File Menu---------------------------------# actConnect = QtGui.QAction(QtGui.QIcon(), '&Connect', self) actConnect.setShortcut('Ctrl+Alt+C') actConnect.triggered.connect(self.on_actConnect_triggered) actDisconnect = QtGui.QAction(QtGui.QIcon(), '&Disconnect', self) actDisconnect.setShortcut('Ctrl+Alt+D') actDisconnect.triggered.connect(self.on_actDisconnect_triggered) actExit = QtGui.QAction(QtGui.QIcon('images/exit.png'), '&Exit', self) actExit.setShortcut('Ctrl+Alt+X') actExit.setStatusTip('Exit application') actExit.triggered.connect(self.close) fileMenu = menubar.addMenu('File') fileMenu.addAction(actConnect) fileMenu.addAction(actDisconnect) fileMenu.addAction(actExit) #-----------------------------Load Menu---------------------------------# loadMenu = menubar.addMenu('Load') self._loadActions = [] for i in range(len(Study.TASKS)): actLoad = QtGui.QAction(QtGui.QIcon(), "Load " + Study.TASKS[i][Study.TASK_NAME], self) actLoad.setShortcut("Ctrl+Alt+" + str(i + 1)) actLoad.triggered.connect(self.on_actLoad_specific) loadMenu.addAction(actLoad) self._loadActions.append(actLoad) # END for #---------------------------Help Menu---------------------------------# actAboutBox = QtGui.QAction(QtGui.QIcon(), '&About', self) actAboutBox.triggered.connect(self.on_actAbout_triggered) actAboutBox.setShortcut("Ctrl+Alt+H") helpMenu = menubar.addMenu('Help') helpMenu.addAction(actAboutBox) #======================================================================= # Create Widgets #======================================================================= self._wgtMain = QtGui.QWidget(self) splitter = QtGui.QSplitter(self._wgtMain) splitter.setOrientation(QtCore.Qt.Horizontal) wgtLeft = QtGui.QWidget(splitter) wgtLeft.setMinimumWidth(350) splitterLeft = QtGui.QSplitter(wgtLeft) splitterLeft.setOrientation(QtCore.Qt.Vertical) self._wgtTimer = TimerWidget(splitterLeft) self._wgtCamera = CameraWidget(splitterLeft, self._nao.getCamera()) self._wgtCamera.setMinimumHeight(385) self._wgtCamera.cameraChanged.connect(self._nao.getCamera().setCameraSource) self._wgtCamera.moveHead.connect(self.on__wgtCamera_moveHead) self._wgtActionList = ActionListWidget(splitterLeft, self._actionQueue) self._wgtActionList.setMinimumHeight(120) self._wgtActionList.editClicked.connect(self.on__wgtActionList_editClicked) layoutLeft = QtGui.QHBoxLayout(wgtLeft) layoutLeft.setMargin(0) layoutLeft.addWidget(splitterLeft) wgtRight = QtGui.QWidget(splitter) wgtRight.setMinimumWidth(380) splitterRight = QtGui.QSplitter(wgtRight) splitterRight.setOrientation(QtCore.Qt.Vertical) self._wgtTaskPanel = QtGui.QWidget(splitterRight) self._wgtTaskPanel.setMinimumHeight(400) self._layoutTaskPanel = QtGui.QStackedLayout(self._wgtTaskPanel) self._layoutTaskPanel.setMargin(0) for i in range(len(Study.TASKS)): Study.TASKS[i][Study.TASK_WIDGET].setParent(self._wgtTaskPanel) Study.TASKS[i][Study.TASK_WIDGET].setActionQueue(self._actionQueue) Study.TASKS[i][Study.TASK_WIDGET].setNao(self._nao) self._layoutTaskPanel.addWidget(Study.TASKS[i][Study.TASK_WIDGET]) # END for widgetTextStiff = QtGui.QWidget(splitterRight) widgetTextStiff.setMinimumHeight(160) self._wgtSpeech = SpeechWidget(splitterRight) self._wgtSpeech.setInputFocus() self._wgtSpeech.inputCancelled.connect(self.setFocus) self._wgtSpeech.textSubmitted.connect(self.on__wgtSpeech_playSpeech) self._wgtSpeech.volumeChanged.connect(self._nao.setVolume) self._wgtMovement = MovementWidget(splitterRight) self._wgtMovement.setActionQueue(self._actionQueue) self._wgtMovement.setNao(self._nao) layoutTextStiff = QtGui.QHBoxLayout(widgetTextStiff) layoutTextStiff.setMargin(0) layoutTextStiff.addWidget(self._wgtSpeech) layoutTextStiff.addWidget(self._wgtMovement) layoutRight = QtGui.QHBoxLayout(wgtRight) layoutRight.setMargin(0) layoutRight.addWidget(splitterRight) layoutMain = QtGui.QHBoxLayout(self._wgtMain) layoutMain.addWidget(splitter) ################################################## # MainWindow ################################################## self.installEventFilter(self) self.setCentralWidget(self._wgtMain) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.setMinimumSize(800, 600) self.setWindowIcon(QtGui.QIcon("images/icon.png")) self.setWindowTitle('NAO Robotic Controller') self.resize(1024, 768) self.show()
class MainWindow(QtGui.QMainWindow): def __init__(self): super(MainWindow, self).__init__() # noinspection PyCallingNonCallable self._nao = Nao() self._actionQueue = ActionModel(self, self._nao) self._LEDTime = QtCore.QTime.currentTime() Study.setup() #======================================================================= # Create Menus #======================================================================= menubar = self.menuBar() #-----------------------------File Menu---------------------------------# actConnect = QtGui.QAction(QtGui.QIcon(), '&Connect', self) actConnect.setShortcut('Ctrl+Alt+C') actConnect.triggered.connect(self.on_actConnect_triggered) actDisconnect = QtGui.QAction(QtGui.QIcon(), '&Disconnect', self) actDisconnect.setShortcut('Ctrl+Alt+D') actDisconnect.triggered.connect(self.on_actDisconnect_triggered) actExit = QtGui.QAction(QtGui.QIcon('images/exit.png'), '&Exit', self) actExit.setShortcut('Ctrl+Alt+X') actExit.setStatusTip('Exit application') actExit.triggered.connect(self.close) fileMenu = menubar.addMenu('File') fileMenu.addAction(actConnect) fileMenu.addAction(actDisconnect) fileMenu.addAction(actExit) #-----------------------------Load Menu---------------------------------# loadMenu = menubar.addMenu('Load') self._loadActions = [] for i in range(len(Study.TASKS)): actLoad = QtGui.QAction(QtGui.QIcon(), "Load " + Study.TASKS[i][Study.TASK_NAME], self) actLoad.setShortcut("Ctrl+Alt+" + str(i + 1)) actLoad.triggered.connect(self.on_actLoad_specific) loadMenu.addAction(actLoad) self._loadActions.append(actLoad) # END for #---------------------------Help Menu---------------------------------# actAboutBox = QtGui.QAction(QtGui.QIcon(), '&About', self) actAboutBox.triggered.connect(self.on_actAbout_triggered) actAboutBox.setShortcut("Ctrl+Alt+H") helpMenu = menubar.addMenu('Help') helpMenu.addAction(actAboutBox) #======================================================================= # Create Widgets #======================================================================= self._wgtMain = QtGui.QWidget(self) splitter = QtGui.QSplitter(self._wgtMain) splitter.setOrientation(QtCore.Qt.Horizontal) wgtLeft = QtGui.QWidget(splitter) wgtLeft.setMinimumWidth(350) splitterLeft = QtGui.QSplitter(wgtLeft) splitterLeft.setOrientation(QtCore.Qt.Vertical) self._wgtTimer = TimerWidget(splitterLeft) self._wgtCamera = CameraWidget(splitterLeft, self._nao.getCamera()) self._wgtCamera.setMinimumHeight(385) self._wgtCamera.cameraChanged.connect(self._nao.getCamera().setCameraSource) self._wgtCamera.moveHead.connect(self.on__wgtCamera_moveHead) self._wgtActionList = ActionListWidget(splitterLeft, self._actionQueue) self._wgtActionList.setMinimumHeight(120) self._wgtActionList.editClicked.connect(self.on__wgtActionList_editClicked) layoutLeft = QtGui.QHBoxLayout(wgtLeft) layoutLeft.setMargin(0) layoutLeft.addWidget(splitterLeft) wgtRight = QtGui.QWidget(splitter) wgtRight.setMinimumWidth(380) splitterRight = QtGui.QSplitter(wgtRight) splitterRight.setOrientation(QtCore.Qt.Vertical) self._wgtTaskPanel = QtGui.QWidget(splitterRight) self._wgtTaskPanel.setMinimumHeight(400) self._layoutTaskPanel = QtGui.QStackedLayout(self._wgtTaskPanel) self._layoutTaskPanel.setMargin(0) for i in range(len(Study.TASKS)): Study.TASKS[i][Study.TASK_WIDGET].setParent(self._wgtTaskPanel) Study.TASKS[i][Study.TASK_WIDGET].setActionQueue(self._actionQueue) Study.TASKS[i][Study.TASK_WIDGET].setNao(self._nao) self._layoutTaskPanel.addWidget(Study.TASKS[i][Study.TASK_WIDGET]) # END for widgetTextStiff = QtGui.QWidget(splitterRight) widgetTextStiff.setMinimumHeight(160) self._wgtSpeech = SpeechWidget(splitterRight) self._wgtSpeech.setInputFocus() self._wgtSpeech.inputCancelled.connect(self.setFocus) self._wgtSpeech.textSubmitted.connect(self.on__wgtSpeech_playSpeech) self._wgtSpeech.volumeChanged.connect(self._nao.setVolume) self._wgtMovement = MovementWidget(splitterRight) self._wgtMovement.setActionQueue(self._actionQueue) self._wgtMovement.setNao(self._nao) layoutTextStiff = QtGui.QHBoxLayout(widgetTextStiff) layoutTextStiff.setMargin(0) layoutTextStiff.addWidget(self._wgtSpeech) layoutTextStiff.addWidget(self._wgtMovement) layoutRight = QtGui.QHBoxLayout(wgtRight) layoutRight.setMargin(0) layoutRight.addWidget(splitterRight) layoutMain = QtGui.QHBoxLayout(self._wgtMain) layoutMain.addWidget(splitter) ################################################## # MainWindow ################################################## self.installEventFilter(self) self.setCentralWidget(self._wgtMain) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.setMinimumSize(800, 600) self.setWindowIcon(QtGui.QIcon("images/icon.png")) self.setWindowTitle('NAO Robotic Controller') self.resize(1024, 768) self.show() # END __init__() def on_actConnect_triggered(self): if not self._nao.isConnected(): self._dlgConnect = ConnectDialog(self) self._dlgConnect.accepted.connect(self.on__dlgConnect_accepted) self._dlgConnect.show() # END if # END on_actConnect_triggered() def on_actDisconnect_triggered(self): if self._nao.isConnected(): self.killTimer(self._timerID) print "===================================" print "Disconnecting from Nao" self._nao.disconnect() print "===================================" self._wgtCamera.setDefaultImage() # END if # END on_actDisconnect_triggered() # noinspection PyUnusedLocal def on_actLoad_specific(self, studyShortName): for i in range(len(self._loadActions)): if self._loadActions[i] == self.sender(): self._layoutTaskPanel.setCurrentIndex(i) return # END if # END for # END on_actLoad_specific def on_actAbout_triggered(self): dlgAbout = AboutWindow(self) dlgAbout.show() # END on_actAbout_triggered() def on__dlgConnect_accepted(self): if not self._nao.isConnected(): ipAddress = str(self._dlgConnect.ipAddress) port = str(self._dlgConnect.port) camIpAddr = str(self._dlgConnect.camIpAddr) camPort = str(self._dlgConnect.camPort) ttsIpAddr = str(self._dlgConnect.ttsIpAddr) ttsPort = str(self._dlgConnect.ttsPort) print "===================================" print "Connecting to Nao (" + ipAddress + ":" + port + ")" if self._nao.connect(ipAddress, int(port), camIpAddr, int(camPort), ttsIpAddr, int(ttsPort)): self._timerID = self.startTimer(50) else: print "FAILED" # END if print "===================================" self._dlgConnect = None # END if # END on__dlgConnect_accepted() def on__wgtActionList_editClicked(self): QtGui.QMessageBox.information(self, "Information", "Not implemented", QtGui.QMessageBox.Ok, QtGui.QMessageBox.NoButton) # END on__wgtActionList_editClicked() def on__wgtCamera_moveHead(self, direction): if self._nao.isConnected(): if direction == Direction.Up: self._nao.tiltHeadUp() elif direction == Direction.Down: self._nao.tiltHeadDown() elif direction == Direction.Left: self._nao.turnHeadLeft() elif direction == Direction.Right: self._nao.turnHeadRight() #END if #END if # END on__wgtCamera_moveHead() def on__wgtSpeech_playSpeech(self, value): actions = Study.TASKS[self._layoutTaskPanel.currentIndex()][Study.TASK_WIDGET].speech(str(value), self._wgtSpeech.getSpeed(), self._wgtSpeech.getShaping()) if actions is None: actions = Speech(value, speed = self._wgtSpeech.getSpeed(), shaping = self._wgtSpeech.getShaping(), blocking = False) #END if self._actionQueue.addActions(actions) # END on__wgtSpeech_playSpeech() # noinspection PyUnusedLocal def closeEvent(self, event): self._actionQueue.dispose() self.on_actDisconnect_triggered() # END closeEvent() # noinspection PyUnusedLocal def timerEvent(self, event): if self._LEDTime < QtCore.QTime.currentTime(): if self._wgtSpeech.isTextEmpty() and (self._actionQueue.rowCount(None) <= 0 or self._actionQueue.isRunning()): Study.TASKS[self._layoutTaskPanel.currentIndex()][Study.TASK_WIDGET].LEDNormal() else: Study.TASKS[self._layoutTaskPanel.currentIndex()][Study.TASK_WIDGET].LEDActive() # END if self._LEDTime = QtCore.QTime.currentTime().addSecs(1.5)
class EntryWindow(Ui_mainWindow): def __init__(self, MainWindow): super().__init__() self.mainWindow = MainWindow self.image_templates_dir = "./img_templates/" self.setupUi(MainWindow) # 初始化界面各个控件 self.initUI() # 初始化人脸识别模块 self.initFaceDetect() # 初始化定时器,用来更新UI self.timer = QtCore.QTimer(MainWindow) self.timer.timeout.connect(self.updateUI) self.timer.setInterval(15) self.timer.start() # 初始化本项目使用的数据库连接 self.databaseConnection = None self.database_filename = "" # 初始化本次选择的组织 self.organization = "" self.cur_org_id = None # 是否开始识别人脸的标记位 self.start_detect = False self.cameraWidget = None def updateUI(self): """ 定时器回调函数,用于更新UI """ # 更新每次人脸检测耗时的标签 timeCostStr = "耗时为:" + str(int(self.timeCost)) + "ms" self.curTimeCost.setText(timeCostStr) # 更新当前识别出的人的人脸图片和人名和编号 imgViewSize = (self.curUserImg.size().width(), self.curUserImg.size().height()) if len(self.face_names) > 0 and self.face_names[0] != "Unknown": name = self.face_names[0] numbers = self.face_numbers[0] image_file_path = self.image_templates_dir + name + "_" + numbers + ".jpg" image = load_image_file(image_file_path, imgViewSize) pixmap = QImage(image, imgViewSize[0], imgViewSize[1], QImage.Format_RGB888) pixmap = QPixmap.fromImage(pixmap) self.curUserImg.setPixmap(pixmap) # 更新名称和学号标签 if len(self.face_names) != 0 and len(self.face_numbers) != 0: self.curUserName.setText("姓名:" + self.face_names[0]) self.curUserNumber.setText("编号:" + self.face_numbers[0]) else: self.curUserName.setText("姓名:无") self.curUserNumber.setText("编号:无") if self.start_detect: # 将识别出的人加入已签到的列表,并更新UI的listview for i in range(len(self.face_names)): name = self.face_names[i] number = self.face_numbers[i] if name == "Unknown": continue # 如果当前识别出的人脸不在已签到列表里面 name_list = [i.split("\t")[0] for i in self.user_list] if name not in name_list: query_res = query_student_by_number( self.databaseConnection, number) # stu_id = query_res[0][0] stu_number = query_res[0][4] if check_number_in_org(self.databaseConnection, stu_number, self.cur_org_id): # 在listview里面添加已签到的学生,并且在数据库中记录 self.addUser(name, number) # 将当前学生的签到记录插入数据库 student_id = query_student_by_number( self.databaseConnection, number)[0][0] org_id = self.cur_org_id insert_t_record(self.databaseConnection, student_id, org_id) # 更新状态栏显示的内容 if self.databaseConnection is None: self.statusbar.showMessage("数据库未连接") else: self.statusbar.showMessage("数据库已连接:" + self.database_filename) def initFaceDetect(self): """ 初始化人脸识别模块 """ # 加载人脸的模板图片 self.known_face_encodings, self.known_face_tags = load_image_templates( self.image_templates_dir) self.known_face_names = [ tag.split("_")[0] for tag in self.known_face_tags ] self.known_face_numbers = [ tag.split("_")[1] for tag in self.known_face_tags ] self.face_locations = [] self.face_names = [] self.timeCost = 0.0 # 标记位,用来降低人脸检测开销 self.process_this_frame = True def initUI(self): """ 初始化界面的各个控件 """ # 绑定按钮事件 self.openCameraBtn.clicked.connect(self.openCamera) self.recordBtn.clicked.connect(self.manuallyRecord) # 绑定菜单事件 self.openDatabaseMenu.triggered.connect(self.openDataBase) self.closeDatabaseMenu.triggered.connect(self.closeDatabase) self.insertFaceTemplateMenu.triggered.connect(self.createFace) self.newOrganizationMenu.triggered.connect(self.createOrganization) self.editOrganizationMenu.triggered.connect(self.createOrgEdit) self.exportExcelMenu.triggered.connect(self.exportExcel) self.initListView() def exportExcel(self): if self.databaseConnection is None: QMessageBox(QMessageBox.Warning, '警告', '请先连接到数据库').exec_() return self.exportExcelWidget = ExportExcelWidget(self.databaseConnection) def initListView(self): """ 初始化已签到用户的QListView """ self.model = QStringListModel() self.user_list = [] self.model.setStringList(self.user_list) self.userListView.setModel(self.model) def addUser(self, name, number): """ 在已签到的用户的列表里面增加一个人员 """ if name not in self.user_list: self.user_list.append(name + "\t" + number) self.model.setStringList(self.user_list) def openCamera(self): if self.databaseConnection is None: QMessageBox(QMessageBox.Warning, '警告', '请先连接到数据库').exec_() return chooseOrgWidget = ChooseOrgWidget(self.databaseConnection, self) chooseOrgWidget.exec_() if self.organization == "": QMessageBox(QMessageBox.Warning, '警告', '未选择组织,请重新选择').exec_() return # 将摄像头部件附加到主界面上 self.cameraWidget = CameraWidget(self.cameraView) # 设置摄像头获取到图像后的回调函数 self.cameraWidget.setonGetFrameFunc(self.onGetFrameFunc) # 设置摄像头图像显示前的回调函数 self.cameraWidget.setBeforeDisplayFrame(self.beforeDisplayFrame) self.openCameraBtn.hide() # 开启开始检测人脸的标志 self.start_detect = True def manuallyRecord(self): """ 手动录入签到信息 """ if self.databaseConnection is None: QMessageBox(QMessageBox.Warning, '警告', '请先连接到数据库').exec_() return name = self.nameEdit.text() number = self.numberEdit.text() if name.strip() == "": QMessageBox(QMessageBox.Warning, '警告', '姓名或编号不能为空!').exec_() return if number.strip() == "": QMessageBox(QMessageBox.Warning, '警告', '姓名或编号不能为空!').exec_() return if check_number_in_org(self.databaseConnection, number, self.cur_org_id): if name == query_name_by_number(self.databaseConnection, number): self.addUser(name, number) # 录入签到表 student_id = query_id_by_number(self.databaseConnection, number) insert_t_record(self.databaseConnection, student_id, self.cur_org_id) else: QMessageBox(QMessageBox.Warning, '警告', '输入的姓名与学号不符!').exec_() else: QMessageBox(QMessageBox.Warning, '警告', '用户不在当前的组织中!').exec_() def onGetFrameFunc(self, frame): """ 获取到摄像头一帧时调用此函数,在此函数中进行人脸识别 """ small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) cur_frame = cv2.cvtColor(small_frame, cv2.COLOR_BGR2RGB) # 每两帧检测一次,降低开销 if self.process_this_frame: # 记录人脸识别算法的开始时间 begin_time = time.time() self.face_locations, self.face_names, self.face_numbers = detect_frame( cur_frame, self.known_face_encodings, self.known_face_names, self.known_face_numbers, tolerance=0.35) # 记录人脸识别算法的结束时间 end_time = time.time() # 计算算法耗时,并转为毫秒 if len(self.face_locations) != 0: self.timeCost = (end_time - begin_time) * 1000 # print('人脸识别算法运行时间:%.1fms' % self.timeCost) self.process_this_frame = not self.process_this_frame # 不对图像做任何处理,直接返回 return frame def beforeDisplayFrame(self, frame): """ 在显示摄像头的图像前调用此函数对一帧图像进行处理, 返回值为修改过的一帧图像 """ # 绘制人脸的方框 for (top, right, bottom, left), name in zip(self.face_locations, self.face_names): # 之前保存的坐标被缩小了四分之一,现在还原回去 top *= 4 right *= 4 bottom *= 4 left *= 4 cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) return frame def openDataBase(self): """ 打开指定的数据库文件 """ fname = QFileDialog.getOpenFileName(self.mainWindow, '打开数据库', './', "DataBaseFiles (*.db)") if fname[0] == "": return # 创建数据库连接 self.databaseConnection = openDatabase(fname[0]) # 更新状态栏 filename = fname[0].split("/")[-1] self.database_filename = filename def closeDatabase(self): """ 关闭数据库连接 """ if self.cameraWidget != None: self.cameraWidget.close() self.cameraWidget = None self.openCameraBtn.show() closeDataBase(self.databaseConnection) self.databaseConnection = None # 关闭开始检测人脸的标志 self.start_detect = False def createFace(self): """ 新建人脸信息 """ if self.databaseConnection is None: QMessageBox(QMessageBox.Warning, '警告', '请先连接到数据库').exec_() return self.addFaceWidget = AddFaceWidget(self.databaseConnection) def createOrganization(self): """ 新增组织信息 """ if self.databaseConnection is None: QMessageBox(QMessageBox.Warning, '警告', '请先连接到数据库').exec_() return self.addFaceWidget = AddOrganizationWidget(self.databaseConnection) def createOrgEdit(self): if self.databaseConnection is None: QMessageBox(QMessageBox.Warning, '警告', '请先连接到数据库').exec_() return self.orgEditWidget = OrgEditWidget(self.databaseConnection) pass