Esempio n. 1
0
    def __init__(self, db_path, parent=None):
        super(Add_Table_UI, self).__init__(parent)

        self.db_path = db_path

        self.sf = Sqlite_Func()

        h_layout = QHBoxLayout()
        label_table_name = QLabel("表名字:")
        self.lineEdit_table_name = QLineEdit()
        # 水平放置
        h_layout.addWidget(label_table_name)
        h_layout.addWidget(self.lineEdit_table_name)

        btn_ok = QPushButton()
        btn_ok.setText("OK")

        v_layout = QVBoxLayout()

        # 垂直放置
        v_layout.addLayout(h_layout)
        v_layout.addWidget(btn_ok)

        self.setLayout(v_layout)

        btn_ok.clicked.connect(self.create_table)
Esempio n. 2
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        self.sf = Sqlite_Func()

        self.opsql = Operate_Sql()

        self.timer_camera_test = QtCore.QTimer()  # qt计数器
        self.timer_camera_face = QtCore.QTimer()  # qt计数器


        self.openSqlite = Sqlite_UI()  # 数据库对象
        self.slot_init()

        self.combobox_face_init()  # 初始化下拉列表:人脸数据表
        self.combobox_checkWork_init()  # 初始化下拉列表:考勤数据表

        self.photoNum = 0  # 照片计数
        self.CAM_NUM = 0
        self.pNum = 0  # 照片计数器
        self.photo_transmission = 0  # 图片传输变量
        self.frame_out = 0

        # 启动Facenet模块
        self.face = face_recognition.face()
        self.init_db()
Esempio n. 3
0
    def __init__(self, db_path, table, field, parent=None):
        super(Add_Data_UI, self).__init__(parent)

        self.db_path = db_path
        self.table = table
        self.field = field

        self.sf = Sqlite_Func()

        v_label_layout = QVBoxLayout()
        v_layout = QVBoxLayout()
        v_lineEdit_layout = QVBoxLayout()

        h_layout = QHBoxLayout()

        self.lineEdit_list = []
        self.field_len = len(field)

        db_type = str(db_path).split('/')
        print("db type:", db_type[len(db_type) - 1].upper())
        if db_type[len(db_type) - 1].upper() == self.sf.DB_TYPE_CHECKWORK:
            self.field_len = len(field) - 1

        for i in range(self.field_len):
            label = QLabel()
            label.setText("{}:".format(str(field[i]).upper()))
            v_label_layout.addWidget(label)

            lineEdit = QLineEdit()
            self.lineEdit_list.append(lineEdit)

            v_lineEdit_layout.addWidget(lineEdit)

        if db_type[len(db_type) - 1].upper() == self.sf.DB_TYPE_CHECKWORK:
            # 对于考勤表 flag不允许手动写入

            label = QLabel()
            label.setText("{}:".format(str(field[self.field_len]).upper()))
            v_label_layout.addWidget(label)

            lineEdit_flag = QLineEdit()
            lineEdit_flag.setReadOnly(True)
            lineEdit_flag.setText("0")

            self.lineEdit_list.append(lineEdit_flag)
            v_lineEdit_layout.addWidget(lineEdit_flag)

        h_layout.addLayout(v_label_layout)
        h_layout.addLayout(v_lineEdit_layout)

        btn_ok = QPushButton()
        btn_ok.setText("确定")

        v_layout.addLayout(h_layout)
        v_layout.addWidget(btn_ok)

        self.setLayout(v_layout)

        self.setupUi(self)
        btn_ok.clicked.connect(self.insert_data)
Esempio n. 4
0
    def __init__(self, parent=None):
        super(Sqlite_UI, self).__init__(parent)
        self.setupUi(self)

        # 隐藏两个组件:因为我不想写了
        self.label_cmd.hide()
        self.lineEdit_cmd.hide()

        # slot init
        self.slot_init()

        self.sf = Sqlite_Func()

        # 数据库路径
        self.db_path = ""
        # 选择的表名
        self.table = ""
        # 所有数据表
        self.table_list = []
        # 当前表所有字段
        self.field_list = []
        # 创建的按钮字段列表
        self.btn_field_list = []
        # 被勾选的字段
        self.select_field_list = []
        # 当前行列
        self.len_row = 0
        self.len_col = 0

        self.model = QStandardItemModel()

        # 数据库类型
        self.db_type = ""
