# -*- coding: utf-8 -*- from __future__ import annotations import sys, os, io, csv, time, datetime from typing import Callable, Optional # PyQt5 from PyQt5 import QtWidgets, uic from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QSize from PyQt5.QtGui import QImage, QPixmap, QKeySequence from PyQt5.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QComboBox, QTextEdit, QFileDialog, QMessageBox, QGroupBox, QGridLayout, QDialog, QFormLayout, QSpinBox, QCheckBox, QLineEdit, QTableWidget, QTableWidgetItem,QDialogButtonBox,QShortcut, QHeaderView ) sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import cv2 from PIL import Image import serial import serial.tools.list_ports # ---------- 协议导入---------- from Shared_CODE.FaceRecognitionProtocol import ( build_reset, build_uvc_view, build_face_view, build_verify, build_enroll_itg_single, build_delete_all, build_get_all_userid,build_delete_user, MID_REPLY, MID_NOTE, CMD_ENROLL, CMD_ENROLL_ITG, parse_reply, parse_note ) sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))) ui_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../Shared_UI')) users_ui_file_path = os.path.join(ui_path, "DialogUsers.ui") CSV_FILE = os.path.join(ui_path, "users.csv") # -------------------- CSV 工具 --------------------" def load_users(): users = [] try: with open(CSV_FILE, "r", encoding="utf-8") as f: reader = csv.reader(f) for row in reader: if len(row) >= 2: user = {"user_id": row[0], "user_name": row[1]} user["created_at"] = row[2] if len(row) >= 3 else "" users.append(user) except FileNotFoundError: pass return users def save_users_list(users): with open(CSV_FILE, "w", newline="", encoding="utf-8") as f: w = csv.writer(f) for u in users: w.writerow([u.get("user_id", ""), u.get("user_name", ""), u.get("created_at", "")]) def save_user(user_id: int, user_name: str) -> bool: users = load_users() for u in users: if str(u["user_id"]) == str(user_id): return False created_at = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") users.append({"user_id": str(user_id), "user_name": user_name, "created_at": created_at}) save_users_list(users) return True class UserManageDialog(QDialog): def __init__(self, parent=None, send_func=None): super().__init__(parent) self.send_func = send_func uic.loadUi(users_ui_file_path, self) self.btn_delete.clicked.connect(self.delete_selected) self.btn_refresh.clicked.connect(self.refresh) self.btn_get.clicked.connect(self.get_from_device) self.btn_del_all.clicked.connect(self.delete_all_users) self.refresh() header = self.table.horizontalHeader() # 用户ID列固定宽度 self.table.setColumnWidth(0, 100) # 用户名列自适应内容 header.setSectionResizeMode(1, QHeaderView.ResizeToContents) # 注册时间列填充剩余空间 header.setSectionResizeMode(2, QHeaderView.Stretch) self.message_timer = QTimer() self.message_timer.timeout.connect(self.close_dialog_timeout) self.setWindowTitle("消息提示") self.setWindowFlag(Qt.FramelessWindowHint) button_box : QDialogButtonBox = self.buttonBox ok_button = button_box.button(QDialogButtonBox.Ok) if ok_button: ok_button.setText('确定') else: button_box.addButton(QDialogButtonBox.Ok) #定义4个快捷键, Key_Enter, Key_Escape经常被各类程序模块使用, 用Key_End, 与Key_Home来代替 QShortcut(QKeySequence(Qt.Key_PageDown), self, activated=self.key_enter_process) QShortcut(QKeySequence(Qt.Key_PageUp), self, activated=self.key_escape_process) QShortcut(QKeySequence(Qt.Key_End), self, activated=self.key_enter_process) QShortcut(QKeySequence(Qt.Key_Home), self, activated=self.key_escape_process) QShortcut(QKeySequence(Qt.Key_Return), self, activated=self.key_enter_process) # 普通回车 def refresh(self): users = load_users() self.table.setRowCount(len(users)) for r, u in enumerate(users): self.table.setItem(r, 0, QTableWidgetItem(str(u.get("user_id", "")))) self.table.setItem(r, 1, QTableWidgetItem(u.get("user_name", ""))) self.table.setItem(r, 2, QTableWidgetItem(u.get("created_at", ""))) def delete_selected(self): row = self.table.currentRow() if row < 0: QMessageBox.warning(self, "提示", "删除选择用户") return uid = self.table.item(row, 0).text() uname = self.table.item(row, 1).text() try: uid_int = int(uid) self.send_func(build_delete_user(uid_int)) except: pass users = [u for u in load_users() if str(u["user_id"]) != uid] save_users_list(users) self.refresh() QMessageBox.information(self, "提示", f"用户 {uname}(ID={uid}) 已删除") def get_from_device(self): self.send_func(build_get_all_userid()) def delete_all_users(self): self.send_func(build_delete_all()) save_users_list([]) self.refresh() QMessageBox.information(self, "提示", "已请求删除所有用户并清空本地记录") def key_enter_process(self): button_box : QDialogButtonBox = self.buttonBox select_button = button_box.button(QDialogButtonBox.Ok) if select_button: select_button.click() def key_escape_process(self): button_box : QDialogButtonBox = self.buttonBox select_button = button_box.button(QDialogButtonBox.Cancel) if select_button: select_button.click() #消息超时 def close_dialog_timeout(self): self.key_enter_process() if __name__ == '__main__': app = QApplication(sys.argv) dialog = UserManageDialog() dialog.exec() sys.exit(0)