Files
MenuPython_QT/QT5_Project/ZM_4/UIFrameWork.py

1624 lines
76 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# This Python file uses the following encoding: utf-8
import sys
import os
import time
import inspect
import cv2
import json
from itertools import chain
from PyQt5 import uic
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.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QFrame, QWidget, QLayout, QLabel
from PyQt5.QtWidgets import QLineEdit, QPushButton, QMessageBox, QShortcut, QDialog
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from Shared_CODE.CameraThread import CameraThread
import menu_utils as utils
import uart_group_config as group_config
from mqtt_device import class_comm_mqtt_thread, class_comm_mqtt_interface
from Shared_CODE.DialogModifyValue import DialogModifyValue
from Shared_CODE.DialogModifyAlias import DialogModifyAlias
from Shared_CODE.DialogModifyText import DialogModifyText
from Shared_CODE.DialogInform import DialogInform
from Shared_CODE.get_tip_prop import *
from print_color import *
import time
from PyQt5.QtCore import QDateTime
import re
from datetime import datetime
import platform
import subprocess
# sys.path.append(sys.path[0] + "/../..")
# sys_path = sys.path[0].replace("\\", "/")
# 设置 img 目录的路径
img_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'background'))
COLOR_RED = QColor("#EE2D2D").name()
COLOR_GREEN = QColor(Qt.green).name()
COLOR_BLUE = QColor(Qt.blue).name()
COLOR_CYAN = QColor("#00FFFF").name()
COLOR_YELLOW = QColor(Qt.yellow).name()
COLOR_NORMAL = QColor("#000000").name()
COLOR_ALARM_NORMAL = QColor("#31D19E").name()
COLOR_ALARM_ERROR_TEXT = QColor("#B1E5FC").name()
COLOR_ALARM_ERROR_BG = QColor("#E17176").name()
COLOR_VALUE_NORMAL = QColor("#31D19E").name()
ALIAS_QUERY_NONE = 0
ALIAS_QUERY_WAIT_RESPOINSE = 1
def is_linux():
return platform.system() == 'Linux'
def set_system_time(year, month, day, hour, minute, second):
if is_linux():
try:
new_time = datetime(year, month, day, hour, minute, second).strftime("%Y-%m-%d %H:%M:%S")
subprocess.run(f'sudo timedatectl set-time "{new_time}"', shell=True, check=True)
print(f"System time updated to {new_time}")
except subprocess.CalledProcessError as e:
print(f"Failed to update system time: {e}")
else:
import ctypes
import ctypes.wintypes
TIME_ZONE_ID_UNKNOWN = 0
TIME_ZONE_ID_STANDARD = 1
TIME_ZONE_ID_DAYLIGHT = 2
class SYSTEMTIME(ctypes.Structure):
_fields_ = [
("wYear", ctypes.wintypes.WORD),
("wMonth", ctypes.wintypes.WORD),
("wDayOfWeek", ctypes.wintypes.WORD),
("wDay", ctypes.wintypes.WORD),
("wHour", ctypes.wintypes.WORD),
("wMinute", ctypes.wintypes.WORD),
("wSecond", ctypes.wintypes.WORD),
("wMilliseconds", ctypes.wintypes.WORD),
]
system_time = SYSTEMTIME()
ctypes.windll.kernel32.GetSystemTime(ctypes.byref(system_time))
system_time.wYear = year
system_time.wMonth = month
system_time.wDay = day
system_time.wHour = hour
system_time.wMinute = minute
system_time.wSecond = second
ctypes.windll.kernel32.SetSystemTime(ctypes.byref(system_time))
print(f"System time updated to {year}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}")
def set_screen_blanking_time(minutes):
"""
设置屏幕黑屏时间:param minutes: 屏幕黑屏时间,以分钟为单位
"""
if is_linux():
# 如果是 Linux 系统,使用 xfconf-query 命令设置 Xfce 的屏幕黑屏时间
try:
# Xfce 的屏幕黑屏时间是以秒为单位
seconds = int(minutes) * 60
subprocess.run([
'xfconf-query', '-c', 'xfce4-power-manager',
'-p', '/xfce4-power-manager/blank-on-ac',
'-s', str(seconds), '-t', 'int', '--create'
], check=True)
print(f"Xfce屏幕黑屏时间设置为 {minutes} 分钟")
except subprocess.CalledProcessError as e:
print(f"设置Xfce屏幕黑屏时间失败: {e}")
except FileNotFoundError:
print("xfconf-query 命令未找到,请确保已安装 xfce4-power-manager。")
elif platform.system() == 'Windows':
# 如果是 Windows 系统,使用 powercfg 命令设置屏幕黑屏时间
try:
# 设置交流电源时的屏幕黑屏时间
subprocess.run(['powercfg', '-change', '-monitor-timeout-ac', str(minutes)], check=True)
# 设置电池供电时的屏幕黑屏时间
subprocess.run(['powercfg', '-change', '-monitor-timeout-dc', str(minutes)], check=True)
print(f"屏幕黑屏时间设置为 {minutes} 分钟 (适用于交流电和电池供电)")
except subprocess.CalledProcessError as e:
print(f"设置屏幕黑屏时间失败: {e}")
else:
print("当前操作系统不支持此操作。")
def json_load_message(message) :
json_dict = {}
if isinstance(message, bytes) :
json_dict = json.loads(message.decode('utf-8'))
elif isinstance(message, str) :
json_dict = json.loads(message.encode('utf-8'))
else :
json_dict = json.loads(message)
return json_dict
def modify_style_sheet(type_name : str, origin_style_sheet : str, lead_str : str, value_str : str) :
if len(value_str) == 0 :
new_style_items = ""
else :
new_style_items = "%s:%s;"%(lead_str, value_str)
style_splits = origin_style_sheet.split("{")
if len(style_splits) == 1 :
style_items_str = style_splits[0]
elif len(style_splits) == 2 :
style_items_str = style_splits[1]
else :
style_items_str = ""
style_items_str = style_items_str.replace("}", "")
prop_splits = style_items_str.split(";")
for each_style_prop in prop_splits :
if lead_str in each_style_prop :
key_value_splits = each_style_prop.split(":")
cmp_str = key_value_splits[0]
cmp_str = cmp_str.replace(" ", "")
cmp_str = cmp_str.replace("\n", "")
if lead_str == cmp_str :
continue
if len(each_style_prop) > 0 :
new_style_items += each_style_prop
new_style_items += ";"
if len(type_name) == 0:
return "%s"%(new_style_items)
else :
return "%s {%s}"%(type_name, new_style_items)
def get_key_combine_str(str1, str2) :
return str1 + "," + str2
def search_circuit_from_topic(topic : str) :
circuit_id = -1
for config_dict in group_config.comm_thread_config :
device_list = utils.dict_or_object_get_attr(config_dict, "device_list", None)
if device_list != None :
for item_dict in device_list :
config_circuit_id = utils.dict_or_object_get_attr(item_dict, "circuit_id", -1)
circuit_unique_name = utils.dict_or_object_get_attr(item_dict, "unique_name", None)
if circuit_unique_name in topic :
circuit_id = config_circuit_id
break
if circuit_id >= 0 :
break
return circuit_id
def get_imag_value_file_name(tip_str : str, value : int) :
file_name = get_tip_value_str(tip_str, "ImageValue", default_string = None)
try :
if isinstance(value, str) :
fvalue = float(value)
value_id = round(fvalue)
else :
value_id = value
except Exception as e :
return None
if file_name != None :
file_name_with_value = file_name%(value_id)
imag_value_file_name = os.path.join(img_path, file_name_with_value)
else :
imag_value_file_name = None
if imag_value_file_name != None :
if os.path.exists(imag_value_file_name) :
return imag_value_file_name.replace("\\", "/")
return None
def get_imag_file_name(tip_str : str, key_imag : str, default_string = None) :
file_name = get_tip_value_str(tip_str, key_imag, default_string)
select_image_file_name = None
if file_name != None :
select_image_file_name = os.path.join(img_path, file_name)
if os.path.exists(select_image_file_name) :
return select_image_file_name.replace("\\", "/")
return None
def get_select_imag_file_name(tip_str : str) :
return get_imag_file_name(tip_str, "SelectImag", default_string = None)
def get_select_icon_file_name(tip_str : str) :
return get_imag_file_name(tip_str, "SelectIcon", default_string = None)
def get_bk_imag_file_name(tip_str : str) :
return get_imag_file_name(tip_str, "ImageBackGround", default_string = None)
def get_indicator_imag_file_name(tip_str : str) :
return get_imag_file_name(tip_str, "ImageIndicator", default_string = None)
def get_compare_index(main_index : int, sub_index : int) :
return (main_index + 1) * 64 + sub_index
class UIFrameWork(QMainWindow, class_comm_mqtt_interface):
mqtt_signal : pyqtSignal = pyqtSignal(str)
def __init__(self):
QMainWindow.__init__(self)
self.topic_message_list : list = []
self.mutex : QMutex = QMutex()
self.mqtt_signal.connect(self.mqtt_topic_message_process)
self.menu_list = []
self.sort_menu_list = []
self.menu_key_index = 0
self.key_active = 0
self.select_object : QWidget = None
self.wait_response_list = []
self.mqtt_thread : class_comm_mqtt_thread= None
self.mqtt_value_dict = {}
self.widget_timeout_list = []
self.alias_dict = {}
self.alias_query_timer : QTimer = None
self.alias_query_timer = QTimer()
self.alias_query_timer.timeout.connect(self.process_alias_query)
self.alias_query_timer.start(3000)
self.video_visible_timer = QTimer()
self.video_visible_timer.timeout.connect(self.video_visible_timeout)
self.video_visible_timer.start(200)
self.time_timer = QTimer()
self.time_timer.timeout.connect(self.flush_system_cycle)
self.time_timer.start(500)
self.canvas_visible_arr = [
False,
False,
False,
False,
False,
False,
False,
False,
False,
]
# QLabel list_index CameraThread
# self.canvas_label_list : QLabel = [ [None, -1, None],[None, -1, None], [None, -1, None], [None, -1, None],
# [None, -1, None],[None, -1, None], [None, -1, None], [None, -1, None],
# [None, -1, None]
# ]
# self.set_video_image_func_arr = [self.set_video_image_0, self.set_video_image_1, self.set_video_image_2, self.set_video_image_3,
# self.set_video_image_4, self.set_video_image_5, self.set_video_image_6, self.set_video_image_7,
# self.set_video_image_8
# ]
# 使用列表推导式动态生成 canvas_label_list
self.canvas_label_list = [[None, -1, None] for _ in range(9)]
# 使用列表推导式动态生成 set_video_image_func_arr
self.set_video_image_func_arr = [getattr(self, f'set_video_image_{i}') for i in range(9)]
self.page = -1
self.select_main_index = -1
self.exist_circuit_mask = 0
self.check_widget_timeout_timer : QTimer = None
QShortcut(QKeySequence(Qt.Key_Up), self, activated=self.key_decrease_parameter)
QShortcut(QKeySequence(Qt.Key_Down), self, activated=self.key_increase_parameter)
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_0), self, activated=self.key_Test_process0)
# QShortcut(QKeySequence(Qt.Key_1), self, activated=self.key_Test_process1)
# QShortcut(QKeySequence(Qt.Key_2), self, activated=self.key_Test_process2)
# QShortcut(QKeySequence(Qt.Key_3), self, activated=self.key_Test_process3)
self.bind_channel = -1
#虚函数, 切换到本页面时调用
def virtual_on_page_enter(self) :
pass
#虚函数, 退出到本页面时调用
def virtual_on_page_leave(self) :
pass
#虚函数, 切换到页面, 需要在派生类中实现, page=-1表示退出到上一级菜单
def virtual_change_to_page(self, page) :
pass
#虚函数, 画布连接到摄像头, 需要在派生类中实现。
def virtual_connect_canvas_to_camera(self, canvas_id : int, camera_id : int, is_visible : bool = True) :
pass
#虚函数, action处理函数, 派生类可以额外处理
def virtual_widget_action_process(self, widget : QObject, action : str) :
return
def set_mqtt_value(self, circuit : int, mqtt_name : str, mqtt_value) :
key = f'{circuit}+{mqtt_name}'
self.mqtt_value_dict[key] = mqtt_value
def get_mqtt_value(self, circuit : int, mqtt_name : str) :
key = f'{circuit}+{mqtt_name}'
if key in self.mqtt_value_dict.keys() :
return self.mqtt_value_dict[key]
return None
def modify_object_style_sheet(self, object :QWidget, lead_str : str, value_str : str) :
meta_object = object.metaObject()
className = meta_object.className()
object_name : str = object.objectName()
object_type_name = className + "#" + object_name
origin_style = object.styleSheet()
new_style_sheet = modify_style_sheet(object_type_name, origin_style, lead_str, value_str)
object.setStyleSheet(new_style_sheet)
def reset_object_style_sheet(self, object :QWidget) :
meta_object = object.metaObject()
className = meta_object.className()
object_name : str = object.objectName()
object_type_name = className + "#" + object_name
origin_style = object.whatsThis()
object.setStyleSheet(origin_style)
def load_window_ui(self, file_window_ui : str) :
if os.path.exists(file_window_ui):
uic.loadUi(file_window_ui, self)
self.load_resource_bitmap()
self.create_menu_list()
self.sort_menu_list = sorted(self.menu_list, key=lambda x: x[0])
self.create_style_sheet_backup()
self.create_timeout_list()
self.create_alias_list()
self.update_window_circuit_mask()
self.exist_circuit_mask = self.get_circuit_mask()
self.check_widget_timeout_timer : QTimer = QTimer()
self.check_widget_timeout_timer.timeout.connect(self.process_widget_timeout_list)
self.check_widget_timeout_timer.start(100)
self.page = get_tip_page(self.statusTip())
self.menu_selectable_object_flush()
def get_circuit_mask(self, child_widget : QWidget = None) :
widget :QWidget = child_widget
if widget == None :
widget = self
circuit_id_mask = 0
for each_object in widget.children():
child : QWidget = each_object
if hasattr(child, "statusTip") :
circuit_id = self.get_circuit_from_object(child)
if circuit_id >= 0 :
circuit_id_mask |= (0x01 << circuit_id)
circuit_id_mask |= self.get_circuit_mask(child)
return circuit_id_mask
def update_window_circuit_mask(self) :
self.exist_circuit_mask = self.get_circuit_mask()
return
def set_menu_main_index(self, main_index) :
self.main_index = main_index
if len(self.sort_menu_list) == 0 :
return
if self.main_index < 0 :
self.menu_key_index = 0
self.select_object = self.sort_menu_list[self.menu_key_index][1]
self.menu_selectable_object_flush()
return
menu_key_index = 0
for each_item in self.sort_menu_list :
compare_index = each_item[0]
if compare_index >= get_compare_index(main_index, 0) :
break
menu_key_index += 1
self.menu_key_index = menu_key_index
self.select_object = self.sort_menu_list[self.menu_key_index][1]
self.menu_selectable_object_flush()
def process_alias_query(self):
if not self.mqtt_thread:
return # 如果没有 MQTT 线程,直接返回
for alias_unique_name, alias_value_dict in self.alias_dict.items(): # {"xxxxx,sss": 123}
if not isinstance(alias_value_dict, int) or alias_value_dict != ALIAS_QUERY_NONE:
continue # 仅处理需要查询的整数别名
alias_name, uniqe_name = alias_unique_name.split(",")
# 初始化 select_object 变量
select_object: QWidget = None
# 将别名的值设置为等待响应状态
self.alias_dict[alias_unique_name] = ALIAS_QUERY_WAIT_RESPOINSE
# 发布 MQTT 消息并等待响应
self.mqtt_publish_and_wait_response(
f"request/alias/{uniqe_name}",
json.dumps({"name": alias_name}),
select_object,
2000,
False
)
def process_widget_timeout_list(self) :
list_index = 0
for timeout_items in self.widget_timeout_list:
time_limit = timeout_items[0]
cur_time = timeout_items[1]
cur_time += 100
if cur_time >= time_limit:
cur_time = 0
timeout_widget : QWidget = timeout_items[2]
if isinstance(timeout_widget, QLineEdit) :
lineedit_widget : QLineEdit = timeout_widget
# 检查 QLineEdit 的宽度
if lineedit_widget.width() < 80:
lineedit_widget.setText("超时")
else:
lineedit_widget.setText("通信超时")
elif isinstance(timeout_widget, QLabel) :
label_widget : QLabel = timeout_widget
if "canvas" in label_widget.statusTip() :
self.camera_signal_timeout(label_widget)
else :
if label_widget.isVisible() :
label_widget.setVisible(False)
#label_widget.hide()
elif isinstance(timeout_widget, QPushButton) :
button_widget : QPushButton = timeout_widget
self.reset_object_style_sheet(button_widget)
if button_widget.width() < 80:
button_widget.setText("超时")
else:
button_widget.setText("通信超时")
timeout_items[1] = cur_time
self.widget_timeout_list[list_index] = timeout_items
list_index = list_index + 1
def reset_widget_timeout(self, widget : QObject) :
Index = 0
for timeout_item in self.widget_timeout_list:
cur_time = timeout_item[1]
timeout_widget : QWidget = timeout_item[2]
if timeout_widget == widget :
timeout_item[1] = 0
self.widget_timeout_list[Index] = timeout_item
break
Index = Index + 1
def connect_camera_thread(self, camera_thread : CameraThread, canvas_id : int = 0, is_visible : bool = True) :
if camera_thread == None or canvas_id < 0:
return
if canvas_id < len(self.set_video_image_func_arr) :
canvas_object : QLabel = self.search_canvas_object(canvas_id)
if canvas_object :
canvas_info_item = self.canvas_label_list[canvas_id]
origin_camera_thread : CameraThread = canvas_info_item[2]
if origin_camera_thread != None and origin_camera_thread.is_signal_connect:
origin_camera_thread.image_signal.disconnect(self.set_video_image_func_arr[canvas_id])
if is_visible :
camera_thread.signal_connect(self.set_video_image_func_arr[canvas_id])
list_index : int = self.get_timeout_List_index(canvas_object)
self.canvas_label_list[canvas_id] = [canvas_object, list_index, camera_thread]
else :
self.canvas_label_list[canvas_id] = [None, -1, None]
self.canvas_visible_arr[canvas_id] = is_visible
def camera_signal_timeout(self, camera_label : QLabel):
if camera_label != None :
pass
def search_canvas_object(self, canvas_id = 0, child = None) :
widget :QWidget = child
if widget == None :
widget = self
child_count = 0
for each_object in widget.children():
child_count += 1
child : QWidget = each_object
if hasattr(child, "statusTip") :
tip_str : str = child.statusTip()
config_canvas_id, config_camera_id = get_tip_canvas_id_and_camera_id(tip_str)
if config_canvas_id >= 0 and config_camera_id >= 0 and config_canvas_id == canvas_id:
if isinstance(child, QLabel) :
return child
find_canvas_object = self.search_canvas_object(canvas_id, child)
if find_canvas_object != None :
return find_canvas_object
if child_count == 0 :
return None
def get_canvas_prop (self, canvas_id : int= 0) :
config_camera_id = -1
is_face_detect : int = 0
canvas_object : QWidget = self.search_canvas_object(canvas_id)
if canvas_object != None :
tip_str : str = canvas_object.statusTip()
config_canvas_id, config_camera_id = get_tip_canvas_id_and_camera_id(tip_str)
is_face_detect = get_tip_face_detection(tip_str)
return config_camera_id, is_face_detect
def load_resource_bitmap(self, child = None) :
widget :QWidget = self
if child != None :
widget = child
for child_widget in widget.children():
if hasattr(child_widget, "statusTip") :
tip_str : str = child_widget.statusTip()
imag_file_name = get_bk_imag_file_name(tip_str)
if imag_file_name != None :
if isinstance(child_widget, QLabel) :
label_child_object : QLabel = child_widget
label_child_object.setScaledContents(True)
image = QPixmap(imag_file_name)
label_child_object.setPixmap(image)
elif isinstance(child_widget, QWidget) :
file_url = "url(%s)"%(imag_file_name)
self.modify_object_style_sheet(child_widget, "background-image", file_url)
self.load_resource_bitmap(child_widget)
def create_style_sheet_backup(self, child = None) :
widget :QWidget = child
if child == None :
widget = self
for child_widget in widget.children():
if hasattr(child_widget, "styleSheet") :
widget : QWidget = child_widget
style_sheet : str = widget.styleSheet()
widget.setWhatsThis(style_sheet)
self.create_style_sheet_backup(child_widget)
def create_timeout_list(self, child = None) :
widget :QWidget = self
if child == None :
self.widget_timeout_list = []
else :
widget = child
for child_widget in widget.children():
if hasattr(child_widget, "statusTip") :
tip_str : str = child_widget.statusTip()
timeout_limit_ms = get_tip_timeout(tip_str)
if timeout_limit_ms >= 0:
self.widget_timeout_list.append([timeout_limit_ms, 0, child_widget])
self.create_timeout_list(child_widget)
def get_timeout_List_index(self, object : QWidget) :
list_index = -1
search_list_index = 0
for items in self.widget_timeout_list :
child_widget : QWidget = items[2]
if child_widget == object :
list_index = search_list_index
break
search_list_index += 1
return list_index
def get_page_circuit(self):
if hasattr(self, "statusTip") :
return get_tip_circuit(self.statusTip())
return -1
def set_page_circuit(self, circuit_id = -1) :
if hasattr(self, "statusTip") :
origin_status_tip : str = self.statusTip()
origin_tip_splits = origin_status_tip.split(",")
new_status_tip = ""
for each_str in origin_tip_splits:
if "circuit" not in each_str :
new_status_tip += each_str
new_status_tip += ","
new_status_tip += "circuit=%d"%(circuit_id)
self.setStatusTip(new_status_tip)
self.update_window_circuit_mask()
self.create_alias_list()
self.process_alias_query()
self.para_or_measure_query()
def create_alias_list(self, child = None) :
widget :QWidget = self
if child == None :
self.alias_dict = {}
else :
widget = child
for child_widget in widget.children():
if hasattr(child_widget, "statusTip") :
tip_str : str = child_widget.statusTip()
alias_str = get_tip_alias_str(tip_str)
if alias_str != None:
unique_name = self.get_unique_name_from_object(child_widget)
if unique_name != None :
key_combine_str = get_key_combine_str(alias_str, unique_name)
if key_combine_str not in self.alias_dict.keys() :
self.alias_dict[key_combine_str] = ALIAS_QUERY_NONE
self.create_alias_list(child_widget)
def create_menu_list(self, child = None) :
widget :QWidget = self
if child == None :
self.menu_list = []
else :
widget = child
for child_widget in widget.children():
if hasattr(child_widget, "statusTip") :
tip_str : str = child_widget.statusTip()
sub_index = get_tip_menu_sub_index(tip_str)
if sub_index >= 0:
main_index = self.get_main_index_from_object(child_widget)
if main_index >= 0 :
compare_index = get_compare_index(main_index, sub_index)
else :
compare_index = sub_index
self.menu_list.append([compare_index, child_widget])
if isinstance(child_widget, QPushButton) :
button : QPushButton = child_widget
button.clicked.connect(self.on_menu_qpush_button_click)
self.create_menu_list(child_widget)
def on_select_object_action_process(self, select_object : QWidget) :
tip_str = select_object.statusTip()
action_str = get_tip_value_str(tip_str, "Action", None)
if action_str != None :
if "password" in tip_str :
dialog_modify_text = DialogModifyValue(self)
caption_str = "请输入密码:"
dialog_modify_text.update_modify_info("", "0000", caption_str)
input = False
if dialog_modify_text.exec() == QDialog.Accepted:
input = True
modify_screen_time_str = dialog_modify_text.value
pass_word = system_parameter()
if modify_screen_time_str != pass_word.get_system_password() :
inform_box : DialogInform = DialogInform()
inform_box.information("提示", "密码错误,无法修改!")
return
else:
input = True
if input :
if "CmdExecute" in action_str :
mqtt_name = get_tip_mqtt_name(tip_str)
unique_name = self.get_unique_name_from_object(select_object)
if mqtt_name != None and unique_name != None:
if len(mqtt_name) > 0 and self.mqtt_thread != None:
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(tip_str)
elif "Modify" in action_str :
if isinstance(select_object, QLineEdit) :
self.on_line_edit_modify_click(select_object)
self.virtual_widget_action_process(select_object, action_str)
def search_menu_match_object(self, object) :
match_object : QWidget = None
menu_index = 0
for each_list in self.sort_menu_list :
search_object = each_list[1]
if search_object == object :
match_object = search_object
break
menu_index += 1
return match_object, menu_index
#刷新屏幕上的系统信息, 例如时间日期之类
def flush_system_info(self, child = None) :
widget : QWidget= child
if child == None :
widget = self
else :
widget = child
for child_widget in widget.children():
if hasattr(child_widget, "statusTip") :
tip_str : str = child_widget.statusTip()
system_str = get_tip_system(tip_str)
if system_str == "DateTime" :
qdate_time = QDateTime.currentDateTime()
time_str = qdate_time.toString("yyyy-MM-dd hh:mm:ss")
if isinstance(child_widget, QPushButton) :
button_widget : QPushButton = child_widget
button_widget.setText(time_str)
elif isinstance(child_widget, QLineEdit) :
line_edit_widget : QLineEdit = child_widget
line_edit_widget.setText(time_str)
elif isinstance(child_widget, QLabel) :
label_widget : QLabel = child_widget
label_widget.setText(time_str)
self.flush_system_info(child_widget)
def func_mqtt_param_modify(self, modify_str : str) :
select_object : QWidget = self.select_object
if select_object == None :
return
tip = select_object.statusTip()
unique_name = self.get_unique_name_from_object(select_object)
mqtt_name = get_tip_mqtt_name(tip)
if self.mqtt_thread != None :
request_topic = "request/param/modify/" + unique_name
request_message = '{"name" : "%s", "value" : "%s"}'%(mqtt_name, modify_str)
self.mqtt_publish_and_wait_response(request_topic, request_message, select_object, 1000)
def func_call_back_on_mqtt_param_info(self, info_str : str) :
select_object : QWidget = self.select_object
if select_object == None :
return
tip = select_object.statusTip()
unique_name = self.get_unique_name_from_object(select_object)
mqtt_name = get_tip_mqtt_name(tip)
if self.mqtt_thread != None :
request_topic = "request/param/info/" + unique_name
request_message = '{"name" : "%s", "value" : "%s"}'%(mqtt_name, info_str)
self.mqtt_publish_and_wait_response(request_topic, request_message, select_object, 1000)
def on_menu_qpush_button_click(self, sender : QPushButton):
sender : QPushButton = self.sender()
match_object : QWidget = None
match_object, menu_index = self.search_menu_match_object(sender)
if match_object != None :
self.menu_key_index = menu_index
self.menu_selectable_object_flush()
if isinstance(match_object, QPushButton) :
self.on_select_object_action_process(match_object)
#修改系统时间与日期
def func_modify_system_time(self, modify_str : str) :
numbers = re.findall(r'\d+', modify_str)
if len(numbers) == 6 :
year = int(numbers[0])
month = int(numbers[1])
day = int(numbers[2])
hour = int(numbers[3])
minute = int(numbers[4])
second = int(numbers[5])
set_system_time(year, month, day, hour, minute, second)
return year, month, day, hour, minute, second
return None
#修改系统黑屏时间
def func_modify_screen_blanking_time(self, modify_str: str):
numbers = re.findall(r'\d+', modify_str)
if len(numbers) == 1:
minutes = int(numbers[0])
set_screen_blanking_time(minutes)
return minutes
return None
def on_system_param_modify(self, tip : str) :
system = get_tip_system(tip)
if system == "DateTime" :
dialog_modify_text : DialogModifyText = DialogModifyText(self)
caption_str = "修改系统时间"
cur_time = QDateTime.currentDateTime()
date_time_str = cur_time.toString("yyyy-MM-dd hh:mm:ss")
dialog_modify_text.update_modify_info(date_time_str, caption_str)
if dialog_modify_text.exec() == QDialog.Accepted:
modify_date_time_str = dialog_modify_text.value
self.func_modify_system_time(modify_date_time_str)
for circuit_id in range(8) :
unique_name = self.get_unique_name_from_circuit(circuit_id)
if unique_name != None and self.mqtt_thread != None:
time_message = '{"name" : "SetupTime", "value" : "%s"}'%(modify_date_time_str)
self.mqtt_thread.publish("request/action/" + unique_name, time_message)
dialog_inform = DialogInform(self)
dialog_inform.information("系统时间修改", "系统时间修改成功")
elif system == "ScreenBlankingTime":
dialog_modify_text = DialogModifyValue(self)
caption_str = "修改屏幕黑屏时间(分钟)"
sbt = system_parameter()
dialog_modify_text.update_modify_info("", str(sbt.get_screen_blanking_time()), caption_str)
if dialog_modify_text.exec() == QDialog.Accepted:
modify_screen_time_str = dialog_modify_text.value
result = self.func_modify_screen_blanking_time(modify_screen_time_str)
sbt.change_screen_blanking_time(modify_screen_time_str)
if result is not None:
self.BlankTimelineEdit.setText(str(result))
dialog_inform = DialogInform(self)
dialog_inform.information("屏幕黑屏时间修改", "屏幕黑屏时间修改成功")
elif system == "SystemPassWord":
dialog_modify_text = DialogModifyValue(self)
caption_str = "修改系统密码"
pass_word = system_parameter()
dialog_modify_text.update_modify_info("", pass_word.get_system_password(), caption_str)
if dialog_modify_text.exec() == QDialog.Accepted:
modify_screen_time_str = dialog_modify_text.value
pass_word.set_system_password(modify_screen_time_str)
dialog_inform = DialogInform(self)
dialog_inform.information("系统密码修改", "系统密码修改成功")
def on_line_edit_modify_click(self, sender :QLineEdit) :
match_object : QLineEdit = None
match_object, menu_index = self.search_menu_match_object(sender)
if match_object != None :
self.menu_key_index = menu_index
if isinstance(match_object, QLineEdit) :
self.dialog_modify_value = None
tip = match_object.statusTip()
alias_name = get_tip_alias_str(tip)
unique_name = self.get_unique_name_from_object(match_object)
if unique_name != None and alias_name != None :
key_combine_str = get_key_combine_str(alias_name, unique_name)
value_dict = utils.dict_or_object_get_attr(self.alias_dict, key_combine_str, None)
if isinstance(value_dict, dict) :
dialog_modify_alias : DialogModifyAlias = DialogModifyAlias(self)
caption_str = get_tip_caption_str(match_object.statusTip())
value_text = match_object.text()
dialog_modify_alias.set_alias_item_info(value_dict, value_text, caption_str)
self.dialog_modify_alias = dialog_modify_alias
if dialog_modify_alias.exec() == QDialog.Accepted :
modify_value = dialog_modify_alias.value
self.func_mqtt_param_modify(modify_value)
else :
inform_box : DialogInform = DialogInform()
inform_box.information('别名数据未获取', 'message: %s'%(alias_name))
else :
dialog_modify_value : DialogModifyValue = DialogModifyValue(self)
caption_str = get_tip_caption_str(match_object.statusTip())
try :
origin_value = float(match_object.text())
except Exception as e :
origin_value = None
inform_box : DialogInform = DialogInform()
inform_box.information('无效值', str(e))
if origin_value != None :
format_str = get_tip_format(tip)
dialog_modify_value.update_modify_info(format_str, origin_value, caption_str)
if dialog_modify_value.exec() == QDialog.Accepted :
modify_value = dialog_modify_value.value
self.func_mqtt_param_modify(modify_value)
def set_video_image(self, image_object : QObject, canvas_id = 0) :
if canvas_id >= len(self.canvas_label_list) :
return
camera_info_items = self.canvas_label_list[canvas_id]
camera_label: QLabel = camera_info_items[0]
timeout_list_index = camera_info_items[1]
camera_thread : CameraThread = camera_info_items[2]
if camera_label != None:
shape = image_object.shape
width = shape[1]
height = shape[0]
if camera_label.isVisible() :
qt_img = QImage(image_object.data, width, height, QImage.Format_RGB888)
camera_label.setScaledContents(True)
camera_label.setPixmap(QPixmap.fromImage(qt_img))
if timeout_list_index >= 0 :
self.widget_timeout_list[timeout_list_index][1] = 0
def set_video_image_0(self, image_object : QObject) :
self.set_video_image(image_object, 0)
def set_video_image_1(self, image_object : QObject) :
self.set_video_image(image_object, 1)
def set_video_image_2(self, image_object : QObject) :
self.set_video_image(image_object, 2)
def set_video_image_3(self, image_object : QObject) :
self.set_video_image(image_object, 3)
def set_video_image_4(self, image_object : QObject) :
self.set_video_image(image_object, 4)
def set_video_image_5(self, image_object : QObject) :
self.set_video_image(image_object, 5)
def set_video_image_6(self, image_object : QObject) :
self.set_video_image(image_object, 6)
def set_video_image_7(self, image_object : QObject) :
self.set_video_image(image_object, 7)
def set_video_image_8(self, image_object : QObject) :
self.set_video_image(image_object, 8)
def update_mqtt_value(self, circuit, json_dict) :
for json_key, json_value in json_dict.items() :
self.set_mqtt_value(circuit, json_key, json_value)
#更新视频显示与否
def update_canvas_camera_visible(self, child = None) :
widget :QWidget = child
if widget == None :
widget = self
for each_object in widget.children():
child : QWidget = each_object
if isinstance(child, QLabel) :
widget_label : QLabel = child
tip_str = widget_label.statusTip()
visible_mqtt = get_tip_visible_mqtt(tip_str, None)
if visible_mqtt != None :
#该Label具有Visible控制, 检查一下是不是视频流
canvas_id, camera_id = get_tip_canvas_id_and_camera_id(tip_str)
if canvas_id >= 0 and camera_id >= 0 :
circuit_id = self.get_circuit_from_object(widget_label)
visible_value = self.get_mqtt_value(circuit_id, visible_mqtt)
is_visible = False
if visible_value != None :
try :
is_visible = True if int(visible_value) > 0 else False
except Exception as e :
is_visible = False
widget_label.setVisible(is_visible)
if is_visible != self.canvas_visible_arr[canvas_id] and canvas_id < len(self.canvas_visible_arr):
self.canvas_visible_arr[canvas_id] = is_visible
self.virtual_connect_canvas_to_camera(canvas_id, camera_id, is_visible)
self.update_canvas_camera_visible(child)
def video_visible_timeout(self) :
self.update_canvas_camera_visible()
#通过json包刷新界面数据
def flush_widgets(self, circuit, json_dict, child = None):
widget :QWidget = child
if widget == None :
widget = self
for each_object in widget.children():
child : QWidget = each_object
if not hasattr(child, "statusTip") :
continue
tip_str : str = child.statusTip()
mqtt_name = get_tip_mqtt_name(tip_str)
circuit_id = self.get_circuit_from_object(each_object)
self.flush_widgets(circuit, json_dict, child)
if circuit_id != circuit :
continue
if mqtt_name in json_dict.keys() :
value_or_dict = json_dict[mqtt_name]
if isinstance(value_or_dict, dict) :
value_text = utils.dict_or_object_get_attr(value_or_dict, "value", "")
else :
value_text = value_or_dict
color_str = utils.dict_or_object_get_attr(value_or_dict, "color", None)
bk_color_str = utils.dict_or_object_get_attr(value_or_dict, "bk_color", None)
imag_file_name = get_imag_value_file_name(tip_str, value_text)
timeout_ms = get_tip_timeout(tip_str)
if timeout_ms > 0 :
self.reset_widget_timeout(child)
if isinstance(child, QPushButton) :
widget_button : QPushButton = child
if imag_file_name != None :
self.modify_object_style_sheet(widget_button, "border-image", "url(%s)"%(imag_file_name))
else :
self.reset_object_style_sheet(widget_button)
if isinstance(child, QLabel) :
widget_label : QLabel = child
if imag_file_name != None :
if widget_label.isVisible() == False :
widget_label.setVisible(True)
self.modify_object_style_sheet(widget_label, "background-image", "url(%s)"%(imag_file_name))
else :
self.reset_object_style_sheet(widget_label)
widget_label.setText(value_text)
if isinstance(child, QLineEdit) :
widget_line_edit : QLineEdit = child
alias_name = get_tip_alias_str(widget_line_edit.statusTip())
unique_name = self.get_unique_name_from_object(widget_line_edit)
if alias_name != None :
fvalue = float(value_text)
value = round(fvalue)
value_str = str(value)
display_text = "(%s)"%(value_str)
alias_key_str = get_key_combine_str(alias_name, unique_name)
if alias_key_str in self.alias_dict.keys() :
alias_value_dict = self.alias_dict[alias_key_str]
if isinstance(alias_value_dict, dict) :
display_text = utils.dict_or_object_get_attr(alias_value_dict, value_str, value_text)
else :
display_text = value_text
widget_line_edit.setText(display_text)
if bk_color_str != None :
if isinstance(child, QLineEdit) :
self.modify_object_style_sheet(child, "background-color", bk_color_str)
if color_str != None :
self.modify_object_style_sheet(child, "color", color_str)
def get_circuit_from_object(self, object :QWidget) :
parent : QWidget= object
circuit_id = -1
while parent != None :
if hasattr(parent, "statusTip") :
tip_str = parent.statusTip()
circuit_id = get_tip_circuit(tip_str)
if circuit_id >= 0 or parent == self:
break
parent = parent.parent()
return circuit_id
def get_main_index_from_object(self, object :QWidget) :
parent : QWidget= object
main_index = -1
while parent != None :
if not hasattr(parent, "statusTip") :
return -1
tip_str = parent.statusTip()
main_index = get_tip_main_index(tip_str)
if main_index >= 0 or parent == self:
break
parent = parent.parent()
return main_index
def get_unique_name_from_circuit(self, circuit_id : int) :
for config_dict in group_config.comm_thread_config :
device_list = utils.dict_or_object_get_attr(config_dict, "device_list", None)
if device_list != None :
for item_dict in device_list :
config_circuit_id = utils.dict_or_object_get_attr(item_dict, "circuit_id", -1)
if config_circuit_id == circuit_id :
circuit_unique_name = utils.dict_or_object_get_attr(item_dict, "unique_name", None)
return circuit_unique_name
return None
def get_unique_name_from_object(self, object :QWidget) :
circuit_id = self.get_circuit_from_object(object)
return self.get_unique_name_from_circuit(circuit_id)
def key_increase_parameter(self):
menu_count = len(self.sort_menu_list)
if menu_count == 0:
return
tip_str = self.sort_menu_list[self.menu_key_index][1].statusTip()
group_items_count = get_tip_group_end(tip_str)
if group_items_count == -1:
next_menu_index = (self.menu_key_index + 1) % menu_count
else:
next_menu_index = (self.menu_key_index - group_items_count + 1) % menu_count
self.menu_key_index = next_menu_index
self.select_object = self.sort_menu_list[self.menu_key_index][1]
self.menu_selectable_object_flush()
def key_decrease_parameter(self):
menu_count = len(self.sort_menu_list)
if menu_count == 0:
return
tip_str = self.sort_menu_list[self.menu_key_index][1].statusTip()
group_items_count = get_tip_group_start(tip_str)
if group_items_count == -1:
prev_menu_index = (self.menu_key_index - 1) % menu_count
else:
prev_menu_index = (self.menu_key_index + group_items_count - 1) % menu_count
self.menu_key_index = prev_menu_index
self.select_object = self.sort_menu_list[self.menu_key_index][1]
self.menu_selectable_object_flush()
def key_enter_process(self):
menu_count = len(self.sort_menu_list)
if menu_count == 0:
return
self.select_object = self.sort_menu_list[self.menu_key_index][1]
self.on_select_object_action_process(self.select_object)
def key_escape_process(self):
#在菜单第一项, 按下复位, 退出到上一页
if self.menu_key_index == 0:
self.virtual_change_to_page(-1)
menu_count = len(self.sort_menu_list) # 获取当前页面可交互控件个数
if menu_count == 0: # 若注册可交互控件个数为0则退出处理返回
return
# 重置菜单选择
self.select_object = self.sort_menu_list[self.menu_key_index][1]
self.menu_key_index = 0
self.menu_selectable_object_flush()
# def key_Test_process0(self):
# json_dict = {"Uab" :"1111",
# "Ubc" : "1111",
# "Uca" : "1111",
# "Uo" : "11" ,
# "Iab" : "1111",
# "Ibc" : "1111",
# "Ica" : "1111",
# "Io" : "1111",
# "SwitchStatus" : {"value" :"0", "bk_color" : COLOR_NORMAL, "color" : COLOR_RED}
# }
# self.flush_widgets(0, json_dict)
# def key_Test_process1(self):
# json_dict = {"Uab" :"2222",
# "Ubc" : "2222",
# "Uca" : "2222",
# "Uo" : "22" ,
# "Iab" : "2222",
# "Ibc" : "2222",
# "Ica" : "2222",
# "Io" : "2222",
# "SwitchStatus" : {"value" :"1", "bk_color" : COLOR_NORMAL, "color" : COLOR_RED}
# }
# self.flush_widgets(1, json_dict)
# def key_Test_process2(self):
# json_dict = {"Uab" :"3333", "Ubc" : "3333", "Uca" : "3333", "Uo" : "33" , "Iab" : "3333", "Ibc" : "3333", "Ica" : "3333", "Io" : "3333"}
# self.flush_widgets(2, json_dict)
# def key_Test_process3(self):
# json_dict = {"Uab" :"33333", "Ubc" : "33333", "Uca" : "33333"}
# self.flush_widgets(3, json_dict)
def menu_selectable_object_flush(self) :
menu_count = len(self.sort_menu_list)
for i in range(menu_count):
object : QWidget = self.sort_menu_list[i][1]
is_select_object_draw = False
if isinstance(object, QPushButton) :
button_object : QPushButton = object
image_file_name = get_select_imag_file_name(object.statusTip())
image_icon_name = get_select_icon_file_name(object.statusTip())
if i == self.menu_key_index:
button_object.setFocus()
if image_file_name != None :
is_select_object_draw = True
file_url = "url(%s)"%(image_file_name)
self.modify_object_style_sheet(button_object, "border-image", file_url)
elif image_icon_name != None :
is_select_object_draw = True
button_size : QSize = button_object.size()
button_object.setIcon(QIcon(image_icon_name))
button_object.setIconSize(button_size)
else :
if image_file_name != None :
is_select_object_draw = True
self.reset_object_style_sheet(button_object)
elif image_icon_name != None :
is_select_object_draw = True
button_object.setIcon(QIcon())
elif isinstance(object, QLabel) :
label_object : QLabel = object
image_file_name = get_select_imag_file_name(object.statusTip())
if i == self.menu_key_index :
if image_file_name != None :
is_select_object_draw = True
file_url = "url(%s)"%(image_file_name)
self.modify_object_style_sheet(label_object, "border-image", file_url)
else :
if image_file_name != None :
is_select_object_draw = True
self.reset_object_style_sheet(label_object)
elif isinstance(object, QLineEdit) :
line_object : QLineEdit = object
image_file_name = get_select_imag_file_name(object.statusTip())
if i == self.menu_key_index :
if image_file_name != None :
is_select_object_draw = True
file_url = "url(%s)"%(image_file_name)
self.modify_object_style_sheet(line_object, "border-image", file_url)
else :
if image_file_name != None :
is_select_object_draw = True
self.reset_object_style_sheet(line_object)
if is_select_object_draw == False :
if i == self.menu_key_index :
self.modify_object_style_sheet(object, "background-color", COLOR_CYAN)
else :
self.reset_object_style_sheet(object)
def response_topic_message_process(self, topic: str,
message : str,
is_timeout :bool = False, inform : bool = False) :
find_reponse_topic_msg = None
for wait_topic_msg in self.wait_response_list :
if wait_topic_msg[0] == topic :
find_reponse_topic_msg = wait_topic_msg
self.wait_response_list.remove(wait_topic_msg)
break
if find_reponse_topic_msg == None :
return
select_object :QWidget = find_reponse_topic_msg[2]
request_message : str = find_reponse_topic_msg[1]
inform_box : DialogInform = None
if inform :
inform_box : DialogInform = DialogInform()
try :
json_dict = json_load_message(message)
result = utils.dict_or_object_get_attr(json_dict, "result", 0)
result = int(result)
except Exception as e:
json_dict = None
result = 0
print_error_msg(str(e) + "invalid json message: %s" % (message))
if "response/action" in topic :
if is_timeout :
inform_message = "命令执行超时"
if inform == True:
inform_box.information('命令执行超时', inform_message)
else :
inform_message = '命令执行成功' if result == 1 else '命令执行失败!!!'
if inform == True:
inform_box.information('命令执行', inform_message)
elif "response/param/modify" in topic :
if is_timeout :
inform_message = '参数修改超时'
if inform == True:
inform_box.information('参数修改超时', inform_message)
else :
inform_message = '参数修改成功' if result == 1 else '参数修改失败!!!'
if inform == True:
inform_box.information('参数修改', inform_message)
if result == 1 :
self.para_or_measure_query()
elif "response/alias" in topic :
unique_name = topic.replace("response/alias/", "")
if is_timeout :
if json_dict != None :
alias_name = None
if "name" in json_dict.keys() :
alias_name = json_dict["name"]
if alias_name != None :
key_str = get_key_combine_str(alias_name, unique_name)
if key_str in self.alias_dict.keys() :
if isinstance(self.alias_dict[key_str], int) :
self.alias_dict[key_str] = ALIAS_QUERY_NONE
if inform == True:
inform_box.information('获取别名超时', message)
else :
dialog_modify_alias : DialogModifyAlias = DialogModifyAlias(self)
if isinstance(json_dict, list):
for item in json_dict:
for alias_key_name, alias_dict in item.items():
if alias_key_name in request_message:
key_str = get_key_combine_str(alias_key_name, unique_name)
if key_str in self.alias_dict.keys():
self.alias_dict[key_str] = alias_dict
if isinstance(select_object, QLineEdit):
line_select_object: QLineEdit = select_object
caption_str = get_tip_value_str(select_object.statusTip(), "Caption", "")
alias_value = int(line_select_object.text())
dialog_modify_alias.set_alias_item_info(alias_dict, alias_value, caption_str)
self.dialog_modify_alias = dialog_modify_alias
dialog_modify_alias.exec()
break
else:
for alias_key_name, alias_dict in json_dict.items():
if alias_key_name in request_message:
key_str = get_key_combine_str(alias_key_name, unique_name)
if key_str in self.alias_dict.keys():
self.alias_dict[key_str] = alias_dict
if isinstance(select_object, QLineEdit):
line_select_object: QLineEdit = select_object
caption_str = get_tip_value_str(select_object.statusTip(), "Caption", "")
alias_value = int(line_select_object.text())
dialog_modify_alias.set_alias_item_info(alias_dict, alias_value, caption_str)
self.dialog_modify_alias = dialog_modify_alias
dialog_modify_alias.exec()
break
def mqtt_topic_message_process(self, msg) :
topic_msg_item = True
while topic_msg_item != None :
self.mutex.lock()
topic_msg_count = len(self.topic_message_list)
if topic_msg_count > 0:
topic_msg_item = self.topic_message_list.pop(0)
else :
topic_msg_item = None
self.mutex.unlock()
if topic_msg_item != None :
topic = topic_msg_item[0]
message = topic_msg_item[1]
try :
json_dict = json_load_message(message)
except Exception as e :
json_dict = None
print_error_msg("invalid json message : %s"%(message))
if json_dict != None:
if "measure" in topic :
circuit_id = search_circuit_from_topic(topic)
self.update_mqtt_value(circuit_id, json_dict)
# print("<mqtt_topic_message_process>@Line:",inspect.currentframe().f_lineno,'<measure> ','<circuit_id> = ',circuit_id,'<json_dict> = ',json_dict)
self.flush_widgets(circuit_id, json_dict)
elif "param/info" in topic:
circuit_id = search_circuit_from_topic(topic)
#print("<mqtt_topic_message_process>@Line:",inspect.currentframe().f_lineno,'<param/info> ','<circuit_id> = ',circuit_id,'<json_dict> = ',json_dict)
self.update_mqtt_value(circuit_id, json_dict)
self.flush_widgets(circuit_id, json_dict)
elif "response/alarm" in topic :
circuit_id = search_circuit_from_topic(topic)
self.flush_alarminfo(circuit_id, json_dict)
self.update_mqtt_value(circuit_id, json_dict)
self.flush_widgets(circuit_id, json_dict)
elif "response" in topic :
self.response_topic_message_process(topic, message, is_timeout = False, inform = True)
elif "alarm/test" in topic :
circuit_id = search_circuit_from_topic(topic)
# print("<mqtt_topic_message_process>@Line:",inspect.currentframe().f_lineno,'<alarm/test> ','<circuit_id> = ',circuit_id,'<json_dict> = ',json_dict)
# 将告警信息刷新到页面
def flush_alarminfo(self, circuit, json_dict, child = None):
alarmTitle : QLineEdit = self.findChild(QLineEdit,"alarmTitle")
if alarmTitle != None:
display_title = "%s"%(json_dict["index"])
alarmTitle.setText(display_title)
alarmTime : QLineEdit = self.findChild(QLineEdit,"alarmTime")
if alarmTime != None:
display_year = "%s-"%(json_dict["AlarmYear"])
display_month = "%s-"%(json_dict["AlarmMonth"])
display_day = "%s"%(json_dict["AlarmDay"])
display_hour = " %s:"%(json_dict["AlarmHour"])
display_minute = "%s: "%(json_dict["AlarmMinute"])
display_second = "%s"%(json_dict["AlarmSecond"])
disp_time = display_year + display_month + display_day + display_hour+ display_minute+ display_second
alarmTime.setText(disp_time)
alarmMsg : QLineEdit = self.findChild(QLineEdit,"alarmMsg")
if alarmMsg != None:
display_msg = "%s"%(json_dict["AlarmCodeMsg"])
alarmMsg.setText(display_msg)
def on_connect(self, mqtt_thread, userdata, flags, rc) :
if rc == 0:
self.mqtt_thread = mqtt_thread
self.mqtt_thread.subscribe("response/#")
self.mqtt_thread.subscribe("param/info/#")
self.mqtt_thread.subscribe("param/modify/#")
self.mqtt_thread.subscribe("measure/#")
self.mqtt_thread.subscribe("status/#")
self.mqtt_thread.subscribe("alarm/#")
self.mqtt_thread.subscribe("response/alarm/#")
self.mqtt_thread.subscribe("action/#")
self.mqtt_thread.subscribe("globalmeasure/#")
# self.mqtt_thread.subscribe("time_group/#")
else :
self.mqtt_thread = None
def on_message(self, mqtt_thread, topic, message) :
NUMBER_OF_CIRCUITS = 3
circuit_id = search_circuit_from_topic(topic)
if circuit_id < 0 :
return
if (self.exist_circuit_mask & (0x1 << circuit_id)) == 0 :
return
self.mutex.lock()
# 特别处理 globalmeasure 主题
if "globalmeasure/" in topic:
if circuit_id == 2: # 如果消息是来自 circuit_0
for i in range(1, NUMBER_OF_CIRCUITS):
broadcast_topic = f"globalmeasure/circuit_{i}"
self.mqtt_thread.publish(broadcast_topic, message) # 发布消息到
else:
if len(self.topic_message_list) < 100:
self.topic_message_list.append([topic, message]) # 将消息添加到列表中
message_str = message.decode('utf-8')
if "time_group/circuit_0" in topic:
try:
time_data = json.loads(message_str)
year = time_data["Year"]
month = time_data["Month"]
day = time_data["Day"]
hour = time_data["Hour"]
minute = time_data["Minute"]
second = time_data["Second"]
# 检查时间数据是否完整
if all([year, month, day, hour, minute, second]):
set_system_time(int(year), int(month), int(day), int(hour), int(minute), int(second))
print(f"Time updated on circuit_{circuit_id} to: {year}-{month}-{day} {hour}:{minute}:{second}")
else:
print(f"Incomplete time data received on circuit_{circuit_id}")
except Exception as e:
print(f"Error processing time_group message on circuit_{circuit_id}: {e}")
if len(self.topic_message_list) < 100 :
self.topic_message_list.append([topic, message])
self.mutex.unlock()
self.mqtt_signal.emit("Refresh UI")
def response_topic_messge_timeout(self):
timer = self.sender()
for wait_response_items in self.wait_response_list:
wait_timer : QTimer = wait_response_items[3]
_inform : bool = wait_response_items[4]
if wait_timer == timer :
topic : str = wait_response_items[0]
message : str = wait_response_items[1]
wait_timer.stop()
self.response_topic_message_process(topic, message, is_timeout=True, inform = _inform)
break
# def mqtt_publish_and_wait_response(self, publish_topic : str, publish_message : str, select_object : QWidget = None, timeout_ms : int = 1000, inform : bool = True) :
# if self.mqtt_thread != None :
# self.mqtt_thread.publish(publish_topic, publish_message)
# response_topic = publish_topic.replace("request", "response")
# #开启超时定时器
# wait_timer = QTimer()
# wait_timer.timeout.connect(self.response_topic_messge_timeout)
# wait_timer.start(timeout_ms)
# self.wait_response_list.append([response_topic, publish_message, select_object, wait_timer, inform])
def mqtt_publish_and_wait_response(self, publish_topic: str, publish_message: str, select_object: QWidget = None, timeout_ms: int = 1000, inform: bool = True):
if self.mqtt_thread is not None:
# 发布MQTT消息
self.mqtt_thread.publish(publish_topic, publish_message)
# 构建响应主题
response_topic = publish_topic.replace("request", "response")
# 设置并启动超时定时器
wait_timer = QTimer()
wait_timer.timeout.connect(lambda: self.response_topic_message_timeout(response_topic))
wait_timer.start(timeout_ms)
# 将响应信息添加到等待列表
self.wait_response_list.append([response_topic, publish_message, select_object, wait_timer, inform])
def response_topic_message_timeout(self, response_topic):
# 处理超时事件
for response_info in self.wait_response_list:
if response_info[0] == response_topic:
response_info[3].stop() # 停止定时器
self.wait_response_list.remove(response_info)
# 在这里添加超时后的处理逻辑,例如通知用户请求超时
if response_info[4]: # 检查是否需要通知
self.inform_timeout(response_info)
break
def inform_timeout(self, response_info):
# 通知用户请求超时的逻辑
# response_info[2] 是 select_object
# 根据具体需求实现通知逻辑
print(f"Request for {response_info[1]} on topic {response_info[0]} timed out.")
def batch_mqtt_publish_and_wait_response(self, publish_list: list, timeout_ms: int = 1000, inform: bool = True):
if self.mqtt_thread is not None:
for publish_topic, publish_message, select_object in publish_list:
# 发布MQTT消息
self.mqtt_thread.publish(publish_topic, publish_message)
# 构建响应主题
response_topic = publish_topic.replace("request", "response")
# 设置并启动超时定时器
wait_timer = QTimer()
wait_timer.timeout.connect(lambda rt=response_topic: self.response_topic_message_timeout(rt))
wait_timer.start(timeout_ms)
# 将响应信息添加到等待列表
self.wait_response_list.append([response_topic, publish_message, select_object, wait_timer, inform])
def para_or_measure_query(self, child = None) :
widget :QWidget = self
if child == None :
self.param_dict = {}
else :
widget = child
for child_widget in widget.children():
if hasattr(child_widget, "statusTip") :
tip_str : str = child_widget.statusTip()
if "ScreenBlankingTime" in tip_str :
sbt = system_parameter()
child_widget.setText(sbt.get_screen_blanking_time())
continue
mqtt_str = get_tip_mqtt_name(tip_str)
if mqtt_str != None and mqtt_str not in self.param_dict.keys():
unique_name = self.get_unique_name_from_object(child_widget)
if unique_name != None and self.mqtt_thread != None:
self.mqtt_thread.publish("request/param/info/"+unique_name, '{"name":"%s"}'%mqtt_str)
self.param_dict[mqtt_str] = ALIAS_QUERY_NONE
self.para_or_measure_query(child_widget)
def flush_system_cycle(self) :
self.flush_system_info()
if __name__ == '__main__':
style_sheet = "QLabel {color : RED;\nbackground-color : GREEN;}"
print(style_sheet)
new_style_items = modify_style_sheet("QLabel", style_sheet, "background-color", "WHITE")
new_style_items = modify_style_sheet("QLabel", new_style_items, "color", "YELLOW")
print(new_style_items)
sys.exit(0)