Esempio n. 5
0
def computing_emb():
    with tf.Graph().as_default():
        with tf.Session() as sess:

            # opsql = sqlite3_op.Operate_Sql()
            sqlite = Sqlite_Func()

            model = '../20170512-110547/'
            emb_img = '../emb_img'
            # 加载facenet模型
            facenet.load_model(model)
            images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
            embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
            phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
            image = []
            nrof_images = 0
            global compare_emb, compare_num, all_obj_name

            all_obj_name = []
            for i in os.listdir(emb_img):
                all_obj_name.append(i)
                img = imageio.imread(os.path.join(emb_img, i))
                prewhitened = facenet.prewhiten(img)  # 预白化去除冗余信息
                image.append(prewhitened)
                nrof_images = nrof_images + 1

            images = np.stack(image)  # 沿着新轴连接数组的序列。
            # 计算对比图片embadding,embdadding是一个128维的张量
            compare_emb = sess.run(embeddings, feed_dict={images_placeholder: images, phase_train_placeholder: False})
            compare_num = len(compare_emb)
            print('compare_emb len:', len(compare_emb[0]))
            print("pre_embadding计算完成")

            for i in os.listdir(emb_img):
                #拆分表名和id号
                index = 0
                info = i.split("#")
                print("info:{}".format(info))
                table_name=info[0]
                id = info[1].split(".")
                ID=id[0]

                # opsql.insert_emb(info[0], id[0], compare_emb[index])
                sqlite.update_face_emb(sqlite.DB_STUDENTFACE_PATH, table_name, ID, compare_emb[index])
                index += 1

            # 移除已经计算过的image
            for f in os.listdir(emb_img):
                pass
                os.remove(os.path.join(emb_img, f))
Esempio n. 6
0
class Add_Table_UI(QDialog, Ui_Dialog_Add_Table):
    signal_status = pyqtSignal()

    def __init__(self, db_path, parent=None):
        super(Add_Table_UI, self).__init__(parent)

        self.db_path = db_path

        self.sf = Sqlite_Func()

        h_layout = QHBoxLayout()
        label_table_name = QLabel("表名字:")
        self.lineEdit_table_name = QLineEdit()
        # 水平放置
        h_layout.addWidget(label_table_name)
        h_layout.addWidget(self.lineEdit_table_name)

        btn_ok = QPushButton()
        btn_ok.setText("OK")

        v_layout = QVBoxLayout()

        # 垂直放置
        v_layout.addLayout(h_layout)
        v_layout.addWidget(btn_ok)

        self.setLayout(v_layout)

        btn_ok.clicked.connect(self.create_table)

    def create_table(self):
        sstr = self.db_path.split('/')
        self.db_type = sstr[len(sstr) - 1]
        print("db_type:", self.db_type)
        print("创建新表")
        if self.lineEdit_table_name == "":
            print("表名字为空")
        else:
            self.sf.create_table(self.db_path, self.lineEdit_table_name.text(), str(self.db_type).upper())
            status = 1

            self.signal_status.emit()
            self.close()

    def test(self, s):
        print("s:", s)
 def __init__(self):
     self.init_mtcnn()
     self.train = False
     self.sqlite = Sqlite_Func()
