def createMenuBar(self, menubar: QMenuBar):
        menubar.addSeparator()
        for config in menubar_configs:
            for label, items in config.items():
                menu = menubar.addMenu(label)
                for item in items:
                    text = item.get('text')
                    sc = item.get('shortcut', None)
                    icon = item.get('icon', None)
                    sub = item.get('sub', None)
                    if sub:
                        submenu = QMenu(text, self)
                        for each_sub in sub:
                            text = each_sub.get('text')
                            action = QAction(text, self)
                            action.triggered.connect(
                                getattr(self, each_sub.get('action')))
                            submenu.addAction(action)
                        menu.addMenu(submenu)
                        continue
                    action = QAction(text, self)
                    if sc:
                        action.setShortcut(sc)
                    if icon:
                        action.setIcon(qta.icon(icon))
                    action.triggered.connect(
                        getattr(self, item.get('action'))
                        # self.actions.get()
                    )
                    menu.addAction(action)

        self.more_actions()
예제 #2
0
class MainUI(QtWidgets.QWidget):
    """
    应用主界面
    """
    def __init__(self, parent=None):
        """
        页面元素初始化
        :param parent:
        """
        super(MainUI, self).__init__(parent)
        # 窗口属性初始化
        # self.resize(920, 560)
        self.setFixedSize(920, 560)
        self.setWindowTitle("MaX.打卡系统--V1.0")

        # 变量初始化
        self.menu_bar = None  # 菜单栏
        self.logcat_menu = None  # 打卡日志
        self.admin_login = None  # 管理员登录
        self.image = None  # 图片初始化
        self.image_path = r"G:\githublocal\drawable\MaXlogo.jpg"
        self.button_in = None  # 输入按钮
        self.button_check = None  # 打卡按钮
        self.widget = None  # 控件
        self.time_label = None  # 时间标签
        self.name_label = None  # 打卡名字显示
        self.time = None  # 获取当前时间
        self.date = None  # 获取当前日期
        self.timer = None  # 定时器
        self.text = None  # 时间格式化
        self.time_flag = "08:00:00"  # 打卡时间设置
        self.pic_num = 0  # 图片存储标记,最多存储15张人脸
        self.sign = 1  # 标记,1代表打卡,2代表录入
        self.idn = None  # id号
        self.admin = None
        self.im_rd = None
        self._sign = 0
        self.check_face = [[], []]  # 打卡数据列表
        # 相机定时器
        self.timer_camera = QTimer()
        self.cap = cv2.VideoCapture()  # 设置相机

        # 布局初始化
        self.glayout = QGridLayout()
        self.glayout.setSpacing(10)
        self.setLayout(self.glayout)

        # 动态显示时间
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.current_time)

        self.timer.start()
        # 函数初始化
        self.set_menu()
        self.show_time_label()
        self.current_time()
        self.set_operation()
        self.set_image()
        self.show_name_label()
        self.clicked_activity()

    def clicked_activity(self):
        """
        控件信号处理
        :return:
        """
        self.logcat_menu.triggered.connect(lambda: self.on_log_dialog())
        self.admin_login.triggered.connect(lambda: self.on_admin_dialog())
        self.button_in.clicked.connect(lambda: self.on_info_dialog())
        self.button_check.clicked.connect(lambda: self.new_create_time())
        self.timer_camera.timeout.connect(lambda: self.show_camera())

    def set_menu(self):
        """
        菜单栏部分界面
        :return:
        """

        self.menu_bar = QMenuBar(self)  # 菜单栏
        self.menu_bar.setObjectName('menu_bar')
        self.logcat_menu = self.menu_bar.addAction("打卡日志")
        self.menu_bar.addSeparator()
        self.admin_login = self.menu_bar.addAction("管理员登录")
        self.glayout.addWidget(self.menu_bar, 0, 0, 1, 30)

    def set_operation(self):
        """
        点击按钮
        :return:
        """
        self.button_in = QPushButton("录入人脸")
        self.button_in.setObjectName('button_in')
        self.button_check = QPushButton("开始打卡")
        self.button_check.setObjectName('button_check')
        self.glayout.addWidget(self.button_in, 10, 2, 10, 10)
        self.glayout.addWidget(self.button_check, 12, 2, 10, 10)

    def set_image(self):
        """
        预设图片
        :return:
        """
        self.image = QLabel(self)
        self.image.setObjectName('image')
        self.image.setPixmap(QPixmap(self.image_path).scaled(600, 400))
        self.glayout.addWidget(self.image, 1, 15, 15, 15)

    def show_time_label(self):
        """
        打卡时间显示
        :return:
        """
        # widget = QtWidgets.QWidget()
        self.time_label = QLabel()
        self.time_label.setObjectName('time_label')
        self.time_label.setFrameShape(QtWidgets.QFrame.Box)
        self.glayout.addWidget(self.time_label, 3, 0, 8, 15)

    def show_name_label(self):
        """
        打卡姓名显示
        :return:
        """
        self.name_label = QLabel(self)
        self.name_label.setObjectName('name_label')
        self.name_label.setText("暂无打卡信息")
        self.name_label.setAlignment(Qt.AlignCenter)
        # self.name_label.setGeometry(50, 500, 20, 20)
        self.name_label.setFrameShape(QtWidgets.QFrame.Box)
        self.glayout.addWidget(self.name_label, 16, 17, 4, 10)

    def current_time(self):
        """
        获取当前日期时间,显示到label标签
        :return:
        """
        self.date = QDate.currentDate()
        self.time = QTime.currentTime()
        self.text = self.date.toString(
            Qt.DefaultLocaleLongDate) + "\n" + self.time.toString()
        self.time_label.setText(self.text)
        self.time_label.setAlignment(Qt.AlignCenter)  # 字体居中

    def on_log_dialog(self):
        logcat = LogDialog()
        logcat.setStyleSheet(CommonHelper.read_qss(style_file))
        logcat.exec_()

    def on_admin_dialog(self):
        """
        打开管理员弹窗
        :return:
        """
        if self.admin_login.text() == "管理员登录":
            admin_dialog = AdminLoginDialog()
            admin_dialog.setStyleSheet(CommonHelper.read_qss(style_file))
            admin_dialog.adname.connect(self.ad_name)
            admin_dialog.exec_()
            if self.admin:
                self.admin_login.setText(self.admin)  # 更改菜单名
        else:
            admin_dialog = AdminDialog()
            admin_dialog.setStyleSheet(CommonHelper.read_qss(style_file))
            admin_dialog.flag_re.connect(self.path_change_fun)  # 链接槽函数
            admin_dialog.exec_()

    def on_info_dialog(self):
        """
        打开信息注册弹窗
        :return:
        """
        info = InfoDialog()
        info.setStyleSheet(CommonHelper.read_qss(style_file))
        info.idtext.connect(self.id_num)
        info.exec_()
        if self.idn:
            self.sign = 2
            self.new_create_time()

    @pyqtSlot(str)
    def id_num(self, s):
        self.idn = s

    @pyqtSlot(str)
    def ad_name(self, n):
        self.admin = n

    @pyqtSlot(str, str, str)
    def path_change_fun(self, *args):
        self.image_path = args[0]

    def new_create_time(self):
        if self.timer_camera.isActive() is False:

            flag = self.cap.open(0)
            if flag is False:
                QMessageBox.warning(self,
                                    u"警告",
                                    u"请检测相机与电脑是否连接正确",
                                    buttons=QMessageBox.Ok,
                                    defaultButton=QMessageBox.Ok)
            else:
                self.timer_camera.start(30)
                if self.sign == 1:
                    self.feature = load_face()
                    self.button_check.setText("停止打卡")
        else:
            self.timer_camera.stop()
            self.sign = 1
            self.cap.release()
            if self.button_check.text() == "停止打卡":
                print(int(self.name_label.text().split(" ")[0]))
                print(set([tuple(t) for t in self.check_face]))
                insert_logcat(int(self.name_label.text().split(" ")[0]),
                              self.date.toString(Qt.ISODate),
                              self.time.toString(), self.time_subtraction())
                self.button_check.setText("开始打卡")
                self.name_label.setText("暂无打卡信息")
            self.image.setPixmap(
                QPixmap(r"G:\githublocal\drawable\MaXlogo.jpg").scaled(
                    600, 400))

    def show_camera(self):
        flag, self.im_rd = self.cap.read()
        # key = cv2.waitKey(10)
        # 人脸数
        dets = detector(self.im_rd, 1)
        # 检测到人脸
        if len(dets) != 0:
            equal_face = dets[0]
            # 占比最大的脸
            max_area = 0
            for det in dets:
                w = det.right() - det.left()
                h = det.top() - det.bottom()
                if w * h > max_area:
                    equal_face = det
                    max_area = w * h
                    # 绘制矩形框
            cv2.rectangle(self.im_rd,
                          tuple([equal_face.left(),
                                 equal_face.top()]),
                          tuple([equal_face.right(),
                                 equal_face.bottom()]), (255, 0, 0), 2)
            show = cv2.resize(self.im_rd, (600, 400))
            show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)  # 颜色通道转换
            show_image = QImage(show.data, show.shape[1], show.shape[0],
                                QImage.Format_RGB888)
            self.image.setPixmap(QPixmap.fromImage(show_image))

            if self.sign == 2:
                # 保存截图
                face_height = equal_face.bottom() - equal_face.top()
                face_width = equal_face.right() - equal_face.left()
                im_blank = np.zeros((face_height, face_width, 3),
                                    np.uint8)  # 初始化一个三通道的图像矩阵
                # print(im_blank)
                try:

                    for height in range(face_height):
                        for width in range(face_width):
                            im_blank[height][width] = self.im_rd[
                                int(equal_face.top()) +
                                height][int(equal_face.left()) + width]
                    self.pic_num += 1
                    cv2.imwrite(Path_face + self.idn + "/face_img" +
                                str(self.pic_num) + ".jpg",
                                im_blank)  # 中文路径无法存储,故采用id为文件名
                    if self.pic_num >= 15:  # 当提取了15张图后,结束提取
                        into_db = ThreadIntoDB(self.idn)
                        into_db.start()
                        self.pic_num = 0
                        self.new_create_time()
                except:
                    print("异常")
            else:
                try:

                    shape = predictor(self.im_rd, equal_face)  # 提取特征点
                    face_cap = face_rgt.compute_face_descriptor(
                        self.im_rd, shape)  # 计算128维向量

                    # 将当前人脸与数据库人脸对比
                    for i, face_data in enumerate(self.feature[1]):  # 对人脸进行遍历
                        compare = distance(face_cap, face_data)
                        if compare is True:
                            str_info = str(
                                self.feature[0][i]) + " " + self.feature[2][i]
                            self.name_label.setText(str_info)
                            self.check_face.append(str_info)
                            break
                except:
                    print("异常")

    def time_subtraction(self):
        time_string1 = self.date.toString(Qt.ISODate) + " " + self.time_flag
        time_string2 = self.date.toString(
            Qt.ISODate) + " " + self.time.toString()
        ta = time.strptime(time_string2, "%Y-%m-%d %H:%M:%S")
        tb = time.strptime(time_string1, "%Y-%m-%d %H:%M:%S")
        y, m, d, H, M, S = ta[0:6]
        data_timea = datetime.datetime(y, m, d, H, M, S)
        y, m, d, H, M, S = tb[0:6]
        data_timeb = datetime.datetime(y, m, d, H, M, S)
        if data_timea <= data_timeb:
            return "0"
        else:
            secondsDiff = (data_timea - data_timeb).seconds
            return str(secondsDiff // 60)
def main():
    # Contains JSON file which will be exported or has been imported and will be manipulated by the user's actions.
    import os
    import pathlib

    project_dir = pathlib.Path(os.path.abspath(os.path.dirname(__file__)))

    dict_state = {}

    # fixme remove, only dummy for debugging
    language = "german"

    Form, Window = uic.loadUiType(pathlib.Path(project_dir, "test_gui.ui"))

    app = QApplication([])
    window = Window()
    form = Form()
    form.setupUi(window)

    form.load_dict.clicked.connect(open_dialog)
    form.save_dict.clicked.connect(save_dialog)
    form.new_dict.clicked.connect(new_dict_dialog)
    form.add_language.clicked.connect(add_lang_dialog)
    form.new_language_button.clicked.connect(fill_new_language)
    form.new_language_button_2.clicked.connect(new_dict_begin_dialog)
    form.add_translation_next.clicked.connect(next_new_language)
    form.add_translation_back.clicked.connect(prev_new_language)
    form.add_translation_finish.clicked.connect(finish_new_language)
    form.dict_table.cellClicked.connect(handle_table_click)
    form.ok_button.clicked.connect(write_to_dict)
    form.cancel_button.clicked.connect(cancel_inspect_mode)
    form.comboBox.currentIndexChanged.connect(change_option)
    form.tableWidget_2.cellClicked.connect(change_lang_inspect_mode)

    # create menu
    # menubar = QMenuBar()
    menubar = QMenuBar()
    window.setMenuBar(menubar)

    extractActionNew = QAction("&New")
    extractActionNew.setShortcut("Ctrl+N")
    extractActionNew.setStatusTip("Create-Dictonary")
    extractActionNew.triggered.connect(new_dict_dialog)
    menubar.addAction(extractActionNew)

    extractActionLoad = QAction("&Load-File")
    extractActionLoad.setShortcut("Ctrl+L")
    extractActionLoad.setStatusTip("Leave The App")
    extractActionLoad.triggered.connect(open_dialog)
    menubar.addAction(extractActionLoad)

    extractActionSave = QAction("&Save-File")
    extractActionSave.setShortcut("Ctrl+S")
    extractActionSave.setStatusTip("Leave The App")
    extractActionSave.triggered.connect(save_dialog)
    menubar.addAction(extractActionSave)

    extractActionAddLan = QAction("&Add-Language")
    extractActionAddLan.setShortcut("Ctrl+Q")
    extractActionAddLan.setStatusTip("Leave The App")
    extractActionAddLan.triggered.connect(add_lang_dialog)
    menubar.addAction(extractActionAddLan)
    menubar.addSeparator()

    extractActionClose = QAction("&Close")
    extractActionClose.setShortcut("Ctrl+Q")
    extractActionClose.setStatusTip("Leave The App")
    extractActionClose.triggered.connect(close_application)
    menubar.addAction(extractActionClose)

    window.show()
    app.exec_()