更改部分bug加入人脸识别锁机制
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
# This Python file uses the following encoding: utf-8
|
# This Python file uses the following encoding: utf-8
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from PyQt5.QtWidgets import QFileDialog
|
from PyQt5.QtWidgets import QFileDialog,QHeaderView
|
||||||
from PyQt5.QtWidgets import QApplication, QMainWindow, QStackedWidget, QWidget, QLayout, QLabel, QLineEdit, QPushButton, QMessageBox, QShortcut, QDialog,QTextEdit
|
from PyQt5.QtWidgets import QApplication, QMainWindow, QStackedWidget, QWidget, QLayout, QLabel, QLineEdit, QPushButton, QMessageBox, QShortcut, QDialog,QTextEdit
|
||||||
from PyQt5 import uic
|
from PyQt5 import uic
|
||||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QObject, QRunnable, QMutex, QTimer, QEvent
|
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QObject, QRunnable, QMutex, QTimer, QEvent
|
||||||
@ -455,8 +455,18 @@ class QFaceCameraViewPage(PageTemplate):
|
|||||||
self.face_verify_result = None # 用于存储人脸验证结果
|
self.face_verify_result = None # 用于存储人脸验证结果
|
||||||
|
|
||||||
self.auto_connect_serial()
|
self.auto_connect_serial()
|
||||||
# 串口管理
|
|
||||||
|
self.refresh()
|
||||||
|
|
||||||
|
header = self.table.horizontalHeader()
|
||||||
|
# 用户ID列固定宽度
|
||||||
|
self.table.setColumnWidth(0, 100)
|
||||||
|
# 用户名列自适应内容
|
||||||
|
header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
|
||||||
|
# 注册时间列填充剩余空间
|
||||||
|
header.setSectionResizeMode(2, QHeaderView.Stretch)
|
||||||
|
|
||||||
|
# 串口管理
|
||||||
def auto_connect_serial(self):
|
def auto_connect_serial(self):
|
||||||
ports = [p.device for p in serial.tools.list_ports.comports()]
|
ports = [p.device for p in serial.tools.list_ports.comports()]
|
||||||
if not ports:
|
if not ports:
|
||||||
@ -540,15 +550,15 @@ class QFaceCameraViewPage(PageTemplate):
|
|||||||
if msg_id == MID_REPLY:
|
if msg_id == MID_REPLY:
|
||||||
info = parse_reply(data)
|
info = parse_reply(data)
|
||||||
self.log(f"[REPLY] {info}")
|
self.log(f"[REPLY] {info}")
|
||||||
if info.get("mid") in (CMD_ENROLL, CMD_ENROLL_ITG) and info.get("result") == 0x00:
|
if info.get("mid") == CMD_ENROLL_ITG:
|
||||||
user_id = info.get("user_id")
|
if info.get("result") == 0x00:
|
||||||
# 如果用户名为空,使用用户ID作为用户名
|
user_id = info.get("user_id")
|
||||||
user_name = self.last_enroll_name if self.last_enroll_name else str(user_id)
|
if user_id:
|
||||||
if user_id: # 只需检查user_id存在即可,因为user_name已确保有值
|
if save_user(user_id):
|
||||||
if save_user(user_id, user_name):
|
self.log(f"[INFO] 用户ID={user_id} 已保存")
|
||||||
self.log(f"[INFO] 用户 {user_name}(ID={user_id}) 已保存")
|
else:
|
||||||
else:
|
inform_box : DialogInform = DialogInform()
|
||||||
QMessageBox.warning(self, "提示", f"用户ID {user_id} 已存在!")
|
inform_box.information("提示", f"用户ID {user_id} 已存在!")
|
||||||
elif info.get("mid") == CMD_VERIFY :
|
elif info.get("mid") == CMD_VERIFY :
|
||||||
|
|
||||||
if info.get("result") == 0x00:
|
if info.get("result") == 0x00:
|
||||||
@ -762,7 +772,9 @@ class APPWindow(QMainWindow):
|
|||||||
# self.setGeometry(0, 0, 1024, 768)
|
# self.setGeometry(0, 0, 1024, 768)
|
||||||
# self.stack.setGeometry(0, 0, 1024, 768)
|
# self.stack.setGeometry(0, 0, 1024, 768)
|
||||||
|
|
||||||
|
QFaceCameraViewPage.video_worker = None
|
||||||
|
QFaceCameraViewPage.ser = None
|
||||||
|
|
||||||
self.showFullScreen()
|
self.showFullScreen()
|
||||||
|
|
||||||
self.menu_sequence_list : PageTemplate = []
|
self.menu_sequence_list : PageTemplate = []
|
||||||
@ -875,10 +887,10 @@ class APPWindow(QMainWindow):
|
|||||||
for camera_thread in self.camera_thread_list:
|
for camera_thread in self.camera_thread_list:
|
||||||
thread_to_stop : CameraThread = camera_thread
|
thread_to_stop : CameraThread = camera_thread
|
||||||
|
|
||||||
if self.video_worker and self.video_worker.isRunning():
|
if QFaceCameraViewPage.video_worker and QFaceCameraViewPage.video_worker.isRunning():
|
||||||
self.video_worker.stop()
|
QFaceCameraViewPage.video_worker.stop()
|
||||||
self.video_worker.wait(300)
|
QFaceCameraViewPage.video_worker.wait(300)
|
||||||
if self.ser and getattr(self.ser,"is_open",False):
|
if QFaceCameraViewPage.ser and getattr(QFaceCameraViewPage.ser,"is_open",False):
|
||||||
self.close_serial()
|
self.close_serial()
|
||||||
if thread_to_stop != None :
|
if thread_to_stop != None :
|
||||||
thread_to_stop.close()
|
thread_to_stop.close()
|
||||||
|
|||||||
@ -93,7 +93,7 @@ color: rgb(207, 0, 13);</string>
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="statusTip">
|
<property name="statusTip">
|
||||||
<string>SwitchOn,Index=2,Action=CmdExecute, SelectImag=SR_001.png, groupstart=6</string>
|
<string>SwitchOn,Index=2,Action=CmdExecute, SelectImag=SR_001.png, password,groupstart=6</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@ -115,7 +115,7 @@ color: rgb(207, 0, 13);</string>
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="statusTip">
|
<property name="statusTip">
|
||||||
<string>SwitchOff,Index=3,Action=CmdExecute, SelectImag=SR_001.png</string>
|
<string>SwitchOff,Index=3,Action=CmdExecute, password,SelectImag=SR_001.png</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@ -218,7 +218,7 @@ color: rgb(207, 0, 13);</string>
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="statusTip">
|
<property name="statusTip">
|
||||||
<string>SwitchOff,Index=4,Action=CmdExecute, SelectImag=SR_001.png</string>
|
<string>SwitchOff,Index=4,Action=CmdExecute, password,SelectImag=SR_001.png</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
|
|||||||
@ -334,6 +334,22 @@ color: rgb(177, 229, 252);</string>
|
|||||||
<string>人脸框</string>
|
<string>人脸框</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QPushButton" name="btn_delete_user_id">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>240</y>
|
||||||
|
<width>80</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Index=0, Action=DeleteUser,SelectImag=IMxx_00F.png</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>删除用户</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="P05_01BG">
|
<widget class="QLabel" name="P05_01BG">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
@ -351,11 +367,40 @@ color: rgb(177, 229, 252);</string>
|
|||||||
<pixmap>../image/FaceCameraView.png</pixmap>
|
<pixmap>../image/FaceCameraView.png</pixmap>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QTableWidget" name="table">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>1080</x>
|
||||||
|
<y>520</y>
|
||||||
|
<width>821</width>
|
||||||
|
<height>371</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||||
|
</property>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>用户ID</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>用户名</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>注册时间</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
</widget>
|
||||||
<zorder>P05_01BG</zorder>
|
<zorder>P05_01BG</zorder>
|
||||||
<zorder>groupBox_sys</zorder>
|
<zorder>groupBox_sys</zorder>
|
||||||
<zorder>group_log</zorder>
|
<zorder>group_log</zorder>
|
||||||
<zorder>group_video</zorder>
|
<zorder>group_video</zorder>
|
||||||
<zorder>group_cmd</zorder>
|
<zorder>group_cmd</zorder>
|
||||||
|
<zorder>table</zorder>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import csv
|
||||||
import inspect
|
import inspect
|
||||||
import cv2
|
import cv2
|
||||||
import json
|
import json
|
||||||
@ -10,7 +11,7 @@ from PyQt5 import uic
|
|||||||
from PyQt5.QtGui import QImage, QPixmap, QColor,QBrush, QKeySequence, QIcon, QPalette
|
from PyQt5.QtGui import QImage, QPixmap, QColor,QBrush, QKeySequence, QIcon, QPalette
|
||||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QObject, QRunnable, QMutex, QTimer, QEvent, QSize, QDateTime
|
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QObject, QRunnable, QMutex, QTimer, QEvent, QSize, QDateTime
|
||||||
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QFrame, QWidget, QLayout, QLabel
|
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QFrame, QWidget, QLayout, QLabel
|
||||||
from PyQt5.QtWidgets import QLineEdit, QPushButton, QMessageBox, QShortcut, QDialog
|
from PyQt5.QtWidgets import QLineEdit, QPushButton, QMessageBox, QShortcut, QDialog,QTableWidgetItem
|
||||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||||
from Shared_CODE.CameraThread import CameraThread
|
from Shared_CODE.CameraThread import CameraThread
|
||||||
import menu_utils as utils
|
import menu_utils as utils
|
||||||
@ -22,7 +23,7 @@ from Shared_CODE.DialogModifyText import DialogModifyText
|
|||||||
from Shared_CODE.DialogInform import DialogInform
|
from Shared_CODE.DialogInform import DialogInform
|
||||||
from QT5_Project.Shared_CODE.FaceRecognitionProtocol import parse_reply
|
from QT5_Project.Shared_CODE.FaceRecognitionProtocol import parse_reply
|
||||||
from QT5_Project.Shared_CODE.DialogFaceEnrollItgSingle import EnrollItgSingleDialog
|
from QT5_Project.Shared_CODE.DialogFaceEnrollItgSingle import EnrollItgSingleDialog
|
||||||
from QT5_Project.Shared_CODE.DialogFaceUserManage import UserManageDialog
|
from QT5_Project.Shared_CODE.DialogFaceUserManage import UserManageDialog, load_users, save_user, save_users_list, CSV_FILE
|
||||||
|
|
||||||
from Shared_CODE.get_tip_prop import *
|
from Shared_CODE.get_tip_prop import *
|
||||||
from print_color import *
|
from print_color import *
|
||||||
@ -801,6 +802,8 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
print("密码认证成功")
|
print("密码认证成功")
|
||||||
|
|
||||||
elif choice == "face":
|
elif choice == "face":
|
||||||
|
# 初始化锁标志
|
||||||
|
self._face_verify_locked = True # 开始验证时锁定
|
||||||
# 人脸认证异步处理
|
# 人脸认证异步处理
|
||||||
face_frame = self.parent_window.P05_01_FaceCameraView
|
face_frame = self.parent_window.P05_01_FaceCameraView
|
||||||
face_frame.face_verify_result = None # 重置标志位
|
face_frame.face_verify_result = None # 重置标志位
|
||||||
@ -809,6 +812,12 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
timeout = system_parameter().get_verify_timeout()
|
timeout = system_parameter().get_verify_timeout()
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
||||||
|
# 停止并删除旧定时器
|
||||||
|
if hasattr(self, "_face_verify_timer"):
|
||||||
|
if self._face_verify_timer.isActive():
|
||||||
|
self._face_verify_timer.stop()
|
||||||
|
self._face_verify_timer.deleteLater()
|
||||||
|
|
||||||
# 创建定时器轮询标志位
|
# 创建定时器轮询标志位
|
||||||
self._face_verify_timer = QTimer(self)
|
self._face_verify_timer = QTimer(self)
|
||||||
self._face_verify_timer.setInterval(50) # 每50ms检查一次
|
self._face_verify_timer.setInterval(50) # 每50ms检查一次
|
||||||
@ -817,6 +826,7 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
nonlocal input
|
nonlocal input
|
||||||
if face_frame.face_verify_result is not None:
|
if face_frame.face_verify_result is not None:
|
||||||
self._face_verify_timer.stop()
|
self._face_verify_timer.stop()
|
||||||
|
self._face_verify_locked = False # 解锁
|
||||||
if face_frame.face_verify_result:
|
if face_frame.face_verify_result:
|
||||||
input = True
|
input = True
|
||||||
inform_box = DialogInform()
|
inform_box = DialogInform()
|
||||||
@ -828,10 +838,15 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
inform_box.information("提示", "人脸认证失败")
|
inform_box.information("提示", "人脸认证失败")
|
||||||
elif time.time() - start_time > timeout:
|
elif time.time() - start_time > timeout:
|
||||||
self._face_verify_timer.stop()
|
self._face_verify_timer.stop()
|
||||||
|
self._face_verify_locked = False # 解锁
|
||||||
input = False
|
input = False
|
||||||
inform_box = DialogInform()
|
inform_box = DialogInform()
|
||||||
inform_box.information("提示", "人脸认证超时")
|
inform_box.information("提示", "人脸认证超时")
|
||||||
|
# 解绑旧槽,绑定新槽
|
||||||
|
try:
|
||||||
|
self._face_verify_timer.timeout.disconnect()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
self._face_verify_timer.timeout.connect(check_face_result)
|
self._face_verify_timer.timeout.connect(check_face_result)
|
||||||
self._face_verify_timer.start()
|
self._face_verify_timer.start()
|
||||||
return # 异步处理,直接返回
|
return # 异步处理,直接返回
|
||||||
@ -875,6 +890,11 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
|
|
||||||
elif "FaceBox" in action_str:
|
elif "FaceBox" in action_str:
|
||||||
self.toggle_face_box()
|
self.toggle_face_box()
|
||||||
|
|
||||||
|
elif "DeleteUser" in action_str:
|
||||||
|
self.delete_user_by_id()
|
||||||
|
elif "UserCount" in action_str:
|
||||||
|
self.query_user_count()
|
||||||
|
|
||||||
self.virtual_widget_action_process(select_object, action_str)
|
self.virtual_widget_action_process(select_object, action_str)
|
||||||
|
|
||||||
@ -919,6 +939,12 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
elif "FaceBox" in action_str:
|
elif "FaceBox" in action_str:
|
||||||
self.toggle_face_box()
|
self.toggle_face_box()
|
||||||
|
|
||||||
|
elif "DeleteUser" in action_str:
|
||||||
|
self.delete_user_by_id()
|
||||||
|
|
||||||
|
elif "UserCount" in action_str:
|
||||||
|
self.query_user_count()
|
||||||
|
|
||||||
self.virtual_widget_action_process(select_object, action_str)
|
self.virtual_widget_action_process(select_object, action_str)
|
||||||
|
|
||||||
def search_menu_match_object(self, object) :
|
def search_menu_match_object(self, object) :
|
||||||
@ -936,7 +962,8 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
def do_verify(self):
|
def do_verify(self):
|
||||||
pd_val = 0
|
pd_val = 0
|
||||||
timeout_val = system_parameter().get_verify_timeout()
|
timeout_val = system_parameter().get_verify_timeout()
|
||||||
self.send(build_verify(pd_val, timeout_val))
|
face_send = self.parent_window.P05_01_FaceCameraView
|
||||||
|
face_send.send(build_verify(pd_val, timeout_val))
|
||||||
|
|
||||||
|
|
||||||
def do_enroll_itg_single(self):
|
def do_enroll_itg_single(self):
|
||||||
@ -1019,6 +1046,69 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
else:
|
else:
|
||||||
self.log("[WARN] 串口未连接,无法控制人脸框")
|
self.log("[WARN] 串口未连接,无法控制人脸框")
|
||||||
|
|
||||||
|
def delete_user_by_id(self, CSV_FILE = CSV_FILE):
|
||||||
|
users = load_users()
|
||||||
|
|
||||||
|
# 弹出对话框选择用户ID
|
||||||
|
dialog_modify_text = DialogModifyValue(self)
|
||||||
|
caption_str = "选择用户ID删除"
|
||||||
|
dialog_modify_text.update_modify_info("", 0, caption_str)
|
||||||
|
|
||||||
|
if dialog_modify_text.exec() != QDialog.Accepted:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 获取用户输入的ID并转换为整数
|
||||||
|
try:
|
||||||
|
user_id = int(dialog_modify_text.value)
|
||||||
|
except ValueError:
|
||||||
|
DialogInform(self).information("提示", "请输入有效数字ID")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 查找用户
|
||||||
|
user = next((u for u in users if u["user_id"] == user_id), None)
|
||||||
|
if not user:
|
||||||
|
DialogInform(self).information("提示", "用户不存在")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 1️⃣ 下发删除命令
|
||||||
|
self.send(build_delete_user(user_id))
|
||||||
|
|
||||||
|
# 2️⃣ 删除 CSV 文件对应行
|
||||||
|
if os.path.exists(CSV_FILE):
|
||||||
|
with open(CSV_FILE, "r", encoding="utf-8", newline="") as f:
|
||||||
|
reader = csv.DictReader(f)
|
||||||
|
fieldnames = reader.fieldnames
|
||||||
|
new_rows = [row for row in reader if str(row.get("user_id")) != str(user_id)]
|
||||||
|
|
||||||
|
with open(CSV_FILE, "w", encoding="utf-8", newline="") as f:
|
||||||
|
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
||||||
|
writer.writeheader()
|
||||||
|
writer.writerows(new_rows)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
DialogInform(self).information("提示", f"删除失败: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 3️⃣ 更新内存用户列表
|
||||||
|
users = [u for u in users if u["user_id"] != user_id]
|
||||||
|
save_users_list(users)
|
||||||
|
|
||||||
|
# 4️⃣ 提示删除成功
|
||||||
|
DialogInform(self).information("提示", f"用户 {user.get('user_name', '')} (ID={user_id}) 已删除")
|
||||||
|
|
||||||
|
|
||||||
|
def query_user_count(self):
|
||||||
|
self.send(build_get_all_userid())
|
||||||
|
|
||||||
|
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", "")))
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#刷新屏幕上的系统信息, 例如时间日期之类
|
#刷新屏幕上的系统信息, 例如时间日期之类
|
||||||
|
|||||||
@ -57,24 +57,23 @@ def save_users_list(users):
|
|||||||
w.writerow([u.get("user_id", ""), u.get("user_name", ""), u.get("created_at", "")])
|
w.writerow([u.get("user_id", ""), u.get("user_name", ""), u.get("created_at", "")])
|
||||||
|
|
||||||
|
|
||||||
def save_user(user_id: int, user_name: str) -> bool:
|
def save_user(user_id: int) -> bool:
|
||||||
users = load_users()
|
users = load_users()
|
||||||
for u in users:
|
for u in users:
|
||||||
if str(u["user_id"]) == str(user_id):
|
if str(u["user_id"]) == str(user_id):
|
||||||
return False
|
return False
|
||||||
created_at = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
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})
|
users.append({"user_id": str(user_id), "user_name": str(user_id), "created_at": created_at})
|
||||||
save_users_list(users)
|
save_users_list(users)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class UserManageDialog(QDialog):
|
class UserManageDialog(QDialog):
|
||||||
def __init__(self, parent=None, send_func=None):
|
def __init__(self, parent=None, send_func=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.send_func = send_func
|
self.send_func = send_func
|
||||||
uic.loadUi(users_ui_file_path, self)
|
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_get.clicked.connect(self.get_from_device)
|
||||||
self.btn_del_all.clicked.connect(self.delete_all_users)
|
self.btn_del_all.clicked.connect(self.delete_all_users)
|
||||||
self.refresh()
|
self.refresh()
|
||||||
@ -105,31 +104,15 @@ class UserManageDialog(QDialog):
|
|||||||
QShortcut(QKeySequence(Qt.Key_Home), self, activated=self.key_escape_process)
|
QShortcut(QKeySequence(Qt.Key_Home), self, activated=self.key_escape_process)
|
||||||
|
|
||||||
QShortcut(QKeySequence(Qt.Key_Return), self, activated=self.key_enter_process) # 普通回车
|
QShortcut(QKeySequence(Qt.Key_Return), self, activated=self.key_enter_process) # 普通回车
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
users = load_users()
|
users = load_users()
|
||||||
self.table.setRowCount(len(users))
|
self.table.setRowCount(len(users))
|
||||||
for r, u in enumerate(users):
|
for r, u in enumerate(users):
|
||||||
self.table.setItem(r, 0, QTableWidgetItem(str(u.get("user_id", ""))))
|
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, 1, QTableWidgetItem(u.get("user_name", "")))
|
||||||
self.table.setItem(r, 2, QTableWidgetItem(u.get("created_at", "")))
|
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):
|
def get_from_device(self):
|
||||||
self.send_func(build_get_all_userid())
|
self.send_func(build_get_all_userid())
|
||||||
|
|||||||
@ -1 +1,3 @@
|
|||||||
1,1,2025-09-13 10:06:01
|
1,1,2025-09-15 10:48:28
|
||||||
|
2,2,2025-09-15 10:56:46
|
||||||
|
3,3,2025-09-15 11:00:04
|
||||||
|
|||||||
|
Reference in New Issue
Block a user