class face():
    def __init__(self):
        self.init_mtcnn()
        self.train = False
        self.sqlite = Sqlite_Func()

    # 初始化MTCNN
    def init_mtcnn(self):
        print('初始化MTCNN')
        with tf.Graph().as_default():
            gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=1.0)
            sess = tf.Session(config=tf.ConfigProto(
                gpu_options=gpu_options, log_device_placement=False))
            with sess.as_default():
                global pnet, rnet, onet
                pnet, rnet, onet = align.detect_face.create_mtcnn(sess, None)

    # 提前计算pre_embadding
    def init_pre_embdading(slef):
        print('初始化 Facenet')
        with tf.Graph().as_default():
            with tf.Session() as sess:
                model = '../20170512-110547/'
                facenet.load_model(model)
                images_placeholder = tf.get_default_graph().get_tensor_by_name(
                    "input:0")
                embeddings = tf.get_default_graph().get_tensor_by_name(
                    "embeddings:0")
                phase_train_placeholder = tf.get_default_graph(
                ).get_tensor_by_name("phase_train:0")
                image = []
                nrof_images = 0
                global compare_emb, compare_num, all_obj_name
                emb_dir = '../emb_img'
                all_obj_name = []
                for i in os.listdir(emb_dir):
                    all_obj_name.append(i)
                    img = imageio.imread(os.path.join(emb_dir, i))
                    print('img.shape:', img.shape)
                    prewhitened = facenet.prewhiten(img)  # 预白化去除冗余信息
                    image.append(prewhitened)
                    nrof_images = nrof_images + 1
                # global compare_emb, compare_num
                images = np.stack(image)  # 沿着新轴连接数组的序列。
                feed_dict = {
                    images_placeholder: images,
                    phase_train_placeholder: False
                }
                # 计算对比图片embadding,embdadding是一个128维的张量
                compare_emb = sess.run(embeddings, feed_dict=feed_dict)
                print('compare_emb:', compare_emb)
                print('compare_emb_shape:', compare_emb.shape)
                compare_num = len(compare_emb)
                print("pre_embadding计算完成")
        return compare_emb, compare_num, all_obj_name  # 数据库embadding,人数,目录标签

    def main(self, face, checkwork):
        with tf.Graph().as_default():
            with tf.Session() as sess:
                model = '../20170512-110547/'
                facenet.load_model(model)
                images_placeholder = tf.get_default_graph().get_tensor_by_name(
                    "input:0")
                embeddings = tf.get_default_graph().get_tensor_by_name(
                    "embeddings:0")
                phase_train_placeholder = tf.get_default_graph(
                ).get_tensor_by_name("phase_train:0")
                '''
                id:学号
                compare_emb:特征值
                compare_num:数据库中的数据条数
                '''

                # 找到当表主键
                face_key_idx, face_key = self.sqlite.find_primary_key(
                    self.sqlite.DB_STUDENTFACE_PATH, face)
                # cw_key_idx,cw_key=self.sqlite.find_primary_key(self.sqlite.DB_STUDENTCHECKWORK_PATH,checkwork)

                # 从数据库获取人脸数据
                cmd = self.sqlite.auto_select(face)
                rows = self.sqlite.executeCMD(self.sqlite.DB_STUDENTFACE_PATH,
                                              cmd)

                id = []

                num = len(rows)
                emb_idx = len(rows[0]) - 1

                compare_num = num
                compare_emb = np.zeros([num, 128])

                for lineIndex in range(num):
                    row = rows[lineIndex]  # 获取某一行的数据,类型是tuple
                    id.append(row[face_key_idx])  # 获取id
                    emb_str = row[emb_idx]  # 获取一个组数据中的emb数据
                    if emb_str is None:
                        compare_emb[lineIndex] = np.full((1, 128), 10)
                    else:
                        str_list = emb_str.split(' ')  # 以空格分割字符串
                        if len(str_list) < 10:
                            continue
                        for i in range(128):
                            compare_emb[lineIndex][i] = float(
                                str_list[i])  # 'list转ndarray:',str->float

                capture = cv2.VideoCapture(0)
                cv2.namedWindow("face recognition", 1)

                while True:
                    ret, frame = capture.read()
                    frame = cv2.flip(frame, 1)
                    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

                    # 识别框
                    cv2.putText(frame,
                                'Identification Box', (200, 90),
                                cv2.FONT_HERSHEY_COMPLEX_SMALL,
                                1, (0, 0, 255),
                                thickness=2,
                                lineType=1)
                    cv2.rectangle(frame, (150, 100), (490, 380),
                                  (165, 245, 25), 2)
                    BOX = [150, 100, 490, 380]

                    # 获取视频流中的最大人脸 判断标识 bounding_box crop_image
                    mark, bounding_box, crop_image = self.load_and_align_data(
                        rgb_frame, 160)
                    '''
                    范围限制
                    '''
                    if mark:
                        if bounding_box[0] < 75:
                            mark = False
                            # print('left')
                        if bounding_box[2] > 565:
                            mark = False
                            # print('right')

                    if mark:
                        # print('计算视频帧的embadding')
                        emb = sess.run(embeddings,
                                       feed_dict={
                                           images_placeholder: crop_image,
                                           phase_train_placeholder: False
                                       })
                        pre_person_num = len(emb)
                        find_obj = []
                        # print('识别到的人数:', pre_person_num)
                        cv2.putText(frame,
                                    'Press esc to exit', (10, 30),
                                    cv2.FONT_HERSHEY_COMPLEX_SMALL,
                                    1, (0, 0, 255),
                                    thickness=1,
                                    lineType=1)
                        # 逐一对比
                        for i in range(pre_person_num):  # 为bounding_box 匹配标签
                            dist_list = []  # 距离列表

                            for j in range(compare_num):
                                # 求误差(欧氏距离)
                                dist = np.sqrt(
                                    np.sum(
                                        np.square(
                                            np.subtract(
                                                emb[i, :],
                                                compare_emb[j, :]))))
                                dist_list.append(dist)
                                # 求视频帧和对比图直接最小的差值,即表示为最相似的图片
                                min_value = min(dist_list)
                                # print("最小差值:", min_value)
                            if min_value > 0.65:
                                find_obj.append('Unknow')
                            else:
                                dist_index = dist_list.index(min_value)
                                find_obj.append(id[dist_index])

                        # 在frame上绘制边框和文字
                        cv2.rectangle(frame,
                                      (bounding_box[0], bounding_box[1]),
                                      (bounding_box[2], bounding_box[3]),
                                      (0, 255, 0), 1, 8, 0)
                        cv2.putText(frame,
                                    str(find_obj[0]),
                                    (bounding_box[0], bounding_box[1]),
                                    cv2.FONT_HERSHEY_COMPLEX_SMALL,
                                    1, (0, 0, 255),
                                    thickness=2,
                                    lineType=2)

                    # 将学号插入到选择的考勤表中
                    if find_obj[0] != "Unknow":
                        self.sqlite.update_checkwork(
                            self.sqlite.DB_STUDENTCHECKWORK_PATH, checkwork,
                            find_obj[0])
                    cv2.imshow('face recognition', frame)
                    key = cv2.waitKey(3)
                    if key == 27:
                        break
                capture.release()
                cv2.destroyWindow("face recognition")

    def load_and_align_data(self, img, image_size):

        minsize = 20
        threshold = [0.6, 0.7, 0.7]
        factor = 0.709
        bounding_boxes, _ = align.detect_face.detect_face(
            img, minsize, pnet, rnet, onet, threshold, factor)
        Index = []  # 序列
        Area = []  # 面积
        Position = []  # 坐标

        # print('len(bounding_boxes):', len(bounding_boxes))

        # 如果未发现目标 直接返回
        if len(bounding_boxes) < 1:
            # print('没有发现人脸')
            return False, 0, 0

        for i, face_position in enumerate(bounding_boxes):
            face_position = face_position.astype(int)
            w = face_position[2] - face_position[0]
            h = face_position[3] - face_position[1]
            S = w * h
            # print('第:', i)
            # print('w:', w)
            # print('h:', h)

            Index.append(i)
            Area.append(S)
            Position.append(face_position)

        max_face_position = max_face(Area, Position)

        # print('bbox:', (max_face_position[0], max_face_position[1]),
        #       (max_face_position[2], max_face_position[3]))

        # 裁剪
        temp_crop = img[max_face_position[1]:max_face_position[3],
                        max_face_position[0]:max_face_position[2], :]

        if max_face_position[0] < 75:  # 左边
            return False, 0, 0

        if max_face_position[2] > 565:  # 右边
            return False, 0, 0

        if max_face_position[1] < 75:  # 上面
            return False, 0, 0

        aligned = cv2.resize(temp_crop, (image_size, image_size),
                             interpolation=cv2.INTER_CUBIC)
        face_out = facenet.prewhiten(aligned)
        crop_image = []
        crop_image.append(np.stack(face_out))
        return True, max_face_position, crop_image  # mark标记位置,回归边框,切割图片
