Esempio n. 1
0
 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
Esempio n. 2
0
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))
Esempio n. 3
0
    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()
Esempio n. 4
0
    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)
Esempio n. 5
0
    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()
Esempio n. 6
0
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)
Esempio n. 7
0
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