1.人脸验证执行操作成功
2.UI底图进行修改
@ -19,7 +19,7 @@ import uart_group_config as group_config
|
|||||||
from mqtt_device import class_comm_mqtt_thread, class_comm_mqtt_interface
|
from mqtt_device import class_comm_mqtt_thread, class_comm_mqtt_interface
|
||||||
from print_color import *
|
from print_color import *
|
||||||
from Shared_CODE.get_tip_prop import *
|
from Shared_CODE.get_tip_prop import *
|
||||||
from QT5_Project.Shared_CODE.DialogFaceVerify import VerifyDialog
|
from QT5_Project.Shared_CODE.FaceRecognitionProtocol import *
|
||||||
from QT5_Project.Shared_CODE.DialogFaceEnrollItgSingle import EnrollItgSingleDialog
|
from QT5_Project.Shared_CODE.DialogFaceEnrollItgSingle import EnrollItgSingleDialog
|
||||||
from QT5_Project.Shared_CODE.DialogFaceUserManage import UserManageDialog, save_user, load_users, save_users_list
|
from QT5_Project.Shared_CODE.DialogFaceUserManage import UserManageDialog, save_user, load_users, save_users_list
|
||||||
|
|
||||||
@ -441,18 +441,6 @@ class QFaceCameraViewPage(PageTemplate):
|
|||||||
self.current_video_mode = 0
|
self.current_video_mode = 0
|
||||||
self.current_face_box = 0
|
self.current_face_box = 0
|
||||||
|
|
||||||
|
|
||||||
#信号绑定
|
|
||||||
self.btn_video.clicked.connect(self.toggle_video)
|
|
||||||
self.btn_video_mode.clicked.connect(self.toggle_video_mode)
|
|
||||||
self.chk_face_box.stateChanged.connect(self.toggle_face_box)
|
|
||||||
self.btn_save.clicked.connect(self.save_log)
|
|
||||||
self.btn_reset.clicked.connect(lambda: self.send(build_reset()))
|
|
||||||
self.btn_enroll.clicked.connect(self.do_enroll_itg_single)
|
|
||||||
self.btn_users.clicked.connect(self.do_manage_users)
|
|
||||||
# self.btn_verify.clicked.connect(self.do_verify)
|
|
||||||
|
|
||||||
|
|
||||||
# 定时器:串口监控 & 视频重连
|
# 定时器:串口监控 & 视频重连
|
||||||
self.t_port = QTimer(self)
|
self.t_port = QTimer(self)
|
||||||
self.t_port.setInterval(1000)
|
self.t_port.setInterval(1000)
|
||||||
@ -464,6 +452,8 @@ class QFaceCameraViewPage(PageTemplate):
|
|||||||
self.t_video.timeout.connect(self._check_video)
|
self.t_video.timeout.connect(self._check_video)
|
||||||
self.t_video.start()
|
self.t_video.start()
|
||||||
|
|
||||||
|
self.face_verify_result = None # 用于存储人脸验证结果
|
||||||
|
|
||||||
self.auto_connect_serial()
|
self.auto_connect_serial()
|
||||||
# 串口管理
|
# 串口管理
|
||||||
|
|
||||||
@ -535,91 +525,6 @@ class QFaceCameraViewPage(PageTemplate):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log(f"[ERR] write: {e}")
|
self.log(f"[ERR] write: {e}")
|
||||||
|
|
||||||
# 业务功能
|
|
||||||
# def do_verify(self):
|
|
||||||
# dlg = VerifyDialog(self)
|
|
||||||
# if dlg.exec_() == QDialog.Accepted:
|
|
||||||
# pd_val, timeout_val = dlg.values()
|
|
||||||
# self.send(build_verify(pd_val, timeout_val))
|
|
||||||
|
|
||||||
|
|
||||||
# def do_enroll_itg_single(self):
|
|
||||||
# dlg = EnrollItgSingleDialog(self)
|
|
||||||
# if dlg.exec_() == QDialog.Accepted:
|
|
||||||
# admin_val, uname, face_dir, timeout_val, itg_val = dlg.values()
|
|
||||||
# self.last_enroll_name = uname
|
|
||||||
# self.send(build_enroll_itg_single(admin_val, uname, face_dir, timeout_val, itg_val))
|
|
||||||
|
|
||||||
# def do_manage_users(self):
|
|
||||||
# UserManageDialog(self, self.send).exec_()
|
|
||||||
|
|
||||||
def toggle_video(self):
|
|
||||||
running = self.video_worker and self.video_worker.isRunning()
|
|
||||||
if running:
|
|
||||||
self.video_worker.stop()
|
|
||||||
self.video_worker.wait(300)
|
|
||||||
self.video_worker = None
|
|
||||||
self.video_label.setText("未打开")
|
|
||||||
self.video_label.setPixmap(QPixmap())
|
|
||||||
self.btn_video.setText("打开视频")
|
|
||||||
self.log("[INFO] 视频已关闭")
|
|
||||||
inform_box : DialogInform = DialogInform()
|
|
||||||
inform_box.information("提示", "视频已关闭")
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.video_label.width()<50 or self.video_label.height()<50:
|
|
||||||
self.video_label.setMinimumSize(360,480)
|
|
||||||
|
|
||||||
self.video_worker = VideoWorker(cam_index=0, target_size=self.video_label.size())
|
|
||||||
self.video_worker.pixmap_ready.connect(self.video_label.setPixmap)
|
|
||||||
self.video_worker.log_message.connect(self.log)
|
|
||||||
self.video_worker.start()
|
|
||||||
self.btn_video.setText("关闭视频")
|
|
||||||
self.log("[INFO] 正在打开视频")
|
|
||||||
inform_box : DialogInform = DialogInform()
|
|
||||||
inform_box.information("提示", "正在打开视频")
|
|
||||||
|
|
||||||
def toggle_video_mode(self):
|
|
||||||
if self.current_video_mode==0:
|
|
||||||
self.send_uvc(0)
|
|
||||||
self.current_video_mode=1
|
|
||||||
self.log("[INFO] 已切换到红外视频模式")
|
|
||||||
inform_box : DialogInform = DialogInform()
|
|
||||||
inform_box.information("提示", "已切换到红外视频模式")
|
|
||||||
else:
|
|
||||||
self.send_uvc(1)
|
|
||||||
self.current_video_mode=0
|
|
||||||
self.log("[INFO] 已切换到彩色视频模式")
|
|
||||||
inform_box : DialogInform = DialogInform()
|
|
||||||
inform_box.information("提示", "已切换到彩色视频模式")
|
|
||||||
|
|
||||||
def toggle_face_box(self, state):
|
|
||||||
if state==Qt.Checked:
|
|
||||||
self.face_box_enabled=True
|
|
||||||
self.send_face_box(1)
|
|
||||||
self.log("[INFO] 人脸框已开启")
|
|
||||||
inform_box : DialogInform = DialogInform()
|
|
||||||
inform_box.information("提示", "人脸框已开启")
|
|
||||||
else:
|
|
||||||
self.face_box_enabled=False
|
|
||||||
self.send_face_box(0)
|
|
||||||
self.log("[INFO] 人脸框已关闭")
|
|
||||||
inform_box : DialogInform = DialogInform()
|
|
||||||
inform_box.information("提示", "人脸框已关闭")
|
|
||||||
|
|
||||||
# ---------------- 发送指令 ----------------
|
|
||||||
def send_uvc(self, mode):
|
|
||||||
if self.ser and getattr(self.ser,"is_open",False):
|
|
||||||
self.ser.write(build_uvc_view(mode))
|
|
||||||
else:
|
|
||||||
self.log("[WARN] 串口未连接,无法切换视频模式")
|
|
||||||
|
|
||||||
def send_face_box(self, state):
|
|
||||||
if self.ser and getattr(self.ser,"is_open",False):
|
|
||||||
self.ser.write(build_face_view(state))
|
|
||||||
else:
|
|
||||||
self.log("[WARN] 串口未连接,无法控制人脸框")
|
|
||||||
|
|
||||||
# ---------------- 定时器检测 ----------------
|
# ---------------- 定时器检测 ----------------
|
||||||
def _check_video(self):
|
def _check_video(self):
|
||||||
if self.video_worker and not self.video_worker.isRunning():
|
if self.video_worker and not self.video_worker.isRunning():
|
||||||
@ -644,6 +549,15 @@ class QFaceCameraViewPage(PageTemplate):
|
|||||||
self.log(f"[INFO] 用户 {user_name}(ID={user_id}) 已保存")
|
self.log(f"[INFO] 用户 {user_name}(ID={user_id}) 已保存")
|
||||||
else:
|
else:
|
||||||
QMessageBox.warning(self, "提示", f"用户ID {user_id} 已存在!")
|
QMessageBox.warning(self, "提示", f"用户ID {user_id} 已存在!")
|
||||||
|
elif info.get("mid") == CMD_VERIFY :
|
||||||
|
|
||||||
|
if info.get("result") == 0x00:
|
||||||
|
user_id = info.get("user_id")
|
||||||
|
print(f"[INFO] 用户(ID={user_id}) 验证通过")
|
||||||
|
self.face_verify_result = True
|
||||||
|
else:
|
||||||
|
self.face_verify_result = False
|
||||||
|
|
||||||
elif msg_id == MID_NOTE:
|
elif msg_id == MID_NOTE:
|
||||||
info = parse_note(data)
|
info = parse_note(data)
|
||||||
self.log(f"[NOTE] {info}")
|
self.log(f"[NOTE] {info}")
|
||||||
@ -848,16 +762,6 @@ 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)
|
||||||
|
|
||||||
self.ser = None
|
|
||||||
self.worker = SerialWorker(lambda: self.ser)
|
|
||||||
self.worker.frame_received.connect(self.on_frame)
|
|
||||||
self.worker.log_message.connect(self.log)
|
|
||||||
self.worker.start()
|
|
||||||
self.video_worker = None
|
|
||||||
self.last_port = None
|
|
||||||
self.last_enroll_name = ""
|
|
||||||
self.current_video_mode = 0
|
|
||||||
self.current_face_box = 0
|
|
||||||
|
|
||||||
self.showFullScreen()
|
self.showFullScreen()
|
||||||
|
|
||||||
@ -923,32 +827,6 @@ class APPWindow(QMainWindow):
|
|||||||
|
|
||||||
test_init = system_parameter()
|
test_init = system_parameter()
|
||||||
set_screen_blanking_time(test_init.get_screen_blanking_time())
|
set_screen_blanking_time(test_init.get_screen_blanking_time())
|
||||||
###########################################################################
|
|
||||||
def on_frame(self, fr: dict):
|
|
||||||
self.log("< " + fr["raw"].hex(" "))
|
|
||||||
msg_id = fr.get("msg_id")
|
|
||||||
data = fr.get("data", b"")
|
|
||||||
|
|
||||||
if msg_id == MID_REPLY:
|
|
||||||
info = parse_reply(data)
|
|
||||||
self.log(f"[REPLY] {info}")
|
|
||||||
if info.get("mid") in (CMD_ENROLL, CMD_ENROLL_ITG) and info.get("result") == 0x00:
|
|
||||||
user_id = info.get("user_id")
|
|
||||||
user_name = self.last_enroll_name or ""
|
|
||||||
if user_id and user_name:
|
|
||||||
if save_user(user_id, user_name):
|
|
||||||
self.log(f"[INFO] 用户 {user_name}(ID={user_id}) 已保存")
|
|
||||||
else:
|
|
||||||
QMessageBox.warning(self, "提示", f"用户ID {user_id} 已存在!")
|
|
||||||
elif msg_id == MID_NOTE:
|
|
||||||
info = parse_note(data)
|
|
||||||
self.log(f"[NOTE] {info}")
|
|
||||||
|
|
||||||
def log(self, s: str):
|
|
||||||
ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
print(f"[{ts}] {s}") # 控制台打印日志
|
|
||||||
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
def search_page_widget(self, page) :
|
def search_page_widget(self, page) :
|
||||||
for list_item in self.allpages_list:
|
for list_item in self.allpages_list:
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 355 KiB |
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 93 KiB |
@ -171,22 +171,6 @@ color: rgb(170, 0, 0);</string>
|
|||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QPushButton" name="btn_video">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>200</x>
|
|
||||||
<y>20</y>
|
|
||||||
<width>80</width>
|
|
||||||
<height>23</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="statusTip">
|
|
||||||
<string>Index=0</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>打开视频</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QGroupBox" name="group_cmd">
|
<widget class="QGroupBox" name="group_cmd">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
@ -229,28 +213,12 @@ color: rgb(170, 0, 0);</string>
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="statusTip">
|
<property name="statusTip">
|
||||||
<string>Index=0, Action=Videomode,SelectImag=IMxx_00F.png</string>
|
<string>Index=0, Action=VideoMode,SelectImag=IMxx_00F.png</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>视频模式</string>
|
<string>视频模式</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QCheckBox" name="chk_face_box">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>12</x>
|
|
||||||
<y>88</y>
|
|
||||||
<width>85</width>
|
|
||||||
<height>21</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="statusTip">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>显示人脸框</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QPushButton" name="btn_verify">
|
<widget class="QPushButton" name="btn_verify">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
@ -277,7 +245,7 @@ color: rgb(170, 0, 0);</string>
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="statusTip">
|
<property name="statusTip">
|
||||||
<string>Index=0, Action=Enroll,SelectImag=IMxx_00F.png</string>
|
<string>Index=0, Action=EnrollItgSingle,SelectImag=IMxx_00F.png</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>ITG注册</string>
|
<string>ITG注册</string>
|
||||||
@ -303,7 +271,7 @@ color: rgb(170, 0, 0);</string>
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>210</y>
|
<y>310</y>
|
||||||
<width>120</width>
|
<width>120</width>
|
||||||
<height>25</height>
|
<height>25</height>
|
||||||
</rect>
|
</rect>
|
||||||
@ -334,6 +302,38 @@ color: rgb(177, 229, 252);</string>
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QPushButton" name="btn_video">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>210</y>
|
||||||
|
<width>80</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Index=0, Action=ConnectCamera,password,SelectImag=IMxx_00F.png</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>打开视频</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="btn_face_mode">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>90</y>
|
||||||
|
<width>80</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="statusTip">
|
||||||
|
<string>Index=0, Action=FaceBox,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">
|
||||||
|
|||||||
@ -864,47 +864,11 @@ color: rgb(207, 0, 13);</string>
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLineEdit" name="FaceRecogTimeoutEdit">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>880</x>
|
|
||||||
<y>640</y>
|
|
||||||
<width>120</width>
|
|
||||||
<height>25</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Arial</family>
|
|
||||||
<pointsize>16</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="statusTip">
|
|
||||||
<string>System=FaceRecogTimeout, Action=ModifySystem, Index=13,SelectImag=P4_ParaSelect.png, password</string>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">background-color: rgba(85, 170, 127,0);
|
|
||||||
color: rgb(177, 229, 252);</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<zorder>sys_P00_2</zorder>
|
<zorder>sys_P00_2</zorder>
|
||||||
<zorder>sys_P00_3</zorder>
|
<zorder>sys_P00_3</zorder>
|
||||||
<zorder>BindNum_Title</zorder>
|
<zorder>BindNum_Title</zorder>
|
||||||
<zorder>sys_home</zorder>
|
<zorder>sys_home</zorder>
|
||||||
<zorder>sys_menu</zorder>
|
<zorder>sys_menu</zorder>
|
||||||
<zorder>FaceRecogTimeoutEdit</zorder>
|
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="indicator_Label">
|
<widget class="QLabel" name="indicator_Label">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
|
|||||||
@ -801,36 +801,124 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
print("密码认证成功")
|
print("密码认证成功")
|
||||||
|
|
||||||
elif choice == "face":
|
elif choice == "face":
|
||||||
# face_page = self.parent_window.P05_01_FaceCameraView
|
# 人脸认证异步处理
|
||||||
|
face_frame = self.parent_window.P05_01_FaceCameraView
|
||||||
|
face_frame.face_verify_result = None # 重置标志位
|
||||||
|
self.do_verify() # 发送 CMD_VERIFY
|
||||||
|
|
||||||
|
timeout = system_parameter().get_verify_timeout()
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
# 创建定时器轮询标志位
|
||||||
|
self._face_verify_timer = QTimer(self)
|
||||||
|
self._face_verify_timer.setInterval(50) # 每50ms检查一次
|
||||||
|
|
||||||
|
def check_face_result():
|
||||||
|
nonlocal input
|
||||||
|
if face_frame.face_verify_result is not None:
|
||||||
|
self._face_verify_timer.stop()
|
||||||
|
if face_frame.face_verify_result:
|
||||||
input = True
|
input = True
|
||||||
|
inform_box = DialogInform()
|
||||||
|
inform_box.information("提示", "人脸认证成功")
|
||||||
|
self._after_face_verify(select_object, action_str)
|
||||||
else:
|
else:
|
||||||
|
input = False
|
||||||
|
inform_box = DialogInform()
|
||||||
|
inform_box.information("提示", "人脸认证失败")
|
||||||
|
elif time.time() - start_time > timeout:
|
||||||
|
self._face_verify_timer.stop()
|
||||||
|
input = False
|
||||||
|
inform_box = DialogInform()
|
||||||
|
inform_box.information("提示", "人脸认证超时")
|
||||||
|
|
||||||
|
self._face_verify_timer.timeout.connect(check_face_result)
|
||||||
|
self._face_verify_timer.start()
|
||||||
|
return # 异步处理,直接返回
|
||||||
|
else:
|
||||||
|
# 无认证要求,直接通过
|
||||||
input = True
|
input = True
|
||||||
|
|
||||||
|
# ---------------- 认证成功后执行操作 ----------------
|
||||||
if input:
|
if input:
|
||||||
if "CmdExecute" in action_str:
|
if "CmdExecute" in action_str:
|
||||||
mqtt_name = get_tip_mqtt_name(tip_str)
|
mqtt_name = get_tip_mqtt_name(tip_str)
|
||||||
unique_name = self.get_unique_name_from_object(select_object)
|
unique_name = self.get_unique_name_from_object(select_object)
|
||||||
if mqtt_name != None and unique_name != None:
|
if mqtt_name and unique_name and self.mqtt_thread and len(mqtt_name) > 0:
|
||||||
if len(mqtt_name) > 0 and self.mqtt_thread != None:
|
|
||||||
publish_topic = "request/action/" + unique_name
|
publish_topic = "request/action/" + unique_name
|
||||||
publish_message = '{"name" : "%s"}'%(mqtt_name)
|
publish_message = '{"name" : "%s"}' % mqtt_name
|
||||||
self.mqtt_publish_and_wait_response(publish_topic, publish_message, select_object, 1000)
|
self.mqtt_publish_and_wait_response(publish_topic, publish_message, select_object, 1000)
|
||||||
|
|
||||||
elif "ModifySystem" in action_str:
|
elif "ModifySystem" in action_str:
|
||||||
self.on_system_param_modify(tip_str)
|
self.on_system_param_modify(tip_str)
|
||||||
elif "Modify" in action_str :
|
|
||||||
if isinstance(select_object, QLineEdit) :
|
elif "Modify" in action_str and isinstance(select_object, QLineEdit):
|
||||||
self.on_line_edit_modify_click(select_object)
|
self.on_line_edit_modify_click(select_object)
|
||||||
|
|
||||||
elif "Users" in action_str:
|
elif "Users" in action_str:
|
||||||
self.do_manage_users()
|
self.do_manage_users()
|
||||||
|
|
||||||
elif "Verify" in action_str:
|
elif "Verify" in action_str:
|
||||||
self.do_verify()
|
self.do_verify()
|
||||||
|
|
||||||
elif "EnrollItgSingle" in action_str:
|
elif "EnrollItgSingle" in action_str:
|
||||||
self.do_enroll_itg_single()
|
self.do_enroll_itg_single()
|
||||||
|
|
||||||
elif "Reset" in action_str:
|
elif "Reset" in action_str:
|
||||||
self.reset_command()
|
self.reset_command()
|
||||||
|
|
||||||
|
elif "ConnectCamera" in action_str:
|
||||||
|
self.connectcamera()
|
||||||
|
|
||||||
|
elif "VideoMode" in action_str:
|
||||||
|
self.toggle_video_mode()
|
||||||
|
|
||||||
|
elif "FaceBox" in action_str:
|
||||||
|
self.toggle_face_box()
|
||||||
|
|
||||||
|
self.virtual_widget_action_process(select_object, action_str)
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------ 后续操作回调 ------------------
|
||||||
|
def _after_face_verify(self, select_object, action_str):
|
||||||
|
"""
|
||||||
|
人脸认证成功后调用,继续执行后续动作
|
||||||
|
"""
|
||||||
|
if "CmdExecute" in action_str:
|
||||||
|
mqtt_name = get_tip_mqtt_name(select_object.statusTip())
|
||||||
|
unique_name = self.get_unique_name_from_object(select_object)
|
||||||
|
if mqtt_name and unique_name and self.mqtt_thread and len(mqtt_name) > 0:
|
||||||
|
publish_topic = "request/action/" + unique_name
|
||||||
|
publish_message = '{"name" : "%s"}' % mqtt_name
|
||||||
|
self.mqtt_publish_and_wait_response(publish_topic, publish_message, select_object, 1000)
|
||||||
|
|
||||||
|
elif "ModifySystem" in action_str:
|
||||||
|
self.on_system_param_modify(select_object.statusTip())
|
||||||
|
|
||||||
|
elif "Modify" in action_str and isinstance(select_object, QLineEdit):
|
||||||
|
self.on_line_edit_modify_click(select_object)
|
||||||
|
|
||||||
|
elif "Users" in action_str:
|
||||||
|
self.do_manage_users()
|
||||||
|
|
||||||
|
elif "Verify" in action_str:
|
||||||
|
self.do_verify()
|
||||||
|
|
||||||
|
elif "EnrollItgSingle" in action_str:
|
||||||
|
self.do_enroll_itg_single()
|
||||||
|
|
||||||
|
elif "Reset" in action_str:
|
||||||
|
self.reset_command()
|
||||||
|
|
||||||
|
elif "ConnectCamera" in action_str:
|
||||||
|
self.connectcamera()
|
||||||
|
|
||||||
|
elif "VideoMode" in action_str:
|
||||||
|
self.toggle_video_mode()
|
||||||
|
|
||||||
|
elif "FaceBox" in action_str:
|
||||||
|
self.toggle_face_box()
|
||||||
|
|
||||||
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) :
|
||||||
@ -850,6 +938,7 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
timeout_val = system_parameter().get_verify_timeout()
|
timeout_val = system_parameter().get_verify_timeout()
|
||||||
self.send(build_verify(pd_val, timeout_val))
|
self.send(build_verify(pd_val, timeout_val))
|
||||||
|
|
||||||
|
|
||||||
def do_enroll_itg_single(self):
|
def do_enroll_itg_single(self):
|
||||||
dlg = EnrollItgSingleDialog(self)
|
dlg = EnrollItgSingleDialog(self)
|
||||||
if dlg.exec_() == QDialog.Accepted:
|
if dlg.exec_() == QDialog.Accepted:
|
||||||
@ -863,6 +952,74 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
def reset_command(self):
|
def reset_command(self):
|
||||||
self.send(build_reset())
|
self.send(build_reset())
|
||||||
|
|
||||||
|
def connectcamera(self):
|
||||||
|
running = self.video_worker and self.video_worker.isRunning()
|
||||||
|
if running:
|
||||||
|
self.video_worker.stop()
|
||||||
|
self.video_worker.wait(300)
|
||||||
|
self.video_worker = None
|
||||||
|
self.video_label.setText("未打开")
|
||||||
|
self.video_label.setPixmap(QPixmap())
|
||||||
|
self.btn_video.setText("打开视频")
|
||||||
|
self.log("[INFO] 视频已关闭")
|
||||||
|
inform_box : DialogInform = DialogInform()
|
||||||
|
inform_box.information("提示", "视频已关闭")
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.video_label.width()<50 or self.video_label.height()<50:
|
||||||
|
self.video_label.setMinimumSize(360,480)
|
||||||
|
|
||||||
|
self.video_worker = VideoWorker(cam_index=0, target_size=self.video_label.size())
|
||||||
|
self.video_worker.pixmap_ready.connect(self.video_label.setPixmap)
|
||||||
|
self.video_worker.log_message.connect(self.log)
|
||||||
|
self.video_worker.start()
|
||||||
|
self.btn_video.setText("关闭视频")
|
||||||
|
self.log("[INFO] 正在打开视频")
|
||||||
|
inform_box : DialogInform = DialogInform()
|
||||||
|
inform_box.information("提示", "正在打开视频")
|
||||||
|
|
||||||
|
def toggle_video_mode(self):
|
||||||
|
if self.current_video_mode==0:
|
||||||
|
self.send_uvc(1)
|
||||||
|
self.current_video_mode=1
|
||||||
|
self.log("[INFO] 已切换到红外视频模式")
|
||||||
|
inform_box : DialogInform = DialogInform()
|
||||||
|
inform_box.information("提示", "已切换到红外视频模式")
|
||||||
|
else:
|
||||||
|
self.send_uvc(0)
|
||||||
|
self.current_video_mode=0
|
||||||
|
self.log("[INFO] 已切换到彩色视频模式")
|
||||||
|
inform_box : DialogInform = DialogInform()
|
||||||
|
inform_box.information("提示", "已切换到彩色视频模式")
|
||||||
|
|
||||||
|
def toggle_face_box(self):
|
||||||
|
if self.current_face_box==0:
|
||||||
|
self.send_face_box(1)
|
||||||
|
self.current_face_box=1
|
||||||
|
self.log("[INFO] 人脸框已开启")
|
||||||
|
inform_box : DialogInform = DialogInform()
|
||||||
|
inform_box.information("提示", "人脸框已开启")
|
||||||
|
else:
|
||||||
|
self.send_face_box(0)
|
||||||
|
self.current_face_box=0
|
||||||
|
self.log("[INFO] 人脸框已关闭")
|
||||||
|
inform_box : DialogInform = DialogInform()
|
||||||
|
inform_box.information("提示", "人脸框已关闭")
|
||||||
|
|
||||||
|
# ---------------- 发送指令 ----------------
|
||||||
|
def send_uvc(self, mode):
|
||||||
|
if self.ser and getattr(self.ser,"is_open",False):
|
||||||
|
self.ser.write(build_uvc_view(mode))
|
||||||
|
else:
|
||||||
|
self.log("[WARN] 串口未连接,无法切换视频模式")
|
||||||
|
|
||||||
|
def send_face_box(self, state):
|
||||||
|
if self.ser and getattr(self.ser,"is_open",False):
|
||||||
|
self.ser.write(build_face_view(state))
|
||||||
|
else:
|
||||||
|
self.log("[WARN] 串口未连接,无法控制人脸框")
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#刷新屏幕上的系统信息, 例如时间日期之类
|
#刷新屏幕上的系统信息, 例如时间日期之类
|
||||||
def flush_system_info(self, child = None) :
|
def flush_system_info(self, child = None) :
|
||||||
@ -1009,8 +1166,6 @@ class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
|
|||||||
modify_screen_time_str = dialog_modify_text.value
|
modify_screen_time_str = dialog_modify_text.value
|
||||||
result = frt.set_verify_timeout(modify_screen_time_str)
|
result = frt.set_verify_timeout(modify_screen_time_str)
|
||||||
|
|
||||||
if result is not None:
|
|
||||||
self.FaceRecogTimeoutEdit.setText(str(result))
|
|
||||||
dialog_inform = DialogInform(self)
|
dialog_inform = DialogInform(self)
|
||||||
dialog_inform.information("人脸识别超时时间修改", "人脸识别超时时间修改成功")
|
dialog_inform.information("人脸识别超时时间修改", "人脸识别超时时间修改成功")
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 228 KiB After Width: | Height: | Size: 368 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 219 KiB |
@ -126,6 +126,11 @@ NOTE_NAMES = {
|
|||||||
# 帧头同步字
|
# 帧头同步字
|
||||||
SYNC = b"\xEF\xAA"
|
SYNC = b"\xEF\xAA"
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
def xor_checksum(data: bytes) -> int:
|
def xor_checksum(data: bytes) -> int:
|
||||||
"""
|
"""
|
||||||
计算异或校验 (XOR),范围为整个帧的 MsgID + Size + Data 部分,
|
计算异或校验 (XOR),范围为整个帧的 MsgID + Size + Data 部分,
|
||||||
@ -366,15 +371,15 @@ def parse_reply(data: bytes) -> dict:
|
|||||||
info["user_id"] = uid
|
info["user_id"] = uid
|
||||||
|
|
||||||
# 自动生成提示消息
|
# 自动生成提示消息
|
||||||
if info.get("ok"):
|
if info["ok"]:
|
||||||
|
if mid == CMD_VERIFY and "user_id" in info:
|
||||||
|
info["message"] = (
|
||||||
|
f"{info['mid_name']} 成功 - 用户ID: {info['user_id']}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
info["message"] = f"{info['mid_name']} 成功"
|
info["message"] = f"{info['mid_name']} 成功"
|
||||||
inform_box : DialogInform = DialogInform()
|
|
||||||
inform_box.information("提示", f"{info['mid_name']} 成功")
|
|
||||||
else:
|
else:
|
||||||
info["message"] = f"{info['mid_name']} 失败: {info['result_name']}"
|
info["message"] = f"{info['mid_name']} 失败: {info['result_name']}"
|
||||||
inform_box : DialogInform = DialogInform()
|
|
||||||
inform_box.information("提示", f"{info['mid_name']} 失败: {info['result_name']}")
|
|
||||||
|
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
1,1,2025-09-11 16:21:21
|
1,1,2025-09-13 10:06:01
|
||||||
|
|||||||
|