Esempio n. 9
0
class MainWindow(QMainWindow, Ui_Face_Recognition_window):
    # 构造函数
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        self.sf = Sqlite_Func()

        self.opsql = Operate_Sql()

        self.timer_camera_test = QtCore.QTimer()  # qt计数器
        self.timer_camera_face = QtCore.QTimer()  # qt计数器


        self.openSqlite = Sqlite_UI()  # 数据库对象
        self.slot_init()

        self.combobox_face_init()  # 初始化下拉列表:人脸数据表
        self.combobox_checkWork_init()  # 初始化下拉列表:考勤数据表

        self.photoNum = 0  # 照片计数
        self.CAM_NUM = 0
        self.pNum = 0  # 照片计数器
        self.photo_transmission = 0  # 图片传输变量
        self.frame_out = 0

        # 启动Facenet模块
        self.face = face_recognition.face()
        self.init_db()

    def init_db(self):
        if os.path.exists("../DB/StudentFaceDB.db") is False:
            os.mkdir("../DB/StudentFaceDB.db")
        if os.path.exists("../DB/StudentCheckWorkDB.db.db")is False:
            os.mkdir("../DB/StudentCheckWorkDB.db.db")

    # 槽初始化
    def slot_init(self):

        self.timer_camera_test.timeout.connect(self.show_frame)

        self.btn_openCamera.clicked.connect(self.opencamera)
        self.btn_takePhoto.clicked.connect(self.take_photo)

        self.btn_refresh.clicked.connect(self.refresh)

        self.btn_train.clicked.connect(self.train)
        self.btn_recogniton.clicked.connect(self.open_recognition_camera)
        self.btn_sqlite.clicked.connect(self.open_sqlite)


    def open_sqlite(self):
        self.openSqlite.show()

    def opencamera(self):
        if self.timer_camera_test.isActive() == False:
            self.cap = cv2.VideoCapture(0)
            flag = self.cap.open(self.CAM_NUM)
            if flag is None:
                msg = QtWidgets.QMessageBox.warning(self, u"Warning", u"摄像头无法打开!",
                                                    buttons=QtWidgets.QMessageBox.Ok,
                                                    defaultButton=QtWidgets.QMessageBox.Ok)
            self.btn_openCamera.setText("关闭摄像头")
            self.timer_camera_test.start(25)
        else:
            self.btn_openCamera.setText(u"打开摄像头")
            self.timer_camera_test.stop()
            self.lab_frame.setText(u"无图像输入")
            self.cap.release()

    def show_frame(self):
        ret, frame = self.cap.read()
        if frame is None:
            return
        frame = cv2.flip(frame, 1)
        frame = cv2.resize(frame, (640, 480))
        self.photo_transmission = frame
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        lable = cv2.putText(frame, '-->Camera OK', (10, 30), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 255, 0),
                            thickness=1, lineType=1)
        showFrame = QtGui.QImage(frame.data, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
        self.lab_frame.setPixmap(QtGui.QPixmap.fromImage(showFrame))


    # 拍照
    def take_photo(self):
        '''
        1、从数据库中读取所有文件名
        2、从文件名中选择文件目录作为照片存储地址
        3、调用拍照程序对当前画面进行拍照
        4、更新拍照数量
        '''

        # 如果摄像头没有打开
        if self.btn_openCamera.text() != '关闭摄像头':
            msg = QtWidgets.QMessageBox.warning(self, u"Warning", u"请打开摄像头!",
                                                buttons=QtWidgets.QMessageBox.Ok,
                                                defaultButton=QtWidgets.QMessageBox.Ok)
        else:
            face = self.comboBox_face.currentText()
            id = self.comboBox_id.currentText()
            if id == '' or id is None:
                msg = QtWidgets.QMessageBox.warning(self, u"Warning", u"请选择学号!",
                                                    buttons=QtWidgets.QMessageBox.Ok,
                                                    defaultButton=QtWidgets.QMessageBox.Ok)
            else:
                name = '{CLASS}#{id}'.format(CLASS=face, id=id)
                name = '../src_img/{name}.jpg'.format(name=name)
                print(name)
                cv2.imwrite(name, self.photo_transmission)

    # 考勤表初始化
    def combobox_checkWork_init(self, checktable=None):
        self.comboBox_checkWork.clear()

        ret = self.sf.check_table(self.sf.DB_STUDENTCHECKWORK_PATH)
        print("DB:{}\ntables:{}\ntable_nmu:{}".format(self.sf.DB_STUDENTCHECKWORK_PATH, ret, len(ret)))

        readlines = len(ret)
        lineindex = 0

        while lineindex < readlines:
            self.comboBox_checkWork.addItem(ret[lineindex])
            lineindex += 1
        if checktable != '' or checktable is None:
            self.comboBox_checkWork.setCurrentText(checktable)
        print('combobox_checkWork_init done\n')

    # 获取人脸数据表
    def combobox_face_init(self, checked_table=None):
        self.comboBox_face.clear()

        ret = self.sf.check_table(self.sf.DB_STUDENTFACE_PATH)
        table_nmu = len(ret)
        print("DB:{}\ntables:{}\ntable_nmu:{}".format(self.sf.DB_STUDENTFACE_PATH, ret, len(ret)))
        readlines = table_nmu
        lineindex = 0

        while lineindex < readlines:
            self.comboBox_face.addItem(ret[lineindex])
            lineindex += 1
        if checked_table != '' or checked_table is None:
            self.comboBox_face.setCurrentText(checked_table)
        print('combobox_face_init done\n')

        # 初始化id列表
        self.combobox_id_init(self.comboBox_face.currentText())

    def combobox_id_init(self, table):
        # 读取人脸数据库中所有id
        field = []
        field.append("id")
        cmd = self.sf.auto_select(table,field)
        print("cmd-->",cmd)
        ret = self.sf.executeCMD(self.sf.DB_STUDENTFACE_PATH, cmd)
        print("ret:", ret)

        self.comboBox_id.clear()
        print(len(ret))
        for i in range(len(ret)):
            self.comboBox_id.addItem(str(ret[i][0]))

    # 刷新显示数据库并且显示id号
    def refresh(self):

        # 获取当前选中表明
        checked_face = self.comboBox_face.currentText()
        checked_cw = self.comboBox_checkWork.currentText()

        print("当前选中:{},{}".format(checked_face, checked_cw))

        self.combobox_face_init(checked_table=checked_face)
        self.combobox_checkWork_init(checktable=checked_cw)

    def train(self):

        ret = QMessageBox.question(self, "Train", "训练过程中,画面无法更新,训练时间随机器性能决定", QMessageBox.Yes | QMessageBox.No,
                                   QMessageBox.No)
        if ret == QMessageBox.Yes:
            get_face.detection()

    # 打开识别摄像头
    def open_recognition_camera(self):

        if self.btn_openCamera.text() == '关闭摄像头':
            msg = QtWidgets.QMessageBox.warning(self, u"警告", u"请先关闭摄像头!",
                                                buttons=QtWidgets.QMessageBox.Ok,
                                                defaultButton=QtWidgets.QMessageBox.Ok)
        else:
            ret = QMessageBox.question(self, "Train", "1、启动时间根据设备性能强弱决定\n\n2、程序启动后按下esc退出检测窗口",
                                       QMessageBox.Yes | QMessageBox.No,
                                       QMessageBox.No)
            if ret == QMessageBox.Yes:
                print('开启摄像头')
                face = self.comboBox_face.currentText()
                cw = self.comboBox_checkWork.currentText()
                self.face.main(face, cw)
Esempio n. 10
0
class Add_Data_UI(QDialog, Ui_Dialog_Add_Data):
    signal_status = pyqtSignal()

    def __init__(self, db_path, table, field, parent=None):
        super(Add_Data_UI, self).__init__(parent)

        self.db_path = db_path
        self.table = table
        self.field = field

        self.sf = Sqlite_Func()

        v_label_layout = QVBoxLayout()
        v_layout = QVBoxLayout()
        v_lineEdit_layout = QVBoxLayout()

        h_layout = QHBoxLayout()

        self.lineEdit_list = []
        self.field_len = len(field)

        db_type = str(db_path).split('/')
        print("db type:", db_type[len(db_type) - 1].upper())
        if db_type[len(db_type) - 1].upper() == self.sf.DB_TYPE_CHECKWORK:
            self.field_len = len(field) - 1

        for i in range(self.field_len):
            label = QLabel()
            label.setText("{}:".format(str(field[i]).upper()))
            v_label_layout.addWidget(label)

            lineEdit = QLineEdit()
            self.lineEdit_list.append(lineEdit)

            v_lineEdit_layout.addWidget(lineEdit)

        if db_type[len(db_type) - 1].upper() == self.sf.DB_TYPE_CHECKWORK:
            # 对于考勤表 flag不允许手动写入

            label = QLabel()
            label.setText("{}:".format(str(field[self.field_len]).upper()))
            v_label_layout.addWidget(label)

            lineEdit_flag = QLineEdit()
            lineEdit_flag.setReadOnly(True)
            lineEdit_flag.setText("0")

            self.lineEdit_list.append(lineEdit_flag)
            v_lineEdit_layout.addWidget(lineEdit_flag)

        h_layout.addLayout(v_label_layout)
        h_layout.addLayout(v_lineEdit_layout)

        btn_ok = QPushButton()
        btn_ok.setText("确定")

        v_layout.addLayout(h_layout)
        v_layout.addWidget(btn_ok)

        self.setLayout(v_layout)

        self.setupUi(self)
        btn_ok.clicked.connect(self.insert_data)

    def insert_data(self):
        lineEdit_data = []
        for i in range(len(self.lineEdit_list)):
            lineEdit_data.append(self.lineEdit_list[i].text())

        # 插入数据库
        ret = self.sf.insert(self.db_path, self.table, lineEdit_data)
        if ret == -1:
            QMessageBox.about(self, "Error", "有数据为空")
        if ret == -2:
            QMessageBox.about(self, "Error", "主键重复")
        self.signal_status.emit()
        self.close()
Esempio n. 11
0
class Sqlite_UI(QtWidgets.QMainWindow, Ui_SqliteMainWindow):
    def __init__(self, parent=None):
        super(Sqlite_UI, self).__init__(parent)
        self.setupUi(self)

        # 隐藏两个组件:因为我不想写了
        self.label_cmd.hide()
        self.lineEdit_cmd.hide()

        # slot init
        self.slot_init()

        self.sf = Sqlite_Func()

        # 数据库路径
        self.db_path = ""
        # 选择的表名
        self.table = ""
        # 所有数据表
        self.table_list = []
        # 当前表所有字段
        self.field_list = []
        # 创建的按钮字段列表
        self.btn_field_list = []
        # 被勾选的字段
        self.select_field_list = []
        # 当前行列
        self.len_row = 0
        self.len_col = 0

        self.model = QStandardItemModel()

        # 数据库类型
        self.db_type = ""

    def slot_init(self):
        print("slot init...")
        self.actionOpen_File.triggered.connect(self.open_db)

        self.radioButton_all.clicked.connect(self.selectAll_radiobtn)
        self.radioButton_notall.clicked.connect(self.selectNotAll_radiobtn)

        self.pushButton_query.clicked.connect(self.query)
        self.pushButton_update.clicked.connect(self.update_data)
        self.pushButton_del.clicked.connect(self.delete_data)
        self.pushButton_add.clicked.connect(self.add_data)
        self.pushButton_delTable.clicked.connect(self.del_table)
        self.pushButton_newTable.clicked.connect(self.add_table)

    def open_db(self):
        print("打开文件")
        self.db_path, file_type = QFileDialog.getOpenFileName(self, "select db files", "",
                                                              "*.db;;*.png;;All Files(*)")
        print("文件路径:{}\n文件类型:{}\n".format(self.db_path, file_type))

        self.table_list = self.sf.check_table(self.db_path)
        print("当前数据库含有表:", self.table_list)

        # 设置窗口名字
        QDialog.setWindowTitle(self, self.db_path)
        sstr = self.db_path.split('/')

        print(sstr)
        self.groupBox_table_field.setTitle("数据库:{}".format(sstr[len(sstr) - 1]))

        self.db_type = sstr[len(sstr) - 1]

        self.create_radiobox_table()

    # 创建数据库表选项
    def create_radiobox_table(self):
        self.count = 0
        self.btn_layer = QWidget()
        for i, data in enumerate(self.table_list):
            self.count += 1
            self.btn = QtWidgets.QRadioButton(self.btn_layer)
            self.btn.setText(str(data))
            self.btn.clicked.connect(partial(self.create_checkbox_field, self.btn.text(), False))
            self.btn.move(10, i * 60)

        self.btn_layer.setMinimumSize(250, self.count * 60)
        self.scrollArea_table.setWidget(self.btn_layer)
        self.scrollArea_table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    # 创建字段表
    def create_checkbox_field(self, table, ischeck):
        self.btn_field_list.clear()
        self.count = 0

        self.table = table
        print("选择了{}表".format(str(table)))
        ret = self.sf.check_field(self.db_path, table)
        self.field_list = ret
        print("当前表含有{}字段:".format(ret))
        self.btn_layer = QWidget()
        for i, data in enumerate(ret):
            self.count += 1
            self.btn = QtWidgets.QCheckBox(self.btn_layer)
            self.btn.setText("{}".format(str(data)))
            self.btn.setChecked(ischeck)
            self.btn.move(10, i * 60)
            self.btn_field_list.append(self.btn)

        self.btn_layer.setMinimumSize(250, self.count * 60)
        self.scrollArea_field.setWidget(self.btn_layer)
        self.scrollArea_field.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    def selectAll_radiobtn(self):
        if self.btn_field_list == []:
            print("没有选择表")
        else:
            print("全选字段")
            self.create_checkbox_field(self.table, True)
            self.select_field_list.clear()
            for btn in self.btn_field_list:
                self.select_field_list.append(btn.text())

    def selectNotAll_radiobtn(self):
        if self.btn_field_list == []:
            print("没有选择表")
        else:
            print("全选字段")
            self.create_checkbox_field(self.table, False)
            self.select_field_list.clear()

    # param:字段,内容
    def show_table(self, fields, data):
        print("显示表内容")
        print("字段:{}\n数据:{}".format(fields, data))

        # 行数
        # 列数
        self.len_row = len(data)
        self.len_col = len(fields)
        print("row:{},col:{}".format(self.len_row, self.len_col))
        # self.model = QStandardItemModel(self.len_row, self.len_col, self)
        self.model.setRowCount(self.len_row)
        self.model.setColumnCount(self.len_col)
        for row in range(self.len_row):
            for col in range(len(data[0])):
                item = QStandardItem("{}".format(data[row][col]))

                self.model.setItem(row, col, item)

        self.tableView_content.setModel(self.model)
        self.tableView_content.horizontalHeader().setStretchLastSection(True)
        self.tableView_content.setEditTriggers(QAbstractItemView.DoubleClicked)
        self.tableView_content.clicked.connect(lambda x: print(self.tableView_content.currentIndex().data()))

    # 通过按键更新数据到数据库
    def update_data(self):
        print(self.btn_field_list)
        if self.btn_field_list == []:
            print("没有选择表")
        else:
            update_data = []
            if self.len_row == 0:
                print("没有数据")
                return

            # 读取新数据
            for i in range(self.len_row):
                update_data_item = []
                for j in range(self.len_col):
                    if self.model.item(i, j).text() != None:
                        update_data_item.append(self.model.item(i, j).text())
                update_data.append(update_data_item)
            print("update data", update_data)

            if len(update_data[0]) != len(self.field_list):
                print("数据不足")
                return
            # 查找主键
            i, key = self.sf.find_primary_key(self.db_path, self.table)

            # 更新数据
            ret = self.sf.update(self.db_path, self.table, self.field_list, update_data, i)
            if ret == -1:
                QMessageBox.about(self, "Error", "有数据为空")
            if ret==-2:
                print("更新异常")
            if ret == -3:
                print("主键被修改,停止更新")
                QMessageBox.about(self,"Error","主键被修改")
            else:
                print("更新完成\n")

    # 查询
    def query(self):
        self.select_field_list.clear()
        for btn in self.btn_field_list:
            print(btn.isChecked())
            if btn.isChecked() == True:
                self.select_field_list.append(btn.text())

        print("self.select_field_list:", self.select_field_list)

        if self.select_field_list != []:

            # 根据所选字段和表构建查询语句:select field1,field2,...,fieldN from table
            str_sql = self.sf.auto_select(self.table, self.select_field_list)
            ret = self.sf.executeCMD(self.db_path, str_sql)
            print(ret)
            for i, data in enumerate(ret):
                print("{}->{}\n".format(i, data))

            # 打印数据
            self.show_table(self.select_field_list, ret)

        if self.select_field_list == []:
            self.tableView_content.setModel(self.model.clear())

    # 进行删除操作需要选中所有字段
    def delete_data(self):
        if self.table == "":
            print("未选择表")
            return
        if self.select_field_list == []:
            print("未选择字段")
            return
        if self.tableView_content.currentIndex().row() == -1:
            print("未选择数据")
            return
        else:
            del_row = self.tableView_content.currentIndex().row()
            print("选择{}行".format(del_row))

            # 主键index和获取主键
            key_idx, key = self.sf.find_primary_key(self.db_path, self.table)
            del_data = []
            # 读取当前行所有数据
            for i in range(self.len_col):
                if self.model.item(del_row, i).text() != None:
                    del_data.append(self.model.item(del_row, i).text())

            if len(del_data) != len(self.field_list):
                print("数据不全")
                return
            print("del data:", del_data)
            self.sf.delete(self.db_path, self.table, key, key_idx, del_data)
            self.query()

    def add_data(self):
        if self.db_path == "":
            print("未选择数据库")
            return
        if self.table == "":
            print("未选择表")
            return
        if self.select_field_list == []:
            print("未选择字段")
            return

        print("添加数据")
        self.add_data_ui = Add_Data_UI(self.db_path, self.table, self.field_list)
        self.add_data_ui.show()
        self.add_data_ui.signal_status.connect(self.query)
        # self.query()

    def flash_table(self):
        # 刷新数据库表
        self.table_list = self.sf.check_table(self.db_path)
        print("当前数据库含有表:", self.table_list)
        self.create_radiobox_table()

    def add_table(self):

        if self.db_path == "":
            print("没有选择数据库")
        else:
            self.add_table_ui = Add_Table_UI(self.db_path)
            self.add_table_ui.show()

            # 子窗口链接主窗口函数
            self.add_table_ui.signal_status.connect(self.flash_table)

    def del_table(self):
        if self.table == "":
            print("没有选择表")
            return
        print("当前选择表:{}".format(self.table))
        ret = QMessageBox.question(self, "delete table", "sure to delete this table?", QMessageBox.Yes | QMessageBox.No,
                                   QMessageBox.No)
        if ret == QMessageBox.Yes:
            self.sf.delete_table(self.db_path, self.table)
            self.tableView_content.setModel(self.model.clear())

            # 刷新数据库表
            self.table_list = self.sf.check_table(self.db_path)
            print("当前数据库含有表:", self.table_list)
            self.create_radiobox_table()