From bd30815b598120c042886e95d64ff22a03bb539d Mon Sep 17 00:00:00 2001 From: zhu-mengmeng <15588200382@163.com> Date: Sat, 7 Jun 2025 10:45:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=A7=86=E9=A2=91=E9=9B=86?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- camera/BasicDemo.py | 362 ++++ camera/CamOperation_class.py | 376 ++++ camera/CameraParams_const.py | 82 + camera/CameraParams_header.py | 1289 +++++++++++++ camera/MvCameraControl_class.py | 1104 +++++++++++ camera/MvErrorDefine_const.py | 67 + camera/PixelType_header.py | 258 +++ camera/PyUICBasicDemo.py | 146 ++ camera/PyUICBasicDemo.ui | 261 +++ .../CamOperation_class.cpython-310.pyc | Bin 0 -> 9574 bytes .../CameraParams_const.cpython-310.pyc | Bin 0 -> 1701 bytes .../CameraParams_header.cpython-310.pyc | Bin 0 -> 24670 bytes .../MvCameraControl_class.cpython-310.pyc | Bin 0 -> 29747 bytes .../MvErrorDefine_const.cpython-310.pyc | Bin 0 -> 1997 bytes .../PixelType_header.cpython-310.pyc | Bin 0 -> 6032 bytes config/app_config.json | 19 + config/application.yaml | 5 + dao/login_dao.py | 52 + db/jtDB.db | Bin 0 -> 16384 bytes logs/app_2025-06-05.log | 1628 +++++++++++++++++ logs/app_2025-06-06.log | 15 + logs/app_2025-06-07.log | 172 ++ main.py | 200 ++ ui/__pycache__/login_ui.cpython-310.pyc | Bin 0 -> 2362 bytes ui/__pycache__/main_window_ui.cpython-310.pyc | Bin 0 -> 15939 bytes ui/__pycache__/settings_ui.cpython-310.pyc | Bin 0 -> 8224 bytes ui/login_ui.py | 85 + ui/main_window_ui.py | 742 ++++++++ ui/settings_ui.py | 369 ++++ .../__pycache__/config_loader.cpython-310.pyc | Bin 0 -> 3340 bytes .../menu_translator.cpython-310.pyc | Bin 0 -> 1045 bytes utils/__pycache__/sql_utils.cpython-310.pyc | Bin 0 -> 2678 bytes .../version_manager.cpython-310.pyc | Bin 0 -> 7036 bytes utils/config_loader.py | 130 ++ utils/init_db.py | 46 + utils/menu_translator.py | 19 + utils/sql_utils.py | 78 + utils/version_manager.py | 262 +++ .../camera_display_widget.cpython-310.pyc | Bin 0 -> 3845 bytes .../camera_manager.cpython-310.pyc | Bin 0 -> 7948 bytes .../camera_settings_widget.cpython-310.pyc | Bin 0 -> 7840 bytes .../__pycache__/login_widget.cpython-310.pyc | Bin 0 -> 3474 bytes .../__pycache__/main_window.cpython-310.pyc | Bin 0 -> 6351 bytes widgets/camera_display_widget.py | 137 ++ widgets/camera_manager.py | 354 ++++ widgets/camera_settings_widget.py | 324 ++++ widgets/camera_widget.py | 298 +++ widgets/login_widget.py | 98 + widgets/main_window.py | 213 +++ widgets/settings_dialog.py | 57 + widgets/settings_widget.py | 140 ++ 51 files changed, 9388 insertions(+) create mode 100644 camera/BasicDemo.py create mode 100644 camera/CamOperation_class.py create mode 100644 camera/CameraParams_const.py create mode 100644 camera/CameraParams_header.py create mode 100644 camera/MvCameraControl_class.py create mode 100644 camera/MvErrorDefine_const.py create mode 100644 camera/PixelType_header.py create mode 100644 camera/PyUICBasicDemo.py create mode 100644 camera/PyUICBasicDemo.ui create mode 100644 camera/__pycache__/CamOperation_class.cpython-310.pyc create mode 100644 camera/__pycache__/CameraParams_const.cpython-310.pyc create mode 100644 camera/__pycache__/CameraParams_header.cpython-310.pyc create mode 100644 camera/__pycache__/MvCameraControl_class.cpython-310.pyc create mode 100644 camera/__pycache__/MvErrorDefine_const.cpython-310.pyc create mode 100644 camera/__pycache__/PixelType_header.cpython-310.pyc create mode 100644 config/app_config.json create mode 100644 config/application.yaml create mode 100644 dao/login_dao.py create mode 100644 db/jtDB.db create mode 100644 logs/app_2025-06-05.log create mode 100644 logs/app_2025-06-06.log create mode 100644 logs/app_2025-06-07.log create mode 100644 main.py create mode 100644 ui/__pycache__/login_ui.cpython-310.pyc create mode 100644 ui/__pycache__/main_window_ui.cpython-310.pyc create mode 100644 ui/__pycache__/settings_ui.cpython-310.pyc create mode 100644 ui/login_ui.py create mode 100644 ui/main_window_ui.py create mode 100644 ui/settings_ui.py create mode 100644 utils/__pycache__/config_loader.cpython-310.pyc create mode 100644 utils/__pycache__/menu_translator.cpython-310.pyc create mode 100644 utils/__pycache__/sql_utils.cpython-310.pyc create mode 100644 utils/__pycache__/version_manager.cpython-310.pyc create mode 100644 utils/config_loader.py create mode 100644 utils/init_db.py create mode 100644 utils/menu_translator.py create mode 100644 utils/sql_utils.py create mode 100644 utils/version_manager.py create mode 100644 widgets/__pycache__/camera_display_widget.cpython-310.pyc create mode 100644 widgets/__pycache__/camera_manager.cpython-310.pyc create mode 100644 widgets/__pycache__/camera_settings_widget.cpython-310.pyc create mode 100644 widgets/__pycache__/login_widget.cpython-310.pyc create mode 100644 widgets/__pycache__/main_window.cpython-310.pyc create mode 100644 widgets/camera_display_widget.py create mode 100644 widgets/camera_manager.py create mode 100644 widgets/camera_settings_widget.py create mode 100644 widgets/camera_widget.py create mode 100644 widgets/login_widget.py create mode 100644 widgets/main_window.py create mode 100644 widgets/settings_dialog.py create mode 100644 widgets/settings_widget.py diff --git a/camera/BasicDemo.py b/camera/BasicDemo.py new file mode 100644 index 0000000..c1f62ee --- /dev/null +++ b/camera/BasicDemo.py @@ -0,0 +1,362 @@ +# -*- coding: utf-8 -*- +import sys +from PyQt5.QtWidgets import * +from CamOperation_class import CameraOperation +from MvCameraControl_class import * +from MvErrorDefine_const import * +from CameraParams_header import * +from PyUICBasicDemo import Ui_MainWindow +import ctypes + + +# 获取选取设备信息的索引,通过[]之间的字符去解析 +def TxtWrapBy(start_str, end, all): + start = all.find(start_str) + if start >= 0: + start += len(start_str) + end = all.find(end, start) + if end >= 0: + return all[start:end].strip() + + +# 将返回的错误码转换为十六进制显示 +def ToHexStr(num): + chaDic = {10: 'a', 11: 'b', 12: 'c', 13: 'd', 14: 'e', 15: 'f'} + hexStr = "" + if num < 0: + num = num + 2 ** 32 + while num >= 16: + digit = num % 16 + hexStr = chaDic.get(digit, str(digit)) + hexStr + num //= 16 + hexStr = chaDic.get(num, str(num)) + hexStr + return hexStr + + +if __name__ == "__main__": + + # ch:初始化SDK | en: initialize SDK + MvCamera.MV_CC_Initialize() + + global deviceList + deviceList = MV_CC_DEVICE_INFO_LIST() + global cam + cam = MvCamera() + global nSelCamIndex + nSelCamIndex = 0 + global obj_cam_operation + obj_cam_operation = 0 + global isOpen + isOpen = False + global isGrabbing + isGrabbing = False + global isCalibMode # 是否是标定模式(获取原始图像) + isCalibMode = True + + # 绑定下拉列表至设备信息索引 + def xFunc(event): + global nSelCamIndex + nSelCamIndex = TxtWrapBy("[", "]", ui.ComboDevices.get()) + + # Decoding Characters + def decoding_char(c_ubyte_value): + c_char_p_value = ctypes.cast(c_ubyte_value, ctypes.c_char_p) + try: + decode_str = c_char_p_value.value.decode('gbk') # Chinese characters + except UnicodeDecodeError: + decode_str = str(c_char_p_value.value) + return decode_str + + # ch:枚举相机 | en:enum devices + def enum_devices(): + global deviceList + global obj_cam_operation + + deviceList = MV_CC_DEVICE_INFO_LIST() + n_layer_type = (MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE + | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE) + ret = MvCamera.MV_CC_EnumDevices(n_layer_type, deviceList) + if ret != 0: + strError = "Enum devices fail! ret = :" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + return ret + + if deviceList.nDeviceNum == 0: + QMessageBox.warning(mainWindow, "Info", "Find no device", QMessageBox.Ok) + return ret + print("Find %d devices!" % deviceList.nDeviceNum) + + devList = [] + for i in range(0, deviceList.nDeviceNum): + mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents + if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE or mvcc_dev_info.nTLayerType == MV_GENTL_GIGE_DEVICE: + print("\ngige device: [%d]" % i) + user_defined_name = decoding_char(mvcc_dev_info.SpecialInfo.stGigEInfo.chUserDefinedName) + model_name = decoding_char(mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName) + print("device user define name: " + user_defined_name) + print("device model name: " + model_name) + + nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24) + nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16) + nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8) + nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff) + print("current ip: %d.%d.%d.%d " % (nip1, nip2, nip3, nip4)) + devList.append( + "[" + str(i) + "]GigE: " + user_defined_name + " " + model_name + "(" + str(nip1) + "." + str( + nip2) + "." + str(nip3) + "." + str(nip4) + ")") + elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE: + print("\nu3v device: [%d]" % i) + user_defined_name = decoding_char(mvcc_dev_info.SpecialInfo.stUsb3VInfo.chUserDefinedName) + model_name = decoding_char(mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName) + print("device user define name: " + user_defined_name) + print("device model name: " + model_name) + + strSerialNumber = "" + for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber: + if per == 0: + break + strSerialNumber = strSerialNumber + chr(per) + print("user serial number: " + strSerialNumber) + devList.append("[" + str(i) + "]USB: " + user_defined_name + " " + model_name + + "(" + str(strSerialNumber) + ")") + elif mvcc_dev_info.nTLayerType == MV_GENTL_CAMERALINK_DEVICE: + print("\nCML device: [%d]" % i) + user_defined_name = decoding_char(mvcc_dev_info.SpecialInfo.stCMLInfo.chUserDefinedName) + model_name = decoding_char(mvcc_dev_info.SpecialInfo.stCMLInfo.chModelName) + print("device user define name: " + user_defined_name) + print("device model name: " + model_name) + + strSerialNumber = "" + for per in mvcc_dev_info.SpecialInfo.stCMLInfo.chSerialNumber: + if per == 0: + break + strSerialNumber = strSerialNumber + chr(per) + print("user serial number: " + strSerialNumber) + devList.append("[" + str(i) + "]CML: " + user_defined_name + " " + model_name + + "(" + str(strSerialNumber) + ")") + elif mvcc_dev_info.nTLayerType == MV_GENTL_CXP_DEVICE: + print("\nCXP device: [%d]" % i) + user_defined_name = decoding_char(mvcc_dev_info.SpecialInfo.stCXPInfo.chUserDefinedName) + model_name = decoding_char(mvcc_dev_info.SpecialInfo.stCXPInfo.chModelName) + print("device user define name: " + user_defined_name) + print("device model name: " + model_name) + + strSerialNumber = "" + for per in mvcc_dev_info.SpecialInfo.stCXPInfo.chSerialNumber: + if per == 0: + break + strSerialNumber = strSerialNumber + chr(per) + print("user serial number: " + strSerialNumber) + devList.append("[" + str(i) + "]CXP: " + user_defined_name + " " + model_name + + "(" + str(strSerialNumber) + ")") + elif mvcc_dev_info.nTLayerType == MV_GENTL_XOF_DEVICE: + print("\nXoF device: [%d]" % i) + user_defined_name = decoding_char(mvcc_dev_info.SpecialInfo.stXoFInfo.chUserDefinedName) + model_name = decoding_char(mvcc_dev_info.SpecialInfo.stXoFInfo.chModelName) + print("device user define name: " + user_defined_name) + print("device model name: " + model_name) + + strSerialNumber = "" + for per in mvcc_dev_info.SpecialInfo.stXoFInfo.chSerialNumber: + if per == 0: + break + strSerialNumber = strSerialNumber + chr(per) + print("user serial number: " + strSerialNumber) + devList.append("[" + str(i) + "]XoF: " + user_defined_name + " " + model_name + + "(" + str(strSerialNumber) + ")") + + ui.ComboDevices.clear() + ui.ComboDevices.addItems(devList) + ui.ComboDevices.setCurrentIndex(0) + + # ch:打开相机 | en:open device + def open_device(): + global deviceList + global nSelCamIndex + global obj_cam_operation + global isOpen + if isOpen: + QMessageBox.warning(mainWindow, "Error", 'Camera is Running!', QMessageBox.Ok) + return MV_E_CALLORDER + + nSelCamIndex = ui.ComboDevices.currentIndex() + if nSelCamIndex < 0: + QMessageBox.warning(mainWindow, "Error", 'Please select a camera!', QMessageBox.Ok) + return MV_E_CALLORDER + + obj_cam_operation = CameraOperation(cam, deviceList, nSelCamIndex) + ret = obj_cam_operation.Open_device() + if 0 != ret: + strError = "Open device failed ret:" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + isOpen = False + else: + set_continue_mode() + + get_param() + + isOpen = True + enable_controls() + + # ch:开始取流 | en:Start grab image + def start_grabbing(): + global obj_cam_operation + global isGrabbing + + ret = obj_cam_operation.Start_grabbing(ui.widgetDisplay.winId()) + if ret != 0: + strError = "Start grabbing failed ret:" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + else: + isGrabbing = True + enable_controls() + + # ch:停止取流 | en:Stop grab image + def stop_grabbing(): + global obj_cam_operation + global isGrabbing + ret = obj_cam_operation.Stop_grabbing() + if ret != 0: + strError = "Stop grabbing failed ret:" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + else: + isGrabbing = False + enable_controls() + + # ch:关闭设备 | Close device + def close_device(): + global isOpen + global isGrabbing + global obj_cam_operation + + if isOpen: + obj_cam_operation.Close_device() + isOpen = False + + isGrabbing = False + + enable_controls() + + # ch:设置触发模式 | en:set trigger mode + def set_continue_mode(): + ret = obj_cam_operation.Set_trigger_mode(False) + if ret != 0: + strError = "Set continue mode failed ret:" + ToHexStr(ret) + " mode is " + str(is_trigger_mode) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + else: + ui.radioContinueMode.setChecked(True) + ui.radioTriggerMode.setChecked(False) + ui.bnSoftwareTrigger.setEnabled(False) + + # ch:设置软触发模式 | en:set software trigger mode + def set_software_trigger_mode(): + ret = obj_cam_operation.Set_trigger_mode(True) + if ret != 0: + strError = "Set trigger mode failed ret:" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + else: + ui.radioContinueMode.setChecked(False) + ui.radioTriggerMode.setChecked(True) + ui.bnSoftwareTrigger.setEnabled(isGrabbing) + + # ch:设置触发命令 | en:set trigger software + def trigger_once(): + ret = obj_cam_operation.Trigger_once() + if ret != 0: + strError = "TriggerSoftware failed ret:" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + + # ch:存图 | en:save image + def save_bmp(): + ret = obj_cam_operation.Save_Bmp() + if ret != MV_OK: + strError = "Save BMP failed ret:" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + else: + print("Save image success") + + def is_float(str): + try: + float(str) + return True + except ValueError: + return False + + + # ch: 获取参数 | en:get param + def get_param(): + ret = obj_cam_operation.Get_parameter() + if ret != MV_OK: + strError = "Get param failed ret:" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + else: + ui.edtExposureTime.setText("{0:.2f}".format(obj_cam_operation.exposure_time)) + ui.edtGain.setText("{0:.2f}".format(obj_cam_operation.gain)) + ui.edtFrameRate.setText("{0:.2f}".format(obj_cam_operation.frame_rate)) + + # ch: 设置参数 | en:set param + def set_param(): + frame_rate = ui.edtFrameRate.text() + exposure = ui.edtExposureTime.text() + gain = ui.edtGain.text() + + if is_float(frame_rate)!=True or is_float(exposure)!=True or is_float(gain)!=True: + strError = "Set param failed ret:" + ToHexStr(MV_E_PARAMETER) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + return MV_E_PARAMETER + + ret = obj_cam_operation.Set_parameter(frame_rate, exposure, gain) + if ret != MV_OK: + strError = "Set param failed ret:" + ToHexStr(ret) + QMessageBox.warning(mainWindow, "Error", strError, QMessageBox.Ok) + + return MV_OK + + # ch: 设置控件状态 | en:set enable status + def enable_controls(): + global isGrabbing + global isOpen + + # 先设置group的状态,再单独设置各控件状态 + ui.groupGrab.setEnabled(isOpen) + ui.groupParam.setEnabled(isOpen) + + ui.bnOpen.setEnabled(not isOpen) + ui.bnClose.setEnabled(isOpen) + + ui.bnStart.setEnabled(isOpen and (not isGrabbing)) + ui.bnStop.setEnabled(isOpen and isGrabbing) + ui.bnSoftwareTrigger.setEnabled(isGrabbing and ui.radioTriggerMode.isChecked()) + + ui.bnSaveImage.setEnabled(isOpen and isGrabbing) + + # ch: 初始化app, 绑定控件与函数 | en: Init app, bind ui and api + app = QApplication(sys.argv) + mainWindow = QMainWindow() + ui = Ui_MainWindow() + ui.setupUi(mainWindow) + ui.bnEnum.clicked.connect(enum_devices) + ui.bnOpen.clicked.connect(open_device) + ui.bnClose.clicked.connect(close_device) + ui.bnStart.clicked.connect(start_grabbing) + ui.bnStop.clicked.connect(stop_grabbing) + + ui.bnSoftwareTrigger.clicked.connect(trigger_once) + ui.radioTriggerMode.clicked.connect(set_software_trigger_mode) + ui.radioContinueMode.clicked.connect(set_continue_mode) + + ui.bnGetParam.clicked.connect(get_param) + ui.bnSetParam.clicked.connect(set_param) + + ui.bnSaveImage.clicked.connect(save_bmp) + + mainWindow.show() + + app.exec_() + + close_device() + + # ch:反初始化SDK | en: finalize SDK + MvCamera.MV_CC_Finalize() + + sys.exit() diff --git a/camera/CamOperation_class.py b/camera/CamOperation_class.py new file mode 100644 index 0000000..42732ab --- /dev/null +++ b/camera/CamOperation_class.py @@ -0,0 +1,376 @@ +# -- coding: utf-8 -- +import threading +import time +import sys +import inspect +import ctypes +import random +from ctypes import * + +sys.path.append("../MvImport") + +from CameraParams_header import * +from MvCameraControl_class import * + +# 强制关闭线程 +def Async_raise(tid, exctype): + tid = ctypes.c_long(tid) + if not inspect.isclass(exctype): + exctype = type(exctype) + res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype)) + if res == 0: + raise ValueError("invalid thread id") + elif res != 1: + ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None) + raise SystemError("PyThreadState_SetAsyncExc failed") + + +# 停止线程 +def Stop_thread(thread): + Async_raise(thread.ident, SystemExit) + + +# 转为16进制字符串 +def To_hex_str(num): + chaDic = {10: 'a', 11: 'b', 12: 'c', 13: 'd', 14: 'e', 15: 'f'} + hexStr = "" + if num < 0: + num = num + 2 ** 32 + while num >= 16: + digit = num % 16 + hexStr = chaDic.get(digit, str(digit)) + hexStr + num //= 16 + hexStr = chaDic.get(num, str(num)) + hexStr + return hexStr + + +# 是否是Mono图像 +def Is_mono_data(enGvspPixelType): + if PixelType_Gvsp_Mono8 == enGvspPixelType or PixelType_Gvsp_Mono10 == enGvspPixelType \ + or PixelType_Gvsp_Mono10_Packed == enGvspPixelType or PixelType_Gvsp_Mono12 == enGvspPixelType \ + or PixelType_Gvsp_Mono12_Packed == enGvspPixelType: + return True + else: + return False + + +# 是否是彩色图像 +def Is_color_data(enGvspPixelType): + if PixelType_Gvsp_BayerGR8 == enGvspPixelType or PixelType_Gvsp_BayerRG8 == enGvspPixelType \ + or PixelType_Gvsp_BayerGB8 == enGvspPixelType or PixelType_Gvsp_BayerBG8 == enGvspPixelType \ + or PixelType_Gvsp_BayerGR10 == enGvspPixelType or PixelType_Gvsp_BayerRG10 == enGvspPixelType \ + or PixelType_Gvsp_BayerGB10 == enGvspPixelType or PixelType_Gvsp_BayerBG10 == enGvspPixelType \ + or PixelType_Gvsp_BayerGR12 == enGvspPixelType or PixelType_Gvsp_BayerRG12 == enGvspPixelType \ + or PixelType_Gvsp_BayerGB12 == enGvspPixelType or PixelType_Gvsp_BayerBG12 == enGvspPixelType \ + or PixelType_Gvsp_BayerGR10_Packed == enGvspPixelType or PixelType_Gvsp_BayerRG10_Packed == enGvspPixelType \ + or PixelType_Gvsp_BayerGB10_Packed == enGvspPixelType or PixelType_Gvsp_BayerBG10_Packed == enGvspPixelType \ + or PixelType_Gvsp_BayerGR12_Packed == enGvspPixelType or PixelType_Gvsp_BayerRG12_Packed == enGvspPixelType \ + or PixelType_Gvsp_BayerGB12_Packed == enGvspPixelType or PixelType_Gvsp_BayerBG12_Packed == enGvspPixelType \ + or PixelType_Gvsp_YUV422_Packed == enGvspPixelType or PixelType_Gvsp_YUV422_YUYV_Packed == enGvspPixelType: + return True + else: + return False + + +# 相机操作类 +class CameraOperation: + + def __init__(self, obj_cam, st_device_list, n_connect_num=0, b_open_device=False, b_start_grabbing=False, + h_thread_handle=None, + b_thread_closed=False, st_frame_info=None, b_exit=False, b_save_bmp=False, b_save_jpg=False, + buf_save_image=None, + n_save_image_size=0, n_win_gui_id=0, frame_rate=0, exposure_time=0, gain=0): + + self.obj_cam = obj_cam + self.st_device_list = st_device_list + self.n_connect_num = n_connect_num + self.b_open_device = b_open_device + self.b_start_grabbing = b_start_grabbing + self.b_thread_closed = b_thread_closed + self.st_frame_info = st_frame_info + self.b_exit = b_exit + self.b_save_bmp = b_save_bmp + self.b_save_jpg = b_save_jpg + self.buf_save_image = buf_save_image + self.n_save_image_size = n_save_image_size + self.h_thread_handle = h_thread_handle + self.b_thread_closed + self.frame_rate = frame_rate + self.exposure_time = exposure_time + self.gain = gain + self.buf_lock = threading.Lock() # 取图和存图的buffer锁 + + # 打开相机 + def Open_device(self): + if not self.b_open_device: + if self.n_connect_num < 0: + return MV_E_CALLORDER + + # ch:选择设备并创建句柄 | en:Select device and create handle + nConnectionNum = int(self.n_connect_num) + stDeviceList = cast(self.st_device_list.pDeviceInfo[int(nConnectionNum)], + POINTER(MV_CC_DEVICE_INFO)).contents + self.obj_cam = MvCamera() + ret = self.obj_cam.MV_CC_CreateHandle(stDeviceList) + if ret != 0: + self.obj_cam.MV_CC_DestroyHandle() + return ret + + ret = self.obj_cam.MV_CC_OpenDevice() + if ret != 0: + return ret + print("open device successfully!") + self.b_open_device = True + self.b_thread_closed = False + + # ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera) + if stDeviceList.nTLayerType == MV_GIGE_DEVICE or stDeviceList.nTLayerType == MV_GENTL_GIGE_DEVICE: + nPacketSize = self.obj_cam.MV_CC_GetOptimalPacketSize() + if int(nPacketSize) > 0: + ret = self.obj_cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize) + if ret != 0: + print("warning: set packet size fail! ret[0x%x]" % ret) + else: + print("warning: set packet size fail! ret[0x%x]" % nPacketSize) + + stBool = c_bool(False) + ret = self.obj_cam.MV_CC_GetBoolValue("AcquisitionFrameRateEnable", stBool) + if ret != 0: + print("get acquisition frame rate enable fail! ret[0x%x]" % ret) + + # ch:设置触发模式为off | en:Set trigger mode as off + ret = self.obj_cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF) + if ret != 0: + print("set trigger mode fail! ret[0x%x]" % ret) + return MV_OK + + # 开始取图 + def Start_grabbing(self, winHandle): + if not self.b_start_grabbing and self.b_open_device: + self.b_exit = False + ret = self.obj_cam.MV_CC_StartGrabbing() + if ret != 0: + return ret + self.b_start_grabbing = True + print("start grabbing successfully!") + try: + thread_id = random.randint(1, 10000) + self.h_thread_handle = threading.Thread(target=CameraOperation.Work_thread, args=(self, winHandle)) + self.h_thread_handle.start() + self.b_thread_closed = True + finally: + pass + return MV_OK + + return MV_E_CALLORDER + + # 停止取图 + def Stop_grabbing(self): + if self.b_start_grabbing and self.b_open_device: + # 退出线程 + if self.b_thread_closed: + Stop_thread(self.h_thread_handle) + self.b_thread_closed = False + ret = self.obj_cam.MV_CC_StopGrabbing() + if ret != 0: + return ret + print("stop grabbing successfully!") + self.b_start_grabbing = False + self.b_exit = True + return MV_OK + else: + return MV_E_CALLORDER + + # 关闭相机 + def Close_device(self): + if self.b_open_device: + # 退出线程 + if self.b_thread_closed: + Stop_thread(self.h_thread_handle) + self.b_thread_closed = False + ret = self.obj_cam.MV_CC_CloseDevice() + if ret != 0: + return ret + + # ch:销毁句柄 | Destroy handle + self.obj_cam.MV_CC_DestroyHandle() + self.b_open_device = False + self.b_start_grabbing = False + self.b_exit = True + print("close device successfully!") + + return MV_OK + + # 设置触发模式 + def Set_trigger_mode(self, is_trigger_mode): + if not self.b_open_device: + return MV_E_CALLORDER + + if not is_trigger_mode: + ret = self.obj_cam.MV_CC_SetEnumValue("TriggerMode", 0) + if ret != 0: + return ret + else: + ret = self.obj_cam.MV_CC_SetEnumValue("TriggerMode", 1) + if ret != 0: + return ret + ret = self.obj_cam.MV_CC_SetEnumValue("TriggerSource", 7) + if ret != 0: + return ret + + return MV_OK + + # 软触发一次 + def Trigger_once(self): + if self.b_open_device: + return self.obj_cam.MV_CC_SetCommandValue("TriggerSoftware") + + # 获取参数 + def Get_parameter(self): + if self.b_open_device: + stFloatParam_FrameRate = MVCC_FLOATVALUE() + memset(byref(stFloatParam_FrameRate), 0, sizeof(MVCC_FLOATVALUE)) + stFloatParam_exposureTime = MVCC_FLOATVALUE() + memset(byref(stFloatParam_exposureTime), 0, sizeof(MVCC_FLOATVALUE)) + stFloatParam_gain = MVCC_FLOATVALUE() + memset(byref(stFloatParam_gain), 0, sizeof(MVCC_FLOATVALUE)) + ret = self.obj_cam.MV_CC_GetFloatValue("AcquisitionFrameRate", stFloatParam_FrameRate) + if ret != 0: + return ret + self.frame_rate = stFloatParam_FrameRate.fCurValue + + ret = self.obj_cam.MV_CC_GetFloatValue("ExposureTime", stFloatParam_exposureTime) + if ret != 0: + return ret + self.exposure_time = stFloatParam_exposureTime.fCurValue + + ret = self.obj_cam.MV_CC_GetFloatValue("Gain", stFloatParam_gain) + if ret != 0: + return ret + self.gain = stFloatParam_gain.fCurValue + + return MV_OK + + # 设置参数 + def Set_parameter(self, frameRate, exposureTime, gain): + if '' == frameRate or '' == exposureTime or '' == gain: + print('show info', 'please type in the text box !') + return MV_E_PARAMETER + if self.b_open_device: + ret = self.obj_cam.MV_CC_SetEnumValue("ExposureAuto", 0) + time.sleep(0.2) + ret = self.obj_cam.MV_CC_SetFloatValue("ExposureTime", float(exposureTime)) + if ret != 0: + print('show error', 'set exposure time fail! ret = ' + To_hex_str(ret)) + return ret + + ret = self.obj_cam.MV_CC_SetFloatValue("Gain", float(gain)) + if ret != 0: + print('show error', 'set gain fail! ret = ' + To_hex_str(ret)) + return ret + + ret = self.obj_cam.MV_CC_SetFloatValue("AcquisitionFrameRate", float(frameRate)) + if ret != 0: + print('show error', 'set acquistion frame rate fail! ret = ' + To_hex_str(ret)) + return ret + + print('show info', 'set parameter success!') + + return MV_OK + + # 取图线程函数 + def Work_thread(self, winHandle): + stOutFrame = MV_FRAME_OUT() + memset(byref(stOutFrame), 0, sizeof(stOutFrame)) + + while True: + ret = self.obj_cam.MV_CC_GetImageBuffer(stOutFrame, 1000) + if 0 == ret: + # 拷贝图像和图像信息 + if self.buf_save_image is None: + self.buf_save_image = (c_ubyte * stOutFrame.stFrameInfo.nFrameLen)() + self.st_frame_info = stOutFrame.stFrameInfo + + # 获取缓存锁 + self.buf_lock.acquire() + cdll.msvcrt.memcpy(byref(self.buf_save_image), stOutFrame.pBufAddr, self.st_frame_info.nFrameLen) + self.buf_lock.release() + + print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" + % (self.st_frame_info.nWidth, self.st_frame_info.nHeight, self.st_frame_info.nFrameNum)) + # 释放缓存 + self.obj_cam.MV_CC_FreeImageBuffer(stOutFrame) + else: + print("no data, ret = " + To_hex_str(ret)) + continue + + # 使用Display接口显示图像 + stDisplayParam = MV_DISPLAY_FRAME_INFO() + memset(byref(stDisplayParam), 0, sizeof(stDisplayParam)) + stDisplayParam.hWnd = int(winHandle) + stDisplayParam.nWidth = self.st_frame_info.nWidth + stDisplayParam.nHeight = self.st_frame_info.nHeight + stDisplayParam.enPixelType = self.st_frame_info.enPixelType + stDisplayParam.pData = self.buf_save_image + stDisplayParam.nDataLen = self.st_frame_info.nFrameLen + self.obj_cam.MV_CC_DisplayOneFrame(stDisplayParam) + + # 是否退出 + if self.b_exit: + if self.buf_save_image is not None: + del self.buf_save_image + break + + # 存jpg图像 + def Save_jpg(self): + + if self.buf_save_image is None: + return + + # 获取缓存锁 + self.buf_lock.acquire() + + file_path = str(self.st_frame_info.nFrameNum) + ".jpg" + c_file_path = file_path.encode('ascii') + stSaveParam = MV_SAVE_IMAGE_TO_FILE_PARAM_EX() + stSaveParam.enPixelType = self.st_frame_info.enPixelType # ch:相机对应的像素格式 | en:Camera pixel type + stSaveParam.nWidth = self.st_frame_info.nWidth # ch:相机对应的宽 | en:Width + stSaveParam.nHeight = self.st_frame_info.nHeight # ch:相机对应的高 | en:Height + stSaveParam.nDataLen = self.st_frame_info.nFrameLen + stSaveParam.pData = cast(self.buf_save_image, POINTER(c_ubyte)) + stSaveParam.enImageType = MV_Image_Jpeg # ch:需要保存的图像类型 | en:Image format to save + stSaveParam.nQuality = 80 + stSaveParam.pcImagePath = ctypes.create_string_buffer(c_file_path) + stSaveParam.iMethodValue = 1 + ret = self.obj_cam.MV_CC_SaveImageToFileEx(stSaveParam) + + self.buf_lock.release() + return ret + + # 存BMP图像 + def Save_Bmp(self): + + if 0 == self.buf_save_image: + return + + # 获取缓存锁 + self.buf_lock.acquire() + + file_path = str(self.st_frame_info.nFrameNum) + ".bmp" + c_file_path = file_path.encode('ascii') + + stSaveParam = MV_SAVE_IMAGE_TO_FILE_PARAM_EX() + stSaveParam.enPixelType = self.st_frame_info.enPixelType # ch:相机对应的像素格式 | en:Camera pixel type + stSaveParam.nWidth = self.st_frame_info.nWidth # ch:相机对应的宽 | en:Width + stSaveParam.nHeight = self.st_frame_info.nHeight # ch:相机对应的高 | en:Height + stSaveParam.nDataLen = self.st_frame_info.nFrameLen + stSaveParam.pData = cast(self.buf_save_image, POINTER(c_ubyte)) + stSaveParam.enImageType = MV_Image_Bmp # ch:需要保存的图像类型 | en:Image format to save + stSaveParam.pcImagePath = ctypes.create_string_buffer(c_file_path) + stSaveParam.iMethodValue = 1 + ret = self.obj_cam.MV_CC_SaveImageToFileEx(stSaveParam) + + self.buf_lock.release() + + return ret + diff --git a/camera/CameraParams_const.py b/camera/CameraParams_const.py new file mode 100644 index 0000000..505ba6a --- /dev/null +++ b/camera/CameraParams_const.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# \~chinese 设备类型定义 \~english Device Type Definition +MV_UNKNOW_DEVICE = 0x00000000 # < \~chinese 未知设备类型,保留意义 \~english Unknown Device Type, Reserved +MV_GIGE_DEVICE = 0x00000001 # < \~chinese GigE设备 \~english GigE Device +MV_1394_DEVICE = 0x00000002 # < \~chinese 1394-a/b 设备 \~english 1394-a/b Device +MV_USB_DEVICE = 0x00000004 # < \~chinese USB 设备 \~english USB Device +MV_CAMERALINK_DEVICE = 0x00000008 # < \~chinese CameraLink设备 \~english CameraLink Device +MV_VIR_GIGE_DEVICE = 0x00000010 # < \~chinese 虚拟GigE设备 \~english Virtual GigE Device +MV_VIR_USB_DEVICE = 0x00000020 # < \~chinese 虚拟USB设备 \~english Virtual USB Device +MV_GENTL_GIGE_DEVICE = 0x00000040 # < \~chinese 自研网卡下GigE设备 \~english GenTL GigE Device +MV_GENTL_CAMERALINK_DEVICE = 0x00000080 # < \~chinese CameraLink设备 \~english GenTL CameraLink Device +MV_GENTL_CXP_DEVICE = 0x00000100 # < \~chinese CoaXPress设备 \~english GenTL CoaXPress Device +MV_GENTL_XOF_DEVICE = 0x00000200 # < \~chinese XoF设备 \~english GenTL XoF Device + +# \~chinese 采集卡类型 \~english Interface type +MV_GIGE_INTERFACE = 0x00000001 # < \~chinese GigE Vision采集卡 \~english GigE Vision interface +MV_CAMERALINK_INTERFACE = 0x00000004 # < \~chinese Camera Link采集卡 \~english Camera Link interface +MV_CXP_INTERFACE = 0x00000008 # < \~chinese CoaXPress采集卡 \~english CoaXPress interface +MV_XOF_INTERFACE = 0x00000010 # < \~chinese XoFLink采集卡 \~english XoFLink interface + +INFO_MAX_BUFFER_SIZE = 64 # < \~chinese 最大的数据信息大小 \~english Maximum data information size + +MV_MAX_TLS_NUM = 8 # < \~chinese 最多支持的传输层实例个数 \~english The maximum number of supported transport layer instances +MV_MAX_DEVICE_NUM = 256 # < \~chinese 最大支持的设备个数 \~english The maximum number of supported devices + +MV_MAX_INTERFACE_NUM = 64 #< \~chinese 最大支持的采集卡数量 \~english The maximum number of Frame Grabber interface supported + +MV_MAX_SERIAL_PORT_NUM = 64 # \~chinese 最大支持的串口数量 \~english The maximum number of serial port supported + +MV_MAX_GENTL_IF_NUM = 256 # < \~chinese 最大支持的GenTL数量 \~english The maximum number of GenTL supported +MV_MAX_GENTL_DEV_NUM = 256 # < \~chinese 最大支持的GenTL设备数量 \~english The maximum number of GenTL devices supported + +# \~chinese 设备的访问模式 \~english Device Access Mode +# \~chinese 独占权限,其他APP只允许读CCP寄存器 \~english Exclusive authority, other APP is only allowed to read the CCP register +MV_ACCESS_Exclusive = 1 +# \~chinese 可以从5模式下抢占权限,然后以独占权限打开 \~english You can seize the authority from the 5 mode, and then open with exclusive authority +MV_ACCESS_ExclusiveWithSwitch = 2 +# \~chinese 控制权限,其他APP允许读所有寄存器 \~english Control authority, allows other APP reading all registers +MV_ACCESS_Control = 3 +# \~chinese 可以从5的模式下抢占权限,然后以控制权限打开 \~english You can seize the authority from the 5 mode, and then open with control authority +MV_ACCESS_ControlWithSwitch = 4 +# \~chinese 以可被抢占的控制权限打开 \~english Open with seized control authority +MV_ACCESS_ControlSwitchEnable = 5 +# \~chinese 可以从5的模式下抢占权限,然后以可被抢占的控制权限打开 \~english You can seize the authority from the 5 mode, and then open with seized control authority +MV_ACCESS_ControlSwitchEnableWithKey = 6 +# \~chinese 读模式打开设备,适用于控制权限下 \~english Open with read mode and is available under control authority +MV_ACCESS_Monitor = 7 + +MV_MATCH_TYPE_NET_DETECT = 0x00000001 # < \~chinese 网络流量和丢包信息 \~english Network traffic and packet loss information +MV_MATCH_TYPE_USB_DETECT = 0x00000002 # < \~chinese host接收到来自U3V设备的字节总数 \~english The total number of bytes host received from U3V device + +# \~chinese GigEVision IP配置 \~english GigEVision IP Configuration +MV_IP_CFG_STATIC = 0x05000000 # < \~chinese 静态 \~english Static +MV_IP_CFG_DHCP = 0x06000000 # < \~chinese DHCP \~english DHCP +MV_IP_CFG_LLA = 0x04000000 # < \~chinese LLA \~english LLA + +# \~chinese GigEVision网络传输模式 \~english GigEVision Net Transfer Mode +MV_NET_TRANS_DRIVER = 0x00000001 # < \~chinese 驱动 \~english Driver +MV_NET_TRANS_SOCKET = 0x00000002 # < \~chinese Socket \~english Socket + +# \~chinese CameraLink波特率 \~english CameraLink Baud Rates (CLUINT32) +MV_CAML_BAUDRATE_9600 = 0x00000001 # < \~chinese 9600 \~english 9600 +MV_CAML_BAUDRATE_19200 = 0x00000002 # < \~chinese 19200 \~english 19200 +MV_CAML_BAUDRATE_38400 = 0x00000004 # < \~chinese 38400 \~english 38400 +MV_CAML_BAUDRATE_57600 = 0x00000008 # < \~chinese 57600 \~english 57600 +MV_CAML_BAUDRATE_115200 = 0x00000010 # < \~chinese 115200 \~english 115200 +MV_CAML_BAUDRATE_230400 = 0x00000020 # < \~chinese 230400 \~english 230400 +MV_CAML_BAUDRATE_460800 = 0x00000040 # < \~chinese 460800 \~english 460800 +MV_CAML_BAUDRATE_921600 = 0x00000080 # < \~chinese 921600 \~english 921600 +MV_CAML_BAUDRATE_AUTOMAX = 0x40000000 # < \~chinese 最大值 \~english Auto Max + +# \~chinese 异常消息类型 \~english Exception message type +MV_EXCEPTION_DEV_DISCONNECT = 0x00008001 # < \~chinese 设备断开连接 \~english The device is disconnected +MV_EXCEPTION_VERSION_CHECK = 0x00008002 # < \~chinese SDK与驱动版本不匹配 \~english SDK does not match the driver version + +MAX_EVENT_NAME_SIZE = 128 # < \~chinese 设备Event事件名称最大长度 \~english Max length of event name +MV_MAX_XML_SYMBOLIC_NUM = 64 # \~chinese 最大XML符号数 \~english Max XML Symbolic Number +MV_MAX_SYMBOLIC_LEN = 64 # \~chinese 最大枚举条目对应的符号长度 \~english Max Enum Entry Symbolic Number + +MV_MAX_SPLIT_NUM = 8 # \~chinese 分时曝光时最多将源图像拆分的个数 \~english The maximum number of source image to be split in time-division exposure diff --git a/camera/CameraParams_header.py b/camera/CameraParams_header.py new file mode 100644 index 0000000..c070b5a --- /dev/null +++ b/camera/CameraParams_header.py @@ -0,0 +1,1289 @@ +# -*- coding: utf-8 -*- +# generated by 'xml2py' +# flags '-c -d -v C:\test_h\CameraParams.xml -o CameraParams_header.py' +from ctypes import * +from CameraParams_const import * +from PixelType_header import * + +STRING = c_char_p + +MV_PointCloudFile_Undefined = 0 # < \~chinese 未定义的点云格式 \~english Undefined point cloud format +MV_ACQ_MODE_CONTINUOUS = 2 # < \~chinese 持续采集模式 \~english Continuous Mode +MV_ACQ_MODE_MUTLI = 1 # < \~chinese 多帧模式 \~english Multi Mode +MV_TRIGGER_MODE_ON = 1 # < \~chinese 打开 \~english On +AM_CycleDetect = 6 # < \~chinese 内部用于AccessMode循环检测 \~english used internally for AccessMode cycle detection +AM_Undefined = 5 # < \~chinese 对象未被初始化 \~english Object is not yet initialized +AM_RW = 4 # < \~chinese 读和写 \~english Read and Write +AM_RO = 3 # < \~chinese 只读 \~english Read Only +AM_WO = 2 # < \~chinese 只写 \~english Write Only +AM_NA = 1 # < \~chinese 不可用 \~english Not available +AM_NI = 0 # < \~chinese 没有实现 \~english Not implemented +MV_Image_Tif = 4 # < \~chinese Tif格式 \~english Tif image file +MV_Image_Png = 3 # < \~chinese Png格式 \~english Png image file +MV_Image_Jpeg = 2 # < \~chinese Jpeg格式 \~english Jpeg image file +MV_Image_Bmp = 1 # < \~chinese Bmp格式 \~english Bmp image file +MV_GAIN_MODE_CONTINUOUS = 2 # < \~chinese 连续 \~english Gain Mode Continuous +MV_GAIN_MODE_ONCE = 1 # < \~chinese 单次 \~english Gain Mode Once +MV_GrabStrategy_UpcomingImage = 3 # < \~chinese 等待下一帧图像 \~english Wait for the next image +MV_GrabStrategy_LatestImages = 2 # < \~chinese 获取列表中最新的图像 \~english Gets the latest image in the list +MV_GrabStrategy_LatestImagesOnly = 1 # < \~chinese 获取列表中最新的一帧图像(同时清除列表中的其余图像) \~english Gets the most recent image in the list (while clearing the rest of the images in the list) +MV_PointCloudFile_OBJ = 3 # < \~chinese OBJ点云格式 \~english The point cloud format named OBJ +MV_PointCloudFile_CSV = 2 # < \~chinese CSV点云格式 \~english The point cloud format named CSV +MV_PointCloudFile_PLY = 1 # < \~chinese PLY点云格式 \~english The point cloud format named PLY +MV_ACQ_MODE_SINGLE = 0 # < \~chinese 单帧模式 \~english Single Mode +MV_TRIGGER_MODE_OFF = 0 # < \~chinese 关闭 \~english Off +MV_TRIGGER_SOURCE_SOFTWARE = 7 # < \~chinese 软触发 \~english Trigger source software +MV_EXPOSURE_MODE_TIMED = 0 # < \~chinese 曝光超时模式 \~english exposure mode timed +MV_FormatType_Undefined = 0 # < \~chinese 未定义的格式类型 \~english Undefined format type +MV_GAIN_MODE_OFF = 0 # < \~chinese 关闭增益模式 \~english Gain mode off +MV_EXPOSURE_AUTO_MODE_CONTINUOUS = 2 # < \~chinese 自动连续曝光模式 \~english Exposure auto mode continuous +MV_EXPOSURE_AUTO_MODE_ONCE = 1 # < \~chinese 单次自动曝光模式 \~english Exposure auto mode once +MV_EXPOSURE_AUTO_MODE_OFF = 0 # < \~chinese 关闭自动曝光模式 \~english Exposure auto mode off +IFT_IValue = 0 # < \~chinese IValue接口类型 \~english IValue interface +MV_GrabStrategy_OneByOne = 0 # < \~chinese 从旧到新一帧一帧的获取图像 \~english Frame by frame from old to new +MV_FormatType_AVI = 1 # < \~chinese AVI视频格式 \~english AVI format type +MV_GAMMA_SELECTOR_USER = 1 # < \~chinese gamma选择项User \~english This enumeration selects the type of gamma to apply +IFT_IString = 6 # < \~chinese IString接口类型 \~english IString interface +MV_BALANCEWHITE_AUTO_OFF = 0 # < \~chinese 白平衡自动关闭 \~english Balance white auto off +MV_GAMMA_SELECTOR_SRGB = 2 # < \~chinese gamma选择项SRGB \~english This enumeration selects the type of gamma to apply +IFT_IPort = 11 # < \~chinese IPort接口类型 \~english IPort interface +MV_BALANCEWHITE_AUTO_CONTINUOUS = 1 # < \~chinese 白平衡自动连续 \~english Balance white auto continuous +IFT_IEnumEntry = 10 # < \~chinese IEnumEntry接口类型 \~english IEnumEntry interface +IFT_ICategory = 8 # < \~chinese ICategory接口类型 \~english ICategory interface +IFT_IRegister = 7 # < \~chinese IRegister接口类型 \~english IRegister interface +MV_Image_Undefined = 0 # < \~chinese 未定义的图像类型 \~english Image undefined +IFT_IFloat = 5 # < \~chinese IFloat接口类型 \~english IFloat interface +IFT_IEnumeration = 9 # < \~chinese IEnumeration接口类型 \~english IEnumeration interface +IFT_ICommand = 4 # < \~chinese ICommand接口类型 \~english ICommand interface +IFT_IBoolean = 3 # < \~chinese IBoolean接口类型 \~english IBoolean interface +IFT_IInteger = 2 # < \~chinese IInteger接口类型 \~english IInteger interface +MV_GIGE_TRANSTYPE_MULTICAST_WITHOUT_RECV = 65537 # < \~chinese 表示组播模式,但本实例不接收图像数据 \~english Multicast without receive data +IFT_IBase = 1 # < \~chinese IBase接口类型 \~english IBase interface +MV_GIGE_TRANSTYPE_UNICAST_WITHOUT_RECV = 65536 # < \~chinese 表示设置了单播,但本实例不接收图像数据 \~english Unicast without receive data +MV_BALANCEWHITE_AUTO_ONCE = 2 # < \~chinese 单次自动白平衡 \~english Balance white auto once +MV_GIGE_TRANSTYPE_LIMITEDBROADCAST = 2 # < \~chinese 表示局域网内广播,暂不支持 \~english Limited broadcast mode,not support +MV_GIGE_TRANSTYPE_MULTICAST = 1 # < \~chinese 表示组播 \~english Multicast mode +MV_GIGE_TRANSTYPE_UNICAST = 0 # < \~chinese 表示单播(默认) \~english Unicast mode(default) +MV_GIGE_TRANSTYPE_CAMERADEFINED = 4 # < \~chinese 表示从相机获取,暂不支持 \~english Transtype from camera,not support +MV_GIGE_TRANSTYPE_SUBNETBROADCAST = 3 # < \~chinese 表示子网内广播,暂不支持 \~english Subnet broadcast mode,not support +MV_EXPOSURE_MODE_TRIGGER_WIDTH = 1 # < \~chinese 曝光模式触发宽 \~english Trigger width +MV_GIGE_TRANSTYPE_UNICAST_DEFINED_PORT = 5 # < \~chinese 表示用户自定义应用端接收图像数据Port号 \~english User Defined Receive Data Port +MV_TRIGGER_SOURCE_FrequencyConverter = 8 # < \~chinese 触发源变频器 \~english Trigger source frequency converter +MV_TRIGGER_SOURCE_COUNTER0 = 4 # < \~chinese 触发源计数器 \~english Trigger source conuter +MV_TRIGGER_SOURCE_LINE3 = 3 # < \~chinese LINE3 触发源 \~english Trigger source line3 +MV_TRIGGER_SOURCE_LINE2 = 2 # < \~chinese LINE2 触发源 \~english Trigger source line2 +MV_TRIGGER_SOURCE_LINE1 = 1 # < \~chinese LINE1 触发源 \~english Trigger source line1 +MV_TRIGGER_SOURCE_LINE0 = 0 # < \~chinese LINE0 触发源 \~english Trigger source line0 +SortMethod_SerialNumber = 0 # < \~chinese 按序列号排序 \~english Sorting by SerialNumber +SortMethod_UserID = 1 # < \~chinese 按用户自定义名字排序 \~english Sorting by UserID +SortMethod_CurrentIP_ASC = 2 # < \~chinese 按当前IP地址排序(升序) \~english Sorting by current IP(Ascending) +SortMethod_CurrentIP_DESC = 3 # < \~chinese 按当前IP地址排序(降序) \~english Sorting by current IP(Descending) +MV_IMAGE_ROTATE_90 = 1 # < \~chinese 旋转90度 \~english Rotate 90 degrees +MV_IMAGE_ROTATE_180 = 2 # < \~chinese 旋转180度 \~english Rotate 180 degrees +MV_IMAGE_ROTATE_270 = 3 # < \~chinese 旋转270度 \~english Rotate 270 degrees +MV_FLIP_VERTICAL = 1 # < \~chinese 垂直翻转 \~english flip vertical +MV_FLIP_HORIZONTAL = 2 # < \~chinese 水平翻转 \~english flip horizontal +MV_CC_GAMMA_TYPE_NONE = 0 # < \~chinese 不启用 \~english Disable +MV_CC_GAMMA_TYPE_VALUE = 1 # < \~chinese Gamma值 \~english Gamma value +MV_CC_GAMMA_TYPE_USER_CURVE = 2 # < \~chinese Gamma曲线 \~english Gamma curve +MV_CC_GAMMA_TYPE_LRGB2SRGB = 3 # < \~chinese linear RGB to sRGB \~english linear RGB to sRGB +MV_CC_GAMMA_TYPE_SRGB2LRGB = 4 # < \~chinese sRGB to linear RGB(仅色彩插值时支持,色彩校正时无效) \~english sRGB to linear RGB +MV_CC_STREAM_EXCEPTION_ABNORMAL_IMAGE = 0x4001 # < \~chinese 异常的图像,该帧被丢弃 \~english abnormal image,the frame is discarded +MV_CC_STREAM_EXCEPTION_LIST_OVERFLOW = 0x4002 # < \~chinese 缓存列表溢出,清除最旧的一帧 \~english Cache list overflow, clear the oldest frame +MV_CC_STREAM_EXCEPTION_LIST_EMPTY = 0x4003 # < \~chinese 缓存列表为空,该帧被丢弃 \~english Cache list is empty,the frame is discarded +MV_CC_STREAM_EXCEPTION_RECONNECTION = 0x4004 # < \~chinese 断流恢复 \~english reconnect +MV_CC_STREAM_EXCEPTION_DISCONNECTED = 0x4005 # < \~chinese 断流,恢复失败,取流被中止 \~english reconnect fail, stream is terminated +MV_CC_STREAM_EXCEPTION_DEVICE = 0x4006 # < \~chinese 设备异常,取流被中止 \~english device exception +MV_SPLIT_BY_LINE = 1 #< \~chinese 源图像按行拆分成多张图像 \~english Source image split into multiple images by line + +int8_t = c_int8 +int16_t = c_int16 +int32_t = c_int32 +int64_t = c_int64 +uint8_t = c_uint8 +uint16_t = c_uint16 +uint32_t = c_uint32 +uint64_t = c_uint64 +int_least8_t = c_byte +int_least16_t = c_short +int_least32_t = c_int +int_least64_t = c_long +uint_least8_t = c_ubyte +uint_least16_t = c_ushort +uint_least32_t = c_uint +uint_least64_t = c_ulong +int_fast8_t = c_byte +int_fast16_t = c_long +int_fast32_t = c_long +int_fast64_t = c_long +uint_fast8_t = c_ubyte +uint_fast16_t = c_ulong +uint_fast32_t = c_ulong +uint_fast64_t = c_ulong +intptr_t = c_long +uintptr_t = c_ulong +intmax_t = c_long +uintmax_t = c_ulong + +# GigE设备信息 \~english GigE device info +class _MV_GIGE_DEVICE_INFO_(Structure): + pass +_MV_GIGE_DEVICE_INFO_._fields_ = [ + ('nIpCfgOption', c_uint), # < \~chinese IP配置选项 \~english Ip config option + ('nIpCfgCurrent', c_uint), # < \~chinese 当前IP地址配置 \~english IP configuration:bit31-static bit30-dhcp bit29-lla + ('nCurrentIp', c_uint), # < \~chinese 当前主机IP地址 \~english Current host Ip + ('nCurrentSubNetMask', c_uint), # < \~chinese 当前子网掩码 \~english curtent subnet mask + ('nDefultGateWay', c_uint), # < \~chinese 默认网关 \~english Default gate way + ('chManufacturerName', c_ubyte * 32), # < \~chinese 厂商名称 \~english Manufacturer Name + ('chModelName', c_ubyte * 32), # < \~chinese 型号名称 \~english Mode name + ('chDeviceVersion', c_ubyte * 32), # < \~chinese 设备固件版本 \~english Device Version + ('chManufacturerSpecificInfo', c_ubyte * 48), # < \~chinese 厂商特殊信息 \~english Manufacturer Specific Infomation + ('chSerialNumber', c_ubyte * 16), # < \~chinese 序列号 \~english serial number + ('chUserDefinedName', c_ubyte * 16), # < \~chinese 用户定义名称 \~english User Defined Name + ('nNetExport', c_uint), # < \~chinese 网口Ip地址 \~english NetWork Ip address + ('nReserved', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_GIGE_DEVICE_INFO = _MV_GIGE_DEVICE_INFO_ + +# USB设备信息 \~english USB device info +class _MV_USB3_DEVICE_INFO_(Structure): + pass +_MV_USB3_DEVICE_INFO_._fields_ = [ + ('CrtlInEndPoint', c_ubyte), # < \~chinese 控制输入端点 \~english Control input endpoint + ('CrtlOutEndPoint', c_ubyte), # < \~chinese 控制输出端点 \~english Control output endpoint + ('StreamEndPoint', c_ubyte), # < \~chinese 流端点 \~english Flow endpoint + ('EventEndPoint', c_ubyte), # < \~chinese 事件端点 \~english Event endpoint + ('idVendor', c_ushort), # < \~chinese 供应商ID号 \~english Vendor ID Number + ('idProduct', c_ushort), # < \~chinese 产品ID号 \~english Device ID Number + ('nDeviceNumber', c_uint), # < \~chinese 设备序列号 \~english Device Serial Number + ('chDeviceGUID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 设备GUID号 \~english Device GUID Number + ('chVendorName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 供应商名字 \~english Vendor Name + ('chModelName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 型号名字 \~english Model Name + ('chFamilyName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 家族名字 \~english Family Name + ('chDeviceVersion', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 设备版本号 \~english Device Version + ('chManufacturerName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 制造商名字 \~english Manufacturer Name + ('chSerialNumber', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 序列号 \~english Serial Number + ('chUserDefinedName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 用户自定义名字 \~english User Defined Name + ('nbcdUSB', c_uint), # < \~chinese 支持的USB协议 \~english Support USB Protocol + ('nDeviceAddress', c_uint), # < \~chinese 设备地址 \~english Device Address + ('nReserved', c_uint * 2), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_USB3_DEVICE_INFO = _MV_USB3_DEVICE_INFO_ + +# CameraLink设备信息 \~english CameraLink device info +class _MV_CamL_DEV_INFO_(Structure): + pass +_MV_CamL_DEV_INFO_._fields_ = [ + ('chPortID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 端口号 \~english Port ID + ('chModelName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 设备型号 \~english Model name + ('chFamilyName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 家族名字 \~english Family Name + ('chDeviceVersion', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 设备版本号 \~english Device Version + ('chManufacturerName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 制造商名字 \~english Manufacturer Name + ('chSerialNumber', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 序列号 \~english Serial Number + ('nReserved', c_uint * 38), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CamL_DEV_INFO = _MV_CamL_DEV_INFO_ + +# 采集卡Camera Link相机信息 \~english Camera Link device information on frame grabber +class _MV_CML_DEVICE_INFO_(Structure): + pass +_MV_CML_DEVICE_INFO_._fields_ = [ + ('chInterfaceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 采集卡ID \~english Interface ID of Frame Grabber + ('chVendorName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 供应商名字 \~english Vendor name + ('chModelName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 型号名字 \~english Model name + ('chManufacturerInfo', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 厂商信息 \~english Manufacturer information + ('chDeviceVersion', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 相机版本 \~english Device version + ('chSerialNumber', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 序列号 \~english Serial Number + ('chUserDefinedName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 用户自定义名字 \~english User defined name + ('chDeviceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 相机ID \~english Device ID + ('nReserved', c_uint * 7), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CML_DEVICE_INFO = _MV_CML_DEVICE_INFO_ + +# CoaXPress相机信息 \~english CoaXPress device information +class _MV_CXP_DEVICE_INFO_(Structure): + pass +_MV_CXP_DEVICE_INFO_._fields_ = [ + ('chInterfaceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 采集卡ID \~english Interface ID of Frame Grabber + ('chVendorName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 供应商名字 \~english Vendor name + ('chModelName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 型号名字 \~english Model name + ('chManufacturerInfo', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 厂商信息 \~english Manufacturer information + ('chDeviceVersion', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 相机版本 \~english Device version + ('chSerialNumber', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 序列号 \~english Serial Number + ('chUserDefinedName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 用户自定义名字 \~english User defined name + ('chDeviceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 相机ID \~english Device ID + ('nReserved', c_uint * 7), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CXP_DEVICE_INFO = _MV_CXP_DEVICE_INFO_ + +# XoFLink相机信息 \~english XoFLink device information +class _MV_XOF_DEVICE_INFO_(Structure): + pass +_MV_XOF_DEVICE_INFO_._fields_ = [ + ('chInterfaceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 采集卡ID \~english Interface ID of Frame Grabber + ('chVendorName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 供应商名字 \~english Vendor name + ('chModelName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 型号名字 \~english Model name + ('chManufacturerInfo', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 厂商信息 \~english Manufacturer information + ('chDeviceVersion', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 相机版本 \~english Device version + ('chSerialNumber', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 序列号 \~english Serial Number + ('chUserDefinedName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 用户自定义名字 \~english User defined name + ('chDeviceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 相机ID \~english Device ID + ('nReserved', c_uint * 7), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_XOF_DEVICE_INFO = _MV_XOF_DEVICE_INFO_ + +# CameraParams.h 80 +class _MV_CC_DEVICE_INFO_(Structure): + pass +# 设备信息 \~english Device info +class N19_MV_CC_DEVICE_INFO_3DOT_0E(Union): + pass +N19_MV_CC_DEVICE_INFO_3DOT_0E._fields_ = [ + ('stGigEInfo', MV_GIGE_DEVICE_INFO), # < \~chinese Gige设备信息 \~english Gige device infomation + ('stUsb3VInfo', MV_USB3_DEVICE_INFO), # < \~chinese U3V设备信息 \~english u3V device information + ('stCamLInfo', MV_CamL_DEV_INFO), # < \~chinese CamLink设备信息 \~english CamLink device information + ('stCMLInfo', MV_CML_DEVICE_INFO), # < \~chinese 采集卡CameraLink设备信息 \~english CameraLink Device Info On Frame Grabber + ('stCXPInfo', MV_CXP_DEVICE_INFO), # < \~chinese 采集卡CoaXPress设备信息 \~english CoaXPress Device Info On Frame Grabber + ('stXoFInfo', MV_XOF_DEVICE_INFO), # < \~chinese 采集卡XoF设备信息 \~english XoF Device Info On Frame Grabber +] + +_MV_CC_DEVICE_INFO_._fields_ = [ + ('nMajorVer', c_ushort), # < \~chinese 规范的主要版本 \~english Major version of the specification. + ('nMinorVer', c_ushort), # < \~chinese 规范的次要版本 \~english Minor version of the specification + ('nMacAddrHigh', c_uint), # < \~chinese MAC地址高位 \~english Mac address high + ('nMacAddrLow', c_uint), # < \~chinese MAC地址低位 \~english Mac address low + ('nTLayerType', c_uint), # < \~chinese 设备传输层协议类型 \~english Device Transport Layer Protocol Type, e.g. MV_GIGE_DEVICE + ('nDevTypeInfo', c_uint), # < \~chinese 设备类型信息 \~english Device Type Info + ('nReserved', c_uint * 3), # < \~chinese 保留字节 \~english Reserved bytes + ('SpecialInfo', N19_MV_CC_DEVICE_INFO_3DOT_0E), # < \~chinese 不同设备特有信息 \~english Special information +] +MV_CC_DEVICE_INFO = _MV_CC_DEVICE_INFO_ + +# 设备信息列表 \~english Device Information List +class _MV_CC_DEVICE_INFO_LIST_(Structure): + pass +_MV_CC_DEVICE_INFO_LIST_._fields_ = [ + ('nDeviceNum', c_uint), # < \~chinese 在线设备数量 \~english Online Device Number + ('pDeviceInfo', POINTER(MV_CC_DEVICE_INFO) * MV_MAX_DEVICE_NUM), # < \~chinese 支持最多256个设备 \~english Support up to 256 devices +] +MV_CC_DEVICE_INFO_LIST = _MV_CC_DEVICE_INFO_LIST_ + +# 通过GenTL枚举到的Interface信息 \~english Interface Information with GenTL +class _MV_GENTL_IF_INFO_(Structure): + pass +_MV_GENTL_IF_INFO_._fields_ = [ + ('chInterfaceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese GenTL接口ID \~english Interface ID of GenTL + ('chTLType', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 传输层类型 \~english Transport Layer type + ('chDisplayName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 设备显示名称 \~english Display name + ('nCtiIndex', c_uint), # < \~chinese GenTL的cti文件索引 \~english Cti file index of GenTL + ('nReserved', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_GENTL_IF_INFO = _MV_GENTL_IF_INFO_ + +# 通过GenTL枚举到的设备信息列表 \~english Device Information List with GenTL +class _MV_GENTL_IF_INFO_LIST_(Structure): + pass +_MV_GENTL_IF_INFO_LIST_._fields_ = [ + ('nInterfaceNum', c_uint), # < \~chinese 在线设备数量 \~english Online Device Number + ('pIFInfo', POINTER(MV_GENTL_IF_INFO) * MV_MAX_GENTL_IF_NUM), # < \~chinese 支持最多256个设备 \~english Support up to 256 devices +] +MV_GENTL_IF_INFO_LIST = _MV_GENTL_IF_INFO_LIST_ + +# 通过GenTL枚举到的设备信息 \~english Device Information with GenTL +class _MV_GENTL_DEV_INFO_(Structure): + pass +_MV_GENTL_DEV_INFO_._fields_ = [ + ('chInterfaceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese GenTL接口ID \~english Interface ID of GenTL + ('chDeviceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 设备ID \~english Device ID + ('chVendorName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 供应商名字 \~english Vendor Name + ('chModelName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 型号名字 \~english Model name + ('chTLType', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 传输层类型 \~english Transport Layer type + ('chDisplayName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 显示名称 \~english Display name + ('chUserDefinedName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 用户自定义名字 \~english User defined name + ('chSerialNumber', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 序列号 \~english Serial number + ('chDeviceVersion', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 设备版本号 \~english Device version + ('nCtiIndex', c_uint), # < \~chinese cti索引 \~english Cti Index + ('nReserved', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_GENTL_DEV_INFO = _MV_GENTL_DEV_INFO_ + +# 通过GenTL枚举到的设备信息列表 \~english Device Information List with GenTL +class _MV_GENTL_DEV_INFO_LIST_(Structure): + pass +_MV_GENTL_DEV_INFO_LIST_._fields_ = [ + ('nDeviceNum', c_uint), # < \~chinese 在线设备数量 \~english Online Device Number + ('pDeviceInfo', POINTER(MV_GENTL_DEV_INFO) * MV_MAX_GENTL_DEV_NUM), # < \~chinese GenTL设备信息 \~english device infomation of GenTL device +] +MV_GENTL_DEV_INFO_LIST = _MV_GENTL_DEV_INFO_LIST_ + +# Chunk内容 \~english The content of ChunkData +class _MV_CHUNK_DATA_CONTENT_(Structure): + pass +_MV_CHUNK_DATA_CONTENT_._fields_ = [ + ('pChunkData', POINTER(c_ubyte)), # < \~chinese 块数据 \~english Chunk data + ('nChunkID', c_uint), # < \~chinese 块数据ID \~english Chunk id + ('nChunkLen', c_uint), # < \~chinese 块数据长度 \~english Chunk len + ('nReserved', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CHUNK_DATA_CONTENT = _MV_CHUNK_DATA_CONTENT_ + +# 输出帧的信息 \~english Output Frame Information +class _MV_FRAME_OUT_INFO_EX_(Structure): + pass +# values for enumeration 'MvGvspPixelType' +MvGvspPixelType = c_int # enum + +class N22_MV_FRAME_OUT_INFO_EX_3DOT_1E(Union): + pass +N22_MV_FRAME_OUT_INFO_EX_3DOT_1E._fields_ = [ + ('pUnparsedChunkContent', POINTER(MV_CHUNK_DATA_CONTENT)), # < \~chinese Chunk内容 \~english Chunk Content + ('nAligning', int64_t), # < \~chinese 校准字段 \~english Aligning +] +_MV_FRAME_OUT_INFO_EX_._fields_ = [ + ('nWidth', c_ushort), + # < \~chinese 图像宽(最大65535,超出请用nExtendWidth) \~english Image Width (over 65535, use nExtendWidth) + ('nHeight', c_ushort), + # < \~chinese 图像高(最大65535,超出请用nExtendHeight) \~english Image Height(over 65535, use nExtendHeight) + ('enPixelType', MvGvspPixelType), # < \~chinese 像素格式 \~english Pixel Type + ('nFrameNum', c_uint), # < \~chinese 帧号 \~english Frame Number + ('nDevTimeStampHigh', c_uint), # < \~chinese 时间戳高32位 \~english Timestamp high 32 bits + ('nDevTimeStampLow', c_uint), # < \~chinese 时间戳低32位 \~english Timestamp low 32 bits + ('nReserved0', c_uint), # < \~chinese 保留,8字节对齐 \~english Reserved, 8-byte aligned + ('nHostTimeStamp', int64_t), # < \~chinese 主机生成的时间戳 \~english Host-generated timestamp + ('nFrameLen', c_uint), # < \~chinese 帧的长度 \~english Frame length + # < \~chinese 以下为chunk新增水印信息 \~english The followings are chunk add frame-specific information + # < \~chinese 设备水印时标 \~english Device frame-specific time scale + ('nSecondCount', c_uint), # < \~chinese 秒数 \~english The Seconds + ('nCycleCount', c_uint), # < \~chinese 周期数 \~english The Count of Cycle + ('nCycleOffset', c_uint), # < \~chinese 周期偏移量 \~english The Offset of Cycle + ('fGain', c_float), # < \~chinese 增益 \~english Gain + ('fExposureTime', c_float), # < \~chinese 曝光时间 \~english Exposure Time + ('nAverageBrightness', c_uint), # < \~chinese 平均亮度 \~english Average brightness + # < \~chinese:白平衡相关 \~english White balance + ('nRed', c_uint), # < \~chinese 红色 \~english Red + ('nGreen', c_uint), # < \~chinese 绿色 \~english Green + ('nBlue', c_uint), # < \~chinese 蓝色 \~english Blue + ('nFrameCounter', c_uint), # < \~chinese 帧计数 \~english Frame counter + ('nTriggerIndex', c_uint), # < \~chinese 触发计数 \~english Trigger index + # < \~chinese 输入/输出 \~english Line Input/Output + ('nInput', c_uint), # < \~chinese 输入 \~english input + ('nOutput', c_uint), # < \~chinese 输出 \~english output + # < \~chinese ROI区域 \~english ROI Region + ('nOffsetX', c_ushort), # < \~chinese 水平偏移量 \~english OffsetX + ('nOffsetY', c_ushort), # < \~chinese 垂直偏移量 \~english OffsetY + ('nChunkWidth', c_ushort), # < \~chinese chunk 宽 \~english The Width of Chunk + ('nChunkHeight', c_ushort), # < \~chinese chunk 高 \~english The Height of Chunk + ('nLostPacket', c_uint), # < \~chinese 本帧丢包数 \~english Lost Pacekt Number In This Frame + ('nUnparsedChunkNum', c_uint), # < \~chinese 未解析的Chunkdata个数 \~english Unparsed chunk number + ('UnparsedChunkList', N22_MV_FRAME_OUT_INFO_EX_3DOT_1E), # < \~chinese 数据库链表 \~english Unparsed chunk list + ('nExtendWidth', c_uint), # < \~chinese 图像宽(扩展变量) \~english Image Width + ('nExtendHeight', c_uint), # < \~chinese 图像高(扩展变量) \~english Image Height + ('nReserved', c_uint * 34), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_FRAME_OUT_INFO_EX = _MV_FRAME_OUT_INFO_EX_ + +# \~chinese 显示帧信息 \~english Display frame information +class _MV_DISPLAY_FRAME_INFO_EX_(Structure): + pass +_MV_DISPLAY_FRAME_INFO_EX_._fields_ = [ + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + ('enPixelType', MvGvspPixelType), # < \~chinese 像素格式 \~english Pixel Type + ('pImageBuf', POINTER(c_ubyte)), # < \~chinese 输入图像缓存 \~english Input image buffer + ('nImageBufLen', c_uint), # < \~chinese 输入图像长度 \~english Input image length + ('enRenderMode', c_uint), # < \~chinese 图像渲染方式 0-GDI(默认), 1-D3D, 2-OPENGL \~english Render mode 0-GDI(default), 1-D3D, 2-OPENGL + ('nRes', c_uint * 3), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_DISPLAY_FRAME_INFO_EX = _MV_DISPLAY_FRAME_INFO_EX_ + +# 图像结构体,输出图像指针地址及图像信息 \~english Image Struct, output the pointer of Image and the information of the specific image +class _MV_FRAME_OUT_(Structure): + pass +_MV_FRAME_OUT_._fields_ = [ + ('pBufAddr', POINTER(c_ubyte)), # < \~chinese 图像指针地址 \~english pointer of image + ('stFrameInfo', MV_FRAME_OUT_INFO_EX), # < \~chinese 图像信息 \~english information of the specific image + ('nRes', c_uint * 16), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_FRAME_OUT = _MV_FRAME_OUT_ + +# values for enumeration '_MV_GRAB_STRATEGY_' +_MV_GRAB_STRATEGY_ = c_int # enum +MV_GRAB_STRATEGY = _MV_GRAB_STRATEGY_ + +# 网络传输的相关信息 \~english Network transmission information +class _MV_NETTRANS_INFO_(Structure): + pass +_MV_NETTRANS_INFO_._fields_ = [ + ('nReceiveDataSize', int64_t), # < \~chinese 已接收数据大小 [统计StartGrabbing和StopGrabbing之间的数据量] \~english Received Data Size [Calculate the Data Size between StartGrabbing and StopGrabbing] + ('nThrowFrameCount', c_int), # < \~chinese 丢帧数量 \~english Throw frame number + ('nNetRecvFrameCount', c_uint), # < \~chinese 收到帧计数 \~english Receive Frame count + ('nRequestResendPacketCount', int64_t), # < \~chinese 请求重发包数 \~english Request Resend Packet Count + ('nResendPacketCount', int64_t), # < \~chinese 重发包数 \~english Resend Packet Count +] +MV_NETTRANS_INFO = _MV_NETTRANS_INFO_ + +# 全匹配的一种信息结构体 \~english A fully matched information structure +class _MV_ALL_MATCH_INFO_(Structure): + pass +_MV_ALL_MATCH_INFO_._fields_ = [ + ('nType', c_uint), # < \~chinese 需要输出的信息类型 \~english Information type need to output + ('pInfo', c_void_p), # < \~chinese 输出的信息缓存,由调用者分配 \~englishOutput information cache, which is allocated by the caller + ('nInfoSize', c_uint), # < \~chinese 信息缓存的大小 \~english Information cache size +] +MV_ALL_MATCH_INFO = _MV_ALL_MATCH_INFO_ + +# 网络流量和丢包信息反馈结构体,对应类型为 MV_MATCH_TYPE_NET_DETECT \~english Network traffic and packet loss feedback structure, the corresponding type is MV_MATCH_TYPE_NET_DETECT +class _MV_MATCH_INFO_NET_DETECT_(Structure): + pass +_MV_MATCH_INFO_NET_DETECT_._fields_ = [ + ('nReceiveDataSize', int64_t), # < \~chinese 已接收数据大小 \~english Received data size + ('nLostPacketCount', int64_t), # < \~chinese 丢失的包数量 \~english Number of packets lost + ('nLostFrameCount', c_uint), # < \~chinese 丢帧数量 \~english Number of frames lost + ('nNetRecvFrameCount', c_uint), # < \~chinese 收到帧计数 \~english Receive Frame count + ('nRequestResendPacketCount', int64_t), # < \~chinese 请求重发包数 \~english Request Resend Packet Count + ('nResendPacketCount', int64_t), # < \~chinese 重发包数 \~english Resend Packet Count +] +MV_MATCH_INFO_NET_DETECT = _MV_MATCH_INFO_NET_DETECT_ + +# \~chinese host收到从u3v设备端的总字节数,对应类型为 MV_MATCH_TYPE_USB_DETECT \~english The total number of bytes host received from the u3v device side, the corresponding type is MV_MATCH_TYPE_USB_DETECT +class _MV_MATCH_INFO_USB_DETECT_(Structure): + pass +_MV_MATCH_INFO_USB_DETECT_._fields_ = [ + ('nReceiveDataSize', int64_t), # < \~chinese 已接收数据大小 \~english Received data size + ('nReceivedFrameCount', c_uint), # < \~chinese 已收到的帧数 \~english Number of frames received + ('nErrorFrameCount', c_uint), # < \~chinese 错误帧数 \~english Number of error frames + ('nReserved', c_uint * 2), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_MATCH_INFO_USB_DETECT = _MV_MATCH_INFO_USB_DETECT_ + +# \~chinese 显示帧信息 \~english Display frame information +class _MV_DISPLAY_FRAME_INFO_(Structure): + pass +_MV_DISPLAY_FRAME_INFO_._fields_ = [ + ('hWnd', c_void_p), # < \~chinese 窗口句柄 \~english Windows handle + ('pData', POINTER(c_ubyte)), # < \~chinese 显示的数据 \~english Data Buffer + ('nDataLen', c_uint), # < \~chinese 数据长度 \~english Data Size + ('nWidth', c_ushort), # < \~chinese 图像宽 \~english Width + ('nHeight', c_ushort), # < \~chinese 图像高 \~english Height + ('enPixelType', MvGvspPixelType), # < \~chinese 像素格式 \~english Pixel format + ('enRenderMode', c_uint), # < \~chinese 图像渲染方式 0-GDI(默认), 1-D3D, 2-OPENGL \~english Render mode 0-GDI(default), 1-D3D, 2-OPENGL + ('nRes', c_uint * 3), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_DISPLAY_FRAME_INFO = _MV_DISPLAY_FRAME_INFO_ + +# values for enumeration 'MV_SAVE_POINT_CLOUD_FILE_TYPE' +MV_SAVE_POINT_CLOUD_FILE_TYPE = c_int # enum + +# \~chinese 保存3D数据到缓存 \~english Save 3D data to buffer +class _MV_SAVE_POINT_CLOUD_PARAM_(Structure): + pass +_MV_SAVE_POINT_CLOUD_PARAM_._fields_ = [ + ('nLinePntNum', c_uint), # < \~chinese 每一行点的数量,即图像宽 \~english The number of points in each row,which is the width of the image + ('nLineNum', c_uint), # < \~chinese 行数,即图像高 \~english The number of rows,which is the height of the image + ('enSrcPixelType', MvGvspPixelType), # < \~chinese 输入数据的像素格式 \~english The pixel format of the input data + ('pSrcData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input data buffer + ('nSrcDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input data size + ('pDstBuf', POINTER(c_ubyte)), # < \~chinese 输出像素数据缓存 \~english Output pixel data buffer + ('nDstBufSize', c_uint), # < \~chinese 提供的输出缓冲区大小(nLinePntNum * nLineNum * (16*3 + 4) + 2048) \~english Output buffer size provided (nLinePntNum * nLineNum * (16*3 + 4) + 2048) + ('nDstBufLen', c_uint), # < \~chinese 输出像素数据缓存长度 \~english Output pixel data buffer size + ('enPointCloudFileType', MV_SAVE_POINT_CLOUD_FILE_TYPE), # < \~chinese 提供输出的点云文件类型 \~english Output point data file type provided + ('nReserved', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_SAVE_POINT_CLOUD_PARAM = _MV_SAVE_POINT_CLOUD_PARAM_ + +# values for enumeration 'MV_SAVE_IAMGE_TYPE' +MV_SAVE_IAMGE_TYPE = c_int # enum + +# \~chinese 图片保存参数 \~english Save Image Parameters +class _MV_SAVE_IMAGE_PARAM_T_EX_(Structure): + pass +_MV_SAVE_IMAGE_PARAM_T_EX_._fields_ = [ + ('pData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input Data Buffer + ('nDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input Data Size + ('enPixelType', MvGvspPixelType), # < \~chinese 输入数据的像素格式 \~english Input Data Pixel Format + ('nWidth', c_ushort), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_ushort), # < \~chinese 图像高 \~english Image Height + ('pImageBuffer', POINTER(c_ubyte)), # < \~chinese 输出图片缓存 \~english Output Image Buffer + ('nImageLen', c_uint), # < \~chinese 输出图片大小 \~english Output Image Size + ('nBufferSize', c_uint), # < \~chinese 提供的输出缓冲区大小 \~english Output buffer size provided + ('enImageType', MV_SAVE_IAMGE_TYPE), # < \~chinese 输出图片格式 \~english Output Image Format + ('nJpgQuality', c_uint), # < \~chinese 编码质量, (50-99] \~english Encoding quality, (50-99] + # < \~chinese ch:Bayer格式转为RGB24的插值方法 0-快速 1-均衡 2-最优 3-最优+ + # < \~english en:Interpolation method of convert Bayer to RGB24 0-Fast 1-Equilibrium 2-Optimal 3-Optimal plus + ('iMethodValue', c_uint), + ('nReserved', c_uint * 3), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_SAVE_IMAGE_PARAM_EX = _MV_SAVE_IMAGE_PARAM_T_EX_ + +class _MV_SAVE_IMAGE_PARAM_EX3_(Structure): + pass +_MV_SAVE_IMAGE_PARAM_EX3_._fields_ = [ + ('pData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input Data Buffer + ('nDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input Data Size + ('enPixelType', MvGvspPixelType), # < \~chinese 输入数据的像素格式 \~english Input Data Pixel Format + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + ('pImageBuffer', POINTER(c_ubyte)), # < \~chinese 输出图片缓存 \~english Output Image Buffer + ('nImageLen', c_uint), # < \~chinese 输出图片大小 \~english Output Image Size + ('nBufferSize', c_uint), # < \~chinese 提供的输出缓冲区大小 \~english Output buffer size provided + ('enImageType', MV_SAVE_IAMGE_TYPE), # < \~chinese 输出图片格式 \~english Output Image Format + ('nJpgQuality', c_uint), # < \~chinese 编码质量, (50-99] \~english Encoding quality, (50-99] + # < \~chinese ch:Bayer格式转为RGB24的插值方法 0-快速 1-均衡 2-最优 3-最优+ + # < \~english en:Interpolation method of convert Bayer to RGB24 0-Fast 1-Equilibrium 2-Optimal 3-Optimal plus + ('iMethodValue', c_uint), + ('nReserved', c_uint * 3), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_SAVE_IMAGE_PARAM_EX3 = _MV_SAVE_IMAGE_PARAM_EX3_ + +# \~chinese 保存BMP、JPEG、PNG、TIFF图片文件的参数 \~english Save BMP、JPEG、PNG、TIFF image file parameters +class _MV_SAVE_IMG_TO_FILE_PARAM_(Structure): + pass +_MV_SAVE_IMG_TO_FILE_PARAM_._fields_ = [ + ('enPixelType', MvGvspPixelType), # < \~chinese 输入数据的像素格式 \~english The pixel format of the input data + ('pData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input Data Buffer + ('nDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input Data Size + ('nWidth', c_ushort), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_ushort), # < \~chinese 图像高 \~english Image Height + ('enImageType', MV_SAVE_IAMGE_TYPE), # < \~chinese 输入图片格式 \~english Input Image Format + ('nQuality', c_uint), # < \~chinese JPG编码质量(50-99] \~english JPG Encoding quality(50-99] + ('pImagePath', c_char * 256), # < \~chinese 输入文件路径 \~english Input file path + # < \~chinese ch:Bayer格式转为RGB24的插值方法 0-快速 1-均衡 2-最优 3-最优+ + # < \~english en:Interpolation method of convert Bayer to RGB24 0-Fast 1-Equilibrium 2-Optimal 3-Optimal plus + ('iMethodValue', c_int), + ('nReserved', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_SAVE_IMG_TO_FILE_PARAM = _MV_SAVE_IMG_TO_FILE_PARAM_ + +class _MV_SAVE_IMAGE_TO_FILE_PARAM_EX_(Structure): + pass +_MV_SAVE_IMAGE_TO_FILE_PARAM_EX_._fields_ = [ + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + # < \~chinese 输入数据的像素格式 \~english The pixel format of the input data + ('enPixelType', MvGvspPixelType), + ('pData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input Data Buffer + ('nDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input Data Size + # < \~chinese 输入图片格式 \~english Input Image Format + ('enImageType', MV_SAVE_IAMGE_TYPE), + ('pcImagePath', POINTER(c_char)), # < \~chinese 输入文件路径 \~english Input file path + ('nQuality', c_uint), # < \~chinese JPG编码质量(50-99],其他格式无效 \~english JPG Encoding quality(50-99] + # < \~chinese ch:Bayer格式转为RGB24的插值方法 0-快速 1-均衡 2-最优 3-最优+ + # < \~english en:Interpolation method of convert Bayer to RGB24 0-Fast 1-Equilibrium 2-Optimal 3-Optimal plus + ('iMethodValue', c_int), + ('nReserved', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_SAVE_IMAGE_TO_FILE_PARAM_EX = _MV_SAVE_IMAGE_TO_FILE_PARAM_EX_ + +# \~chinese 图像转换结构体 \~english Pixel convert structure +class _MV_CC_PIXEL_CONVERT_PARAM_T_(Structure): + pass +_MV_CC_PIXEL_CONVERT_PARAM_T_._fields_ = [ + ('nWidth', c_ushort), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_ushort), # < \~chinese 图像高 \~english Image Height + ('enSrcPixelType', MvGvspPixelType), # < \~chinese 源像素格式 \~english Source pixel format + ('pSrcData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input data buffer + ('nSrcDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input data size + ('enDstPixelType', MvGvspPixelType), # < \~chinese 目标像素格式 \~english Destination pixel format + ('pDstBuffer', POINTER(c_ubyte)), # < \~chinese 输出数据缓存 \~english Output data buffer + ('nDstLen', c_uint), # < \~chinese 输出数据大小 \~english Output data size + ('nDstBufferSize', c_uint), # < \~chinese 提供的输出缓冲区大小 \~english Provided outbut buffer size + ('nRes', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_PIXEL_CONVERT_PARAM = _MV_CC_PIXEL_CONVERT_PARAM_T_ + +class _MV_PIXEL_CONVERT_PARAM_EX_T_(Structure): + pass +_MV_PIXEL_CONVERT_PARAM_EX_T_._fields_ = [ + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + ('enSrcPixelType', MvGvspPixelType), # < \~chinese 源像素格式 \~english Source pixel format + ('pSrcData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input data buffer + ('nSrcDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input data size + ('enDstPixelType', MvGvspPixelType), # < \~chinese 目标像素格式 \~english Destination pixel format + ('pDstBuffer', POINTER(c_ubyte)), # < \~chinese 输出数据缓存 \~english Output data buffer + ('nDstLen', c_uint), # < \~chinese 输出数据大小 \~english Output data size + ('nDstBufferSize', c_uint), # < \~chinese 提供的输出缓冲区大小 \~english Provided outbut buffer size + ('nRes', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_PIXEL_CONVERT_PARAM_EX = _MV_PIXEL_CONVERT_PARAM_EX_T_ + +# values for enumeration '_MV_RECORD_FORMAT_TYPE_' +_MV_RECORD_FORMAT_TYPE_ = c_int # enum +MV_RECORD_FORMAT_TYPE = _MV_RECORD_FORMAT_TYPE_ + +# \~chinese 录像参数 \~english Record Parameters +class _MV_CC_RECORD_PARAM_T_(Structure): + pass +_MV_CC_RECORD_PARAM_T_._fields_ = [ + ('enPixelType', MvGvspPixelType), # < \~chinese 输入数据的像素格式 \~english Ip config option + ('nWidth', c_ushort), # < \~chinese 图像宽(指定目标参数时需为2的倍数) \~english Ip config option + ('nHeight', c_ushort), # < \~chinese 图像高(指定目标参数时需为2的倍数) \~english Ip config option + ('fFrameRate', c_float), # < \~chinese 帧率fps(1/16-120) \~english Ip config option + ('nBitRate', c_uint), # < \~chinese 码率kbps(128kbps-16Mbps) \~english Ip config option + ('enRecordFmtType', MV_RECORD_FORMAT_TYPE), # < \~chinese 录像格式 \~english Ip config option + ('strFilePath', STRING), # < \~chinese 录像文件存放路径(如果路径中存在中文,需转成utf-8) \~english Video file storage path (if there is Chinese in the path, it needs to be converted to utf-8) + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_RECORD_PARAM = _MV_CC_RECORD_PARAM_T_ + +# \~chinese 录像数据 \~english Record Data +class _MV_CC_INPUT_FRAME_INFO_T_(Structure): + pass +_MV_CC_INPUT_FRAME_INFO_T_._fields_ = [ + ('pData', POINTER(c_ubyte)), # < \~chinese 图像数据指针 \~english Input Data Buffer + ('nDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input Data Size + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_INPUT_FRAME_INFO = _MV_CC_INPUT_FRAME_INFO_T_ + +# values for enumeration '_MV_CAM_ACQUISITION_MODE_' +_MV_CAM_ACQUISITION_MODE_ = c_int # enum +MV_CAM_ACQUISITION_MODE = _MV_CAM_ACQUISITION_MODE_ + +# values for enumeration '_MV_CAM_GAIN_MODE_' +_MV_CAM_GAIN_MODE_ = c_int # enum +MV_CAM_GAIN_MODE = _MV_CAM_GAIN_MODE_ + +# values for enumeration '_MV_CAM_EXPOSURE_MODE_' +_MV_CAM_EXPOSURE_MODE_ = c_int # enum +MV_CAM_EXPOSURE_MODE = _MV_CAM_EXPOSURE_MODE_ + +# values for enumeration '_MV_CAM_EXPOSURE_AUTO_MODE_' +_MV_CAM_EXPOSURE_AUTO_MODE_ = c_int # enum +MV_CAM_EXPOSURE_AUTO_MODE = _MV_CAM_EXPOSURE_AUTO_MODE_ + +# values for enumeration '_MV_CAM_TRIGGER_MODE_' +_MV_CAM_TRIGGER_MODE_ = c_int # enum +MV_CAM_TRIGGER_MODE = _MV_CAM_TRIGGER_MODE_ + +# values for enumeration '_MV_CAM_GAMMA_SELECTOR_' +_MV_CAM_GAMMA_SELECTOR_ = c_int # enum +MV_CAM_GAMMA_SELECTOR = _MV_CAM_GAMMA_SELECTOR_ + +# values for enumeration '_MV_CAM_BALANCEWHITE_AUTO_' +_MV_CAM_BALANCEWHITE_AUTO_ = c_int # enum +MV_CAM_BALANCEWHITE_AUTO = _MV_CAM_BALANCEWHITE_AUTO_ + +# values for enumeration '_MV_CAM_TRIGGER_SOURCE_' +_MV_CAM_TRIGGER_SOURCE_ = c_int # enum +MV_CAM_TRIGGER_SOURCE = _MV_CAM_TRIGGER_SOURCE_ + +# \~chinese Event事件回调信息\ \~english Event callback infomation +class _MV_EVENT_OUT_INFO_(Structure): + pass +_MV_EVENT_OUT_INFO_._fields_ = [ + ('EventName', c_char * MAX_EVENT_NAME_SIZE), # < \~chinese Event名称 \~english Event name + ('nEventID', c_ushort), # < \~chinese Event号 \~english Event ID + ('nStreamChannel', c_ushort), # < \~chinese 流通道序号 \~english Circulation number + ('nBlockIdHigh', c_uint), # < \~chinese 帧号高位 (暂无固件支持) \~english BlockId high, not support + ('nBlockIdLow', c_uint), # < \~chinese 帧号低位 (暂无固件支持) \~english BlockId low, not support + ('nTimestampHigh', c_uint), # < \~chinese 时间戳高位 \~english Timestramp high + ('nTimestampLow', c_uint), # < \~chinese 时间戳低位 \~english Timestramp low + ('pEventData', c_void_p), # < \~chinese Event数据 (暂无固件支持) \~english Event data, not support + ('nEventDataSize', c_uint), # < \~chinese Event数据长度 (暂无固件支持) \~english Event data len, not support + ('nReserved', c_uint * 16), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_EVENT_OUT_INFO = _MV_EVENT_OUT_INFO_ + +# \~chinese 文件存取 \~english File Access +class _MV_CC_FILE_ACCESS_T(Structure): + pass +_MV_CC_FILE_ACCESS_T._fields_ = [ + ('pUserFileName', STRING), # < \~chinese 用户文件名 \~english User file name + ('pDevFileName', STRING), # < \~chinese 设备文件名 \~english Device file name + ('nReserved', c_uint * 32), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_FILE_ACCESS = _MV_CC_FILE_ACCESS_T + +# \~chinese 文件存取进度 \~english File Access Progress +class _MV_CC_FILE_ACCESS_PROGRESS_T(Structure): + pass +_MV_CC_FILE_ACCESS_PROGRESS_T._fields_ = [ + ('nCompleted', int64_t), # < \~chinese 已完成的长度 \~english Completed Length + ('nTotal', int64_t), # < \~chinese 总长度 \~english Total Length + ('nReserved', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_FILE_ACCESS_PROGRESS = _MV_CC_FILE_ACCESS_PROGRESS_T + +# values for enumeration '_MV_GIGE_TRANSMISSION_TYPE_' +_MV_GIGE_TRANSMISSION_TYPE_ = c_int # enum +MV_GIGE_TRANSMISSION_TYPE = _MV_GIGE_TRANSMISSION_TYPE_ + +# 传输模式,可以为单播模式、组播模式等 \~english Transmission type +class _MV_TRANSMISSION_TYPE_T(Structure): + pass +_MV_TRANSMISSION_TYPE_T._fields_ = [ + ('enTransmissionType', MV_GIGE_TRANSMISSION_TYPE), # < \~chinese 传输模式 \~english Transmission type + ('nDestIp', c_uint), # < \~chinese 目标IP,组播模式下有意义 \~english Destination IP + ('nDestPort', c_ushort), # < \~chinese 目标Port,组播模式下有意义 \~english Destination port + ('nReserved', c_uint * 32), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_TRANSMISSION_TYPE = _MV_TRANSMISSION_TYPE_T + +# \~chinese 动作命令信息 \~english Action Command +class _MV_ACTION_CMD_INFO_T(Structure): + pass +_MV_ACTION_CMD_INFO_T._fields_ = [ + ('nDeviceKey', c_uint), # < \~chinese 设备密钥 \~english Device key + ('nGroupKey', c_uint), # < \~chinese 组键 \~english Group key + ('nGroupMask', c_uint), # < \~chinese 组掩码 \~english Group mask + ('bActionTimeEnable', c_uint), # < \~chinese 只有设置成1时Action Time才有效,非1时无效 \~english Action time enable + ('nActionTime', int64_t), # < \~chinese 预定的时间,和主频有关 \~english Action time + ('pBroadcastAddress', STRING), # < \~chinese 广播包地址 \~english Broadcast address + ('nTimeOut', c_uint), # < \~chinese 等待ACK的超时时间,如果为0表示不需要ACK \~english Timeout + ('nReserved', c_uint * 16), # < \~chinese 预留 \~english Reserved bytes +] +MV_ACTION_CMD_INFO = _MV_ACTION_CMD_INFO_T + +# \~chinese 动作命令返回信息 \~english Action Command Result +class _MV_ACTION_CMD_RESULT_T(Structure): + pass +_MV_ACTION_CMD_RESULT_T._fields_ = [ + ('strDeviceAddress', c_ubyte * 16), # < \~chinese IP配置选项 \~english IP address of the device + #1.0x0000:success. + #2.0x8001:Command is not supported by the device. + #3.0x8013:The device is not synchronized to a master clock to be used as time reference. + #4.0x8015:A device queue or packet data has overflowed. + #5.0x8016:The requested scheduled action command was requested at a time that is already past. + ('nStatus', c_int), # < \~chinese 状态码 \~english status + ('nReserved', c_uint * 4), # < \~chinese 预留 \~english Reserved bytes +] +MV_ACTION_CMD_RESULT = _MV_ACTION_CMD_RESULT_T + +# \~chinese 动作命令返回信息列表 \~english Action Command Result List +class _MV_ACTION_CMD_RESULT_LIST_T(Structure): + pass +_MV_ACTION_CMD_RESULT_LIST_T._fields_ = [ + ('nNumResults', c_uint), # < \~chinese 返回值个数 \~english Num Results + ('pResults', POINTER(MV_ACTION_CMD_RESULT)), # < \~chinese 动作命令返回信息 \~english action command result list +] +MV_ACTION_CMD_RESULT_LIST = _MV_ACTION_CMD_RESULT_LIST_T + +# values for enumeration 'MV_XML_InterfaceType' +MV_XML_InterfaceType = c_int # enum + +# values for enumeration 'MV_XML_AccessMode' +MV_XML_AccessMode = c_int # enum + +# \~chinese 枚举类型值 \~english Enumeration Value +class _MVCC_ENUMVALUE_T(Structure): + pass +_MVCC_ENUMVALUE_T._fields_ = [ + ('nCurValue', c_uint), # < \~chinese 当前值 \~english Current Value + ('nSupportedNum', c_uint), # < \~chinese 数据的有效数据个数 \~english Number of valid data + ('nSupportValue', c_uint * MV_MAX_XML_SYMBOLIC_NUM), # < \~chinese 支持值列表 \~english Support value list + ('nReserved', c_uint * 4), # < \~chinese 预留 \~english Reserved bytes +] +MVCC_ENUMVALUE = _MVCC_ENUMVALUE_T + +# \~chinese Int类型值 \~english Int Value +class _MVCC_INTVALUE_T(Structure): + pass +_MVCC_INTVALUE_T._fields_ = [ + ('nCurValue', c_uint), # < \~chinese 当前值 \~english Current Value + ('nMax', c_uint), # < \~chinese 最大值 \~english Max Value + ('nMin', c_uint), # < \~chinese 最小值 \~english Min Value + ('nInc', c_uint), # < \~chinese 步径 \~english Step size + ('nReserved', c_uint * 4), # < \~chinese 预留 \~english Reserved bytes +] +MVCC_INTVALUE = _MVCC_INTVALUE_T + +# \~chinese Int类型值Ex \~english Int Value Ex +class _MVCC_INTVALUE_EX_T(Structure): + pass +_MVCC_INTVALUE_EX_T._fields_ = [ + ('nCurValue', int64_t), # < \~chinese 当前值 \~english Current Value + ('nMax', int64_t), # < \~chinese 最大值 \~english Max Value + ('nMin', int64_t), # < \~chinese 最小值 \~english Min Value + ('nInc', int64_t), # < \~chinese 步径 \~english Step size + ('nReserved', c_uint * 16), # < \~chinese 预留 \~english Reserved bytes +] +MVCC_INTVALUE_EX = _MVCC_INTVALUE_EX_T + +# \~chinese Float类型值 \~english Float Value +class _MVCC_FLOATVALUE_T(Structure): + pass +_MVCC_FLOATVALUE_T._fields_ = [ + ('fCurValue', c_float), # < \~chinese 当前值 \~english Current Value + ('fMax', c_float), # < \~chinese 最大值 \~english Max Value + ('fMin', c_float), # < \~chinese 最小值 \~english Min Value + ('nReserved', c_uint * 4), # < \~chinese 预留 \~english Reserved bytes +] +MVCC_FLOATVALUE = _MVCC_FLOATVALUE_T + +# \~chinese String类型值 \~english String Value +class _MVCC_STRINGVALUE_T(Structure): + pass +_MVCC_STRINGVALUE_T._fields_ = [ + ('chCurValue', c_char * 256), # < \~chinese 当前值 \~english Current Value + ('nMaxLength', int64_t), # < \~chinese 最大长度 \~english Max length + ('nReserved', c_uint * 2), # < \~chinese 预留 \~english Reserved bytes +] +MVCC_STRINGVALUE = _MVCC_STRINGVALUE_T + +# \~chinese 水印信息 \~english Frame-specific information +class _MV_CC_FRAME_SPEC_INFO_(Structure): + pass +_MV_CC_FRAME_SPEC_INFO_._fields_ = [ + # < \~chinese 设备水印时标 \~english Device frame-specific time scale + ('nSecondCount', c_uint), # < \~chinese 秒数 \~english The Seconds + ('nCycleCount', c_uint), # < \~chinese 周期数 \~english The Count of Cycle + ('nCycleOffset', c_uint), # < \~chinese 周期偏移量 \~english The Offset of Cycle + ('fGain', c_float), # < \~chinese 增益 \~english Gain + ('fExposureTime', c_float), # < \~chinese 曝光时间 \~english Exposure Time + ('nAverageBrightness', c_uint), # < \~chinese 平均亮度 \~english Average brightness + # < \~chinese 白平衡相关 \~english White balance + ('nRed', c_uint), # < \~chinese 红色 \~english Red + ('nGreen', c_uint), # < \~chinese 绿色 \~english Green + ('nBlue', c_uint), # < \~chinese 蓝色 \~english Blue + ('nFrameCounter', c_uint), # < \~chinese 总帧数 \~english Frame Counter + ('nTriggerIndex', c_uint), # < \~chinese 触发计数 \~english Trigger Counting + ('nInput', c_uint), # < \~chinese 输入 \~english Input + ('nOutput', c_uint), # < \~chinese 输出 \~english Output + # < \~chinese ROI区域 \~english ROI Region + ('nOffsetX', c_ushort), # < \~chinese 水平偏移量 \~english OffsetX + ('nOffsetY', c_ushort), # < \~chinese 垂直偏移量 \~english OffsetY + ('nFrameWidth', c_ushort), # < \~chinese 水印宽 \~english The Width of Chunk + ('nFrameHeight', c_ushort), # < \~chinese 水印高 \~english The Height of Chunk + ('nReserved', c_uint * 16), # < \~chinese 预留 \~english Reserved bytes +] +MV_CC_FRAME_SPEC_INFO = _MV_CC_FRAME_SPEC_INFO_ + +# \~chinese 无损解码参数 \~english High Bandwidth decode structure +class _MV_CC_HB_DECODE_PARAM_T_(Structure): + pass +_MV_CC_HB_DECODE_PARAM_T_._fields_ = [ + ('pSrcBuf', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input data buffer + ('nSrcLen', c_uint), # < \~chinese 输入数据大小 \~english Input data size + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + ('pDstBuf', POINTER(c_ubyte)), # < \~chinese 输出数据缓存 \~english Output data buffer + ('nDstBufSize', c_uint), # < \~chinese 提供的输出缓冲区大小 \~english Provided output buffer size + ('nDstBufLen', c_uint), # < \~chinese 输出数据大小 \~english Output data size + ('enDstPixelType', MvGvspPixelType), # < \~chinese 输出的像素格式 \~english Output pixel format + ('stFrameInfo', MV_CC_FRAME_SPEC_INFO), # < \~chinese 水印信息 \~english Frame Spec Info + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_HB_DECODE_PARAM = _MV_CC_HB_DECODE_PARAM_T_ + +# values for enumeration '_MV_SORT_METHOD_' +_MV_SORT_METHOD_ = c_int # enum +MV_SORT_METHOD = _MV_SORT_METHOD_ + +# values for enumeration '_MV_IMG_ROTATION_ANGLE_' +_MV_IMG_ROTATION_ANGLE_ = c_int # enum +MV_IMG_ROTATION_ANGLE = _MV_IMG_ROTATION_ANGLE_ + +# values for enumeration '_MV_IMG_FLIP_TYPE_' +_MV_IMG_FLIP_TYPE_ = c_int # enum +MV_IMG_FLIP_TYPE = _MV_IMG_FLIP_TYPE_ + +# values for enumeration '_MV_CC_GAMMA_TYPE_' +_MV_CC_GAMMA_TYPE_ = c_int # enum +MV_CC_GAMMA_TYPE = _MV_CC_GAMMA_TYPE_ + +# values for enumeration '_MV_CC_STREAM_EXCEPTION_TYPE_' +_MV_CC_STREAM_EXCEPTION_TYPE_ = c_int # enum +MV_CC_STREAM_EXCEPTION_TYPE = _MV_CC_STREAM_EXCEPTION_TYPE_ + +# values for enumeration '_MV_IMAGE_RECONSTRUCTION_METHOD_' +_MV_IMAGE_RECONSTRUCTION_METHOD_ = c_int # enum +MV_IMAGE_RECONSTRUCTION_METHOD = _MV_IMAGE_RECONSTRUCTION_METHOD_ + +# \~chinese 图像旋转结构体 \~english Rotate image structure +class _MV_CC_ROTATE_IMAGE_PARAM_T_(Structure): + pass +_MV_CC_ROTATE_IMAGE_PARAM_T_._fields_ = [ + ('enPixelType', MvGvspPixelType), # < \~chinese 像素格式 \~english pixel format + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + ('pSrcData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input data buffer + ('nSrcDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input data length + ('pDstBuf', POINTER(c_ubyte)), # < \~chinese 输出数据缓存 \~english Output data buffer + ('nDstBufLen', c_uint), # < \~chinese输出数据长度 \~english Output data length + ('nDstBufSize', c_uint), # < \~chinese 提供的输出缓冲区大小 \~english Provided output buffer size + ('enRotationAngle', MV_IMG_ROTATION_ANGLE), # < \~chinese 旋转角度 \~english Rotation angle + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_ROTATE_IMAGE_PARAM = _MV_CC_ROTATE_IMAGE_PARAM_T_ + +# \~chinese 图像翻转结构体 \~english Flip image structure +class _MV_CC_FLIP_IMAGE_PARAM_T_(Structure): + pass +_MV_CC_FLIP_IMAGE_PARAM_T_._fields_ = [ + ('enPixelType', MvGvspPixelType), # < \~chinese 像素格式 \~english pixel format + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + ('pSrcData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input data buffer + ('nSrcDataLen', c_uint), # < \~chinese 输入数据大小 \~english Input data length + ('pDstBuf', POINTER(c_ubyte)), # < \~chinese 输出数据缓存 \~english Output data buffer + ('nDstBufLen', c_uint), # < \~chinese输出数据长度 \~english Output data length + ('nDstBufSize', c_uint), # < \~chinese 提供的输出缓冲区大小 \~english Provided output buffer size + ('enFlipType', MV_IMG_FLIP_TYPE), # < \~chinese 翻转类型 \~english Flip type + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_FLIP_IMAGE_PARAM = _MV_CC_FLIP_IMAGE_PARAM_T_ + +# \~chinese Gamma信息结构体 \~english Gamma info structure +class _MV_CC_GAMMA_PARAM_T_(Structure): + pass +_MV_CC_GAMMA_PARAM_T_._fields_ = [ + ('enGammaType', MV_CC_GAMMA_TYPE), # < \~chinese Gamma类型 \~english Gamma type + ('fGammaValue', c_float), # < \~chinese Gamma值[0.1,4.0] \~english Gamma value[0.1,4.0] + ('pGammaCurveBuf', POINTER(c_ubyte)), # < \~chinese Gamma曲线缓存 \~english Gamma curve buffer + ('nGammaCurveBufLen', c_uint), # < \~chinese Gamma曲线长度 \~english Gamma curve buffer size + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_GAMMA_PARAM = _MV_CC_GAMMA_PARAM_T_ + +# \~chinese CCM参数 \~english CCM param +class _MV_CC_CCM_PARAM_T_(Structure): + pass +_MV_CC_CCM_PARAM_T_._fields_ = [ + ('bCCMEnable', c_bool), # < \~chinese 是否启用CCM \~english CCM enable + ('nCCMat', c_int * 9), # < \~chinese CCM矩阵[-8192~8192] \~english Color correction matrix[-8192~8192] + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_CCM_PARAM = _MV_CC_CCM_PARAM_T_ + +# \~chinese CCM参数 \~english CCM param +class _MV_CC_CCM_PARAM_EX_T_(Structure): + pass +_MV_CC_CCM_PARAM_EX_T_._fields_ = [ + ('bCCMEnable', c_bool), # < \~chinese 是否启用CCM \~english CCM enable + ('nCCMat', c_int * 9), # < \~chinese CCM矩阵[-65536~65536] \~english Color correction matrix[-65536~65536] + ('nCCMScale', c_uint), # < \~chinese 量化系数(2的整数幂,最大65536) \~english Quantitative scale(Integer power of 2, <= 65536) + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_CCM_PARAM_EX = _MV_CC_CCM_PARAM_EX_T_ + +# \~chinese 对比度调节结构体 \~english Contrast structure +class _MV_CC_CONTRAST_PARAM_T_(Structure): + pass +_MV_CC_CONTRAST_PARAM_T_._fields_ = [ + ('nWidth', c_uint), # < \~chinese 图像宽(最小8) \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高(最小8) \~english Image Height + ('pSrcBuf', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english Input data buffer + ('nSrcBufLen', c_uint), # < \~chinese 输入数据大小 \~english Input data length + ('enPixelType', MvGvspPixelType), # < \~chinese 像素格式 \~english pixel format + ('pDstBuf', POINTER(c_ubyte)), # < \~chinese 输出数据缓存 \~english Output data buffer + ('nDstBufSize', c_uint), # < \~chinese提供的输出缓冲区大小 \~english Provided output buffer size + ('nDstBufLen', c_uint), # < \~chinese 输出数据长度 \~english Output data length + ('nContrastFactor', c_uint), # < \~chinese 对比度值,[1,10000] \~english Contrast factor,[1,10000] + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_CONTRAST_PARAM_T = _MV_CC_CONTRAST_PARAM_T_ + +# \~chinese 枚举类型条目 \~english Enumeration Entry +class _MVCC_ENUMENTRY_T(Structure): + pass +_MVCC_ENUMENTRY_T._fields_ = [ + ('nValue', c_uint), # < \~chinese 指定值 \~english Value + ('chSymbolic', c_char * MV_MAX_SYMBOLIC_LEN), # < \~chinese 指定值对应的符号 \~english Symbolic + + ('nReserved', c_uint * 4), # < \~chinese 预留 \~english Reserved bytes +] +MVCC_ENUMENTRY = _MVCC_ENUMENTRY_T + +# \~chinese 辅助线颜色 \~english Color of Auxiliary Line +class _MVCC_COLORF(Structure): + pass +_MVCC_COLORF._fields_ = [ + ('fR', c_float), + # < \~chinese 红色,根据像素颜色的相对深度,范围为[0.0 , 1.0],代表着[0, 255]的颜色深度 \~english Red,Range[0.0, 1.0] + ('fG', c_float), + # < \~chinese 绿色,根据像素颜色的相对深度,范围为[0.0 , 1.0],代表着[0, 255]的颜色深度 \~english Green,Range[0.0, 1.0] + ('fB', c_float), + # < \~chinese 蓝色,根据像素颜色的相对深度,范围为[0.0 , 1.0],代表着[0, 255]的颜色深度 \~english Blue,Range[0.0, 1.0] + ('fAlpha', c_float), + # < \~chinese 透明度,根据像素颜色的相对透明度,范围为[0.0 , 1.0] (此参数功能暂不支持) \~english Alpha,Range[0.0, 1.0](Not Support) + ('nReserved', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MVCC_COLORF = _MVCC_COLORF + +# \~chinese 自定义点 \~english Point defined +class _MVCC_POINTF(Structure): + pass +_MVCC_POINTF._fields_ = [ + ('fX', c_float), + # < \~chinese 该点距离图像左边缘距离,根据图像的相对位置,范围为[0.0 , 1.0] \~english Distance From Left,Range[0.0, 1.0] + ('fY', c_float), + # < \~chinese 该点距离图像上边缘距离,根据图像的相对位置,范围为[0.0 , 1.0] \~english Distance From Top,Range[0.0, 1.0] + ('nReserved', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MVCC_POINTF = _MVCC_POINTF + +# \~chinese 矩形框区域信息 \~english Rect Area Info +class _MVCC_RECT_INFO(Structure): + pass +_MVCC_RECT_INFO._fields_ = [ + ('fTop', c_float), + # < \~chinese 矩形上边缘距离图像上边缘的距离,根据图像的相对位置,范围为[0.0 , 1.0] \~english Distance From Top,Range[0, 1.0] + ('fBottom', c_float), + # < \~chinese 矩形下边缘距离图像下边缘的距离,根据图像的相对位置,范围为[0.0 , 1.0] \~english Distance From Bottom,Range[0, 1.0] + ('fLeft', c_float), + # < \~chinese 矩形左边缘距离图像左边缘的距离,根据图像的相对位置,范围为[0.0 , 1.0] \~english Distance From Left,Range[0, 1.0] + ('fRight', c_float), + # < \~chinese 矩形右边缘距离图像右边缘的距离,根据图像的相对位置,范围为[0.0 , 1.0] \~english Distance From Right,Range[0, 1.0] + ('stColor', MVCC_COLORF), # < \~chinese 辅助线颜色信息 \~english Color of Auxiliary Line + ('nLineWidth', c_uint), # < \~chinese 辅助线宽度,宽度只能是1或2 \~english Width of Auxiliary Line, width is 1 or 2 + ('nReserved', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MVCC_RECT_INFO = _MVCC_RECT_INFO + +# \~chinese 圆形框区域信息 \~english Circle Area Info +class _MVCC_CIRCLE_INFO(Structure): + pass +_MVCC_CIRCLE_INFO._fields_ = [ + ('stCenterPoint', MVCC_POINTF), # < \~chinese 圆心信息 \~english Circle Point Info + ('fR1', c_float), + # < \~chinese 宽向半径,根据图像的相对位置[0, 1.0],半径与圆心的位置有关,需保证画出的圆在显示框范围之内,否则报错 \~english Width Radius, Range[0, 1.0] + ('fR2', c_float), + # < \~chinese高向半径,根据图像的相对位置[0, 1.0],半径与圆心的位置有关,需保证画出的圆在显示框范围之内,否则报错 \~english Height Radius, Range[0, 1.0] + ('stColor', MVCC_COLORF), # < \~chinese 辅助线颜色信息 \~english Color of Auxiliary Line + ('nLineWidth', c_uint), # < \~chinese 辅助线宽度,宽度只能是1或2 \~english Width of Auxiliary Line, width is 1 or 2 + ('nReserved', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MVCC_CIRCLE_INFO = _MVCC_CIRCLE_INFO + +# \~chinese 线条辅助线信息 \~english Linear Auxiliary Line Info +class _MVCC_LINES_INFO(Structure): + pass +_MVCC_LINES_INFO._fields_ = [ + ('stStartPoint', MVCC_POINTF), # < \~chinese 线条辅助线的起始点坐标 \~english The Start Point of Auxiliary Line + ('stEndPoint', MVCC_POINTF), # < \~chinese线条辅助线的终点坐标 \~english The End Point of Auxiliary Line + ('stColor', MVCC_COLORF), # < \~chinese 辅助线颜色信息 \~english Color of Auxiliary Line + ('nLineWidth', c_uint), # < \~chinese 辅助线宽度,宽度只能是1或2 \~english Width of Auxiliary Line, width is 1 or 2 + ('nReserved', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MVCC_LINES_INFO = _MVCC_LINES_INFO + +# \~chinese 图像重构后的图像列表 \~english List of images after image reconstruction +class _MV_OUTPUT_IMAGE_INFO_(Structure): + pass +_MV_OUTPUT_IMAGE_INFO_._fields_ = [ + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + ('enPixelType', MvGvspPixelType), # < \~chinese 像素格式 \~english pixel format + ('pBuf', POINTER(c_ubyte)), # < \~chinese 输出数据缓存 \~english Output data buffer + ('nBufLen', c_uint), # < \~chinese 输出数据长度 \~english Output data length + ('nBufSize', c_uint), # < \~chinese 提供的输出缓冲区大小 \~english Provided output buffer size + ('nRes', c_uint * 8), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_OUTPUT_IMAGE_INFO = _MV_OUTPUT_IMAGE_INFO_ + +# \~chinese 重构图像参数信息 \~english Restructure image parameters +class _MV_RECONSTRUCT_IMAGE_PARAM_(Structure): + pass +_MV_RECONSTRUCT_IMAGE_PARAM_._fields_ = [ + ('nWidth', c_uint), # < \~chinese 图像宽 \~english Image Width + ('nHeight', c_uint), # < \~chinese 图像高 \~english Image Height + ('enPixelType', MvGvspPixelType), # < \~chinese 像素格式 \~english pixel format + ('pSrcData', POINTER(c_ubyte)), # < \~chinese 输入数据缓存 \~english input data buffer + ('nSrcDataLen', c_uint), # < \~chinese 输入数据大小 \~english input data size + ('nExposureNum', c_uint), # < \~chinese 曝光个数(1-8] \~english Exposure number + ('enReconstructMethod', MV_IMAGE_RECONSTRUCTION_METHOD), # < \~chinese 图像重构方式 \~english Image restructuring method + ('stDstBufList', MV_OUTPUT_IMAGE_INFO * MV_MAX_SPLIT_NUM), # < \~chinese 输出数据缓存信息 \~english Output data info + ('nRes', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_RECONSTRUCT_IMAGE_PARAM = _MV_RECONSTRUCT_IMAGE_PARAM_ + +# \~chinese 文件存取 \~english File Access +class _MV_CC_FILE_ACCESS_E(Structure): + pass +_MV_CC_FILE_ACCESS_E._fields_ = [ + ('pUserFileBuf', POINTER(c_char)), # < \~chinese 用户文件数据 \~english User file data + ('pFileBufSize', c_uint), # < \~chinese 用户数据缓存大小 \~english data buffer size + ('pFileBufLen', c_uint), # < \~chinese 用户数据缓存长度 \~english data buffer len + ('pDevFileName', STRING), # < \~chinese 设备文件名 \~english Device file name + ('nReserved', c_uint * 32), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CC_FILE_ACCESS_EX = _MV_CC_FILE_ACCESS_E + +# 采集卡信息 \~english Interface information +class _MV_INTERFACE_INFO_(Structure): + pass +_MV_INTERFACE_INFO_._fields_ = [ + ('nTLayerType', c_uint), # < \~chinese 采集卡类型 \~english Interface type + ('nPCIEInfo', c_uint), # < \~chinese 采集卡的PCIE插槽信息 \~english PCIe slot information of interface + ('chInterfaceID', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 采集卡ID \~english Interface ID + ('chDisplayName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 显示名称 \~english Display name + ('chSerialNumber', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 序列号 \~english Serial number + ('chModelName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 型号 \~english model name + ('chManufacturer', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 厂商 \~english manufacturer name + ('chDeviceVersion', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 版本号 \~english device version + ('chUserDefinedName', c_ubyte * INFO_MAX_BUFFER_SIZE), # < \~chinese 自定义名称 \~english user defined name + ('nReserved', c_uint * 64), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_INTERFACE_INFO = _MV_INTERFACE_INFO_ + +# 采集卡信息列表 \~english Interface Information List +class _MV_INTERFACE_INFO_LIST_(Structure): + pass +_MV_INTERFACE_INFO_LIST_._fields_ = [ + ('nInterfaceNum', c_uint), # < \~chinese 在线设备数量 \~english Online Device Number + ('pInterfaceInfos', POINTER(MV_INTERFACE_INFO) * MV_MAX_INTERFACE_NUM), # < \~chinese 支持最多256个设备 \~english Support up to 256 devices +] +MV_INTERFACE_INFO_LIST = _MV_INTERFACE_INFO_LIST_ + +# 串口信息 \~english Serial Port Info +class _MV_CAML_SERIAL_PORT_(Structure): + pass +_MV_CAML_SERIAL_PORT_._fields_ = [ + ('chSerialPort', c_char * INFO_MAX_BUFFER_SIZE), # < \~chinese 串口号 \~english Serial Port + ('nRes', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CAML_SERIAL_PORT = _MV_CAML_SERIAL_PORT_ + +# 本机串口列表 \~english serial port list +class _MV_CAML_SERIAL_PORT_LIST_(Structure): + pass +_MV_CAML_SERIAL_PORT_LIST_._fields_ = [ + ('nSerialPortNum', c_uint), # < \~chinese 串口数量 \~english Serial Port Num + ('stSerialPort', MV_CAML_SERIAL_PORT * MV_MAX_SERIAL_PORT_NUM), # < \~chinese 串口信息 \~english Serial Port Information + ('nRes', c_uint * 4), # < \~chinese 保留字节 \~english Reserved bytes +] +MV_CAML_SERIAL_PORT_LIST = _MV_CAML_SERIAL_PORT_LIST_ + +__all__ = ['_MV_ALL_MATCH_INFO_', 'MV_CC_FILE_ACCESS_PROGRESS', + 'N19_MV_CC_DEVICE_INFO_3DOT_0E', 'MV_FRAME_OUT', + 'MV_CAM_GAIN_MODE', + 'MV_ALL_MATCH_INFO', + 'MV_GIGE_TRANSTYPE_UNICAST_WITHOUT_RECV', + 'MV_TRIGGER_SOURCE_LINE0', 'MV_PointCloudFile_Undefined', + 'MV_TRIGGER_SOURCE_LINE2', 'MV_TRIGGER_SOURCE_LINE3', + 'AM_CycleDetect', + 'MV_GrabStrategy_UpcomingImage', 'IFT_IFloat', + 'MV_EVENT_OUT_INFO', 'MV_TRANSMISSION_TYPE', + 'uint_fast16_t', 'MV_CHUNK_DATA_CONTENT','MV_ACTION_CMD_RESULT', + 'MV_CC_INPUT_FRAME_INFO', + '_MV_ACTION_CMD_RESULT_T', + 'AM_RO', 'IFT_IPort', 'uint_least16_t', + '_MV_FRAME_OUT_INFO_EX_', '_MV_TRANSMISSION_TYPE_T', + 'MV_SAVE_IMAGE_PARAM_EX', 'MV_SAVE_IMAGE_PARAM_EX3', 'AM_RW', 'MV_XML_InterfaceType', + 'int32_t', '_MV_ACTION_CMD_INFO_T', 'intptr_t', + 'uint_least64_t', '_MV_NETTRANS_INFO_', + '_MV_CAM_TRIGGER_MODE_', 'int_least32_t', + 'MV_GIGE_TRANSTYPE_SUBNETBROADCAST', + 'MV_SAVE_POINT_CLOUD_FILE_TYPE', + 'MV_ACTION_CMD_RESULT_LIST', + 'MV_BALANCEWHITE_AUTO_CONTINUOUS', + '_MV_CHUNK_DATA_CONTENT_', 'MV_FormatType_AVI', + '_MV_CC_PIXEL_CONVERT_PARAM_T_','_MV_PIXEL_CONVERT_PARAM_EX_T_', + 'MV_GENTL_IF_INFO', + 'MV_ACQ_MODE_SINGLE', + 'MV_TRIGGER_MODE_ON', + 'int_least16_t', 'N22_MV_FRAME_OUT_INFO_EX_3DOT_1E', + 'MV_GIGE_TRANSTYPE_LIMITEDBROADCAST', 'int_fast32_t', + '_MV_CAM_GAIN_MODE_', + 'MV_RECORD_FORMAT_TYPE', 'MV_CC_DEVICE_INFO', + 'IFT_ICommand', '_MV_RECORD_FORMAT_TYPE_', + '_MV_CAM_ACQUISITION_MODE_', + '_MVCC_STRINGVALUE_T', + 'MV_GIGE_TRANSTYPE_MULTICAST_WITHOUT_RECV', + '_MV_MATCH_INFO_NET_DETECT_', 'MVCC_INTVALUE', + 'MV_PointCloudFile_OBJ', '_MV_GIGE_TRANSMISSION_TYPE_', + '_MV_CC_RECORD_PARAM_T_', + '_MV_GENTL_IF_INFO_', 'MV_EXPOSURE_MODE_TIMED', 'intmax_t', + 'int16_t', + 'MV_DISPLAY_FRAME_INFO', '_MV_CC_FILE_ACCESS_PROGRESS_T', + '_MV_GRAB_STRATEGY_', '_MV_SAVE_IMG_TO_FILE_PARAM_', '_MV_SAVE_IMAGE_TO_FILE_PARAM_EX_', + 'int_fast64_t', + 'MV_XML_AccessMode', + 'MV_GAIN_MODE_ONCE', 'IFT_IInteger', + 'MV_CAM_BALANCEWHITE_AUTO', 'int_least8_t', + 'MV_PointCloudFile_CSV', 'IFT_IBase', + 'MV_TRIGGER_MODE_OFF', 'MV_Image_Bmp', + '_MV_GENTL_DEV_INFO_', 'MV_CC_FILE_ACCESS', + '_MV_CAM_EXPOSURE_AUTO_MODE_', + 'uint_least8_t', + 'MV_ACTION_CMD_INFO', + '_MV_CC_INPUT_FRAME_INFO_T_', + 'MV_GENTL_DEV_INFO_LIST', '_MV_CAM_TRIGGER_SOURCE_', + 'MV_GRAB_STRATEGY', + 'IFT_IEnumeration', 'uint64_t', 'uint8_t', + '_MV_GENTL_DEV_INFO_LIST_', + 'MV_CAM_GAMMA_SELECTOR', + 'MV_CamL_DEV_INFO', 'MV_GENTL_IF_INFO_LIST', + 'MV_CAM_TRIGGER_MODE', 'MV_GIGE_TRANSTYPE_MULTICAST', + 'uint16_t', 'uint_fast8_t', + '_MV_ACTION_CMD_RESULT_LIST_T', + '_MV_MATCH_INFO_USB_DETECT_', + '_MVCC_ENUMVALUE_T', + 'MV_SAVE_POINT_CLOUD_PARAM', '_MV_CC_DEVICE_INFO_', + 'IFT_IBoolean', + 'MV_MATCH_INFO_USB_DETECT', 'MV_PointCloudFile_PLY', + 'MVCC_ENUMVALUE', + 'IFT_IString', + 'MV_ACQ_MODE_CONTINUOUS', + 'MV_TRIGGER_SOURCE_FrequencyConverter', + 'MV_TRIGGER_SOURCE_COUNTER0', + 'MV_GAIN_MODE_OFF', '_MV_CC_DEVICE_INFO_LIST_', + 'MV_GIGE_DEVICE_INFO', '_MV_SAVE_IMAGE_PARAM_T_EX_', '_MV_SAVE_IMAGE_PARAM_EX3_', + 'AM_NA', 'uint_least32_t', + 'MV_CC_PIXEL_CONVERT_PARAM', 'MV_CC_PIXEL_CONVERT_PARAM_EX','AM_NI', + '_MVCC_INTVALUE_EX_T', 'uintptr_t', 'MV_Image_Tif', + 'MVCC_FLOATVALUE', 'MV_GIGE_TRANSTYPE_CAMERADEFINED', + '_MV_GENTL_IF_INFO_LIST_', 'MV_NETTRANS_INFO', + 'IFT_IRegister', 'MV_GIGE_TRANSMISSION_TYPE', + 'MV_EXPOSURE_AUTO_MODE_ONCE', 'MV_GIGE_TRANSTYPE_UNICAST', + 'int8_t', '_MV_GIGE_DEVICE_INFO_', 'IFT_IValue', 'AM_WO', + 'int_fast8_t', + 'MV_GAMMA_SELECTOR_SRGB','int_least64_t', + 'MV_GrabStrategy_LatestImagesOnly', + 'MV_EXPOSURE_AUTO_MODE_OFF', 'MV_CAM_EXPOSURE_AUTO_MODE', + 'MV_EXPOSURE_AUTO_MODE_CONTINUOUS', + 'MV_CAM_ACQUISITION_MODE', 'AM_Undefined', + 'MV_MATCH_INFO_NET_DETECT', + '_MV_CC_FILE_ACCESS_T', + '_MV_DISPLAY_FRAME_INFO_','MV_GrabStrategy_OneByOne', + 'MV_TRIGGER_SOURCE_SOFTWARE', 'MV_FormatType_Undefined', + 'MV_BALANCEWHITE_AUTO_ONCE', + 'uintmax_t', 'int_fast16_t', + '_MV_CAM_EXPOSURE_MODE_','MV_BALANCEWHITE_AUTO_OFF', + 'int64_t', 'MV_Image_Undefined', 'MV_GAIN_MODE_CONTINUOUS', + 'uint_fast32_t', + 'MV_CAM_TRIGGER_SOURCE', 'MV_GrabStrategy_LatestImages', + 'MV_Image_Png', + 'MV_Image_Jpeg', '_MV_CamL_DEV_INFO_', + '_MVCC_FLOATVALUE_T', + 'MV_FRAME_OUT_INFO_EX', '_MV_SAVE_POINT_CLOUD_PARAM_', + '_MV_CAM_BALANCEWHITE_AUTO_', 'MV_CC_RECORD_PARAM', + '_MV_USB3_DEVICE_INFO_', + 'MVCC_INTVALUE_EX', 'MV_EXPOSURE_MODE_TRIGGER_WIDTH', + 'MV_GIGE_TRANSTYPE_UNICAST_DEFINED_PORT', + 'MV_SAVE_IAMGE_TYPE','MV_GENTL_DEV_INFO', + 'MV_CAM_EXPOSURE_MODE', + 'MVCC_STRINGVALUE', + 'MvGvspPixelType', + 'MV_CC_DEVICE_INFO_LIST', + 'MV_TRIGGER_SOURCE_LINE1', + 'uint_fast64_t','_MVCC_INTVALUE_T', + 'IFT_ICategory', + 'MV_SAVE_IMG_TO_FILE_PARAM', 'MV_SAVE_IMAGE_TO_FILE_PARAM_EX', '_MV_FRAME_OUT_', + 'MV_GAMMA_SELECTOR_USER', + 'uint32_t', '_MV_CAM_GAMMA_SELECTOR_', 'MV_ACQ_MODE_MUTLI', + 'MV_USB3_DEVICE_INFO', '_MV_EVENT_OUT_INFO_', 'MV_CC_FRAME_SPEC_INFO', 'MV_CC_HB_DECODE_PARAM', + 'MV_SORT_METHOD', '_MV_SORT_METHOD_', + 'SortMethod_SerialNumber', 'SortMethod_UserID', 'SortMethod_CurrentIP_ASC', 'SortMethod_CurrentIP_DESC', + '_MV_IMG_ROTATION_ANGLE_', 'MV_IMG_ROTATION_ANGLE', + 'MV_IMAGE_ROTATE_90', 'MV_IMAGE_ROTATE_180', 'MV_IMAGE_ROTATE_270', + '_MV_IMG_FLIP_TYPE_', 'MV_IMG_FLIP_TYPE', 'MV_FLIP_VERTICAL', 'MV_FLIP_HORIZONTAL', + '_MV_CC_GAMMA_TYPE_', 'MV_CC_GAMMA_TYPE', 'MV_CC_GAMMA_TYPE_NONE', 'MV_CC_GAMMA_TYPE_VALUE', + 'MV_CC_GAMMA_TYPE_USER_CURVE', 'MV_CC_GAMMA_TYPE_LRGB2SRGB', 'MV_CC_GAMMA_TYPE_SRGB2LRGB', + 'MV_CC_STREAM_EXCEPTION_TYPE', '_MV_CC_STREAM_EXCEPTION_TYPE_', + 'MV_CC_STREAM_EXCEPTION_ABNORMAL_IMAGE', 'MV_CC_STREAM_EXCEPTION_LIST_OVERFLOW', + 'MV_CC_STREAM_EXCEPTION_LIST_EMPTY', 'MV_CC_STREAM_EXCEPTION_RECONNECTION', + 'MV_CC_STREAM_EXCEPTION_DISCONNECTED', 'MV_CC_STREAM_EXCEPTION_DEVICE', + '_MV_IMAGE_RECONSTRUCTION_METHOD_', 'MV_IMAGE_RECONSTRUCTION_METHOD', 'MV_SPLIT_BY_LINE', + 'MVCC_COLORF', '_MVCC_COLORF', '_MVCC_POINTF', 'MVCC_POINTF', '_MVCC_RECT_INFO', 'MVCC_RECT_INFO', + '_MVCC_CIRCLE_INFO', 'MVCC_CIRCLE_INFO', '_MVCC_LINES_INFO', 'MVCC_LINES_INFO', '_MV_OUTPUT_IMAGE_INFO_', + 'MV_OUTPUT_IMAGE_INFO', 'MV_RECONSTRUCT_IMAGE_PARAM', '_MV_RECONSTRUCT_IMAGE_PARAM_', + '_MVCC_ENUMENTRY_T', 'MVCC_ENUMENTRY','_MV_CC_CONTRAST_PARAM_T_', 'MV_CC_CONTRAST_PARAM_T', + '_MV_CC_CCM_PARAM_EX_T_', 'MV_CC_CCM_PARAM_EX', 'MV_CC_CCM_PARAM', '_MV_CC_CCM_PARAM_T_', + 'MV_CC_GAMMA_PARAM', '_MV_CC_GAMMA_PARAM_T_', 'MV_CC_FLIP_IMAGE_PARAM', '_MV_CC_FLIP_IMAGE_PARAM_T_', + '_MV_CC_ROTATE_IMAGE_PARAM_T_', 'MV_CC_ROTATE_IMAGE_PARAM', 'MV_CC_FILE_ACCESS_EX', '_MV_CC_FILE_ACCESS_E', + '_MV_DISPLAY_FRAME_INFO_EX_', 'MV_DISPLAY_FRAME_INFO_EX', 'MV_CML_DEVICE_INFO', '_MV_CML_DEVICE_INFO_', + 'MV_CXP_DEVICE_INFO', '_MV_CXP_DEVICE_INFO_', '_MV_XOF_DEVICE_INFO_', 'MV_XOF_DEVICE_INFO', + '_MV_INTERFACE_INFO_LIST_', 'MV_INTERFACE_INFO_LIST', '_MV_INTERFACE_INFO_', 'MV_INTERFACE_INFO', + '_MV_CAML_SERIAL_PORT_LIST_', 'MV_CAML_SERIAL_PORT_LIST', '_MV_CAML_SERIAL_PORT_', 'MV_CAML_SERIAL_PORT'] diff --git a/camera/MvCameraControl_class.py b/camera/MvCameraControl_class.py new file mode 100644 index 0000000..2947b70 --- /dev/null +++ b/camera/MvCameraControl_class.py @@ -0,0 +1,1104 @@ +# -- coding: utf-8 -- + +import sys +import copy +import ctypes + +from ctypes import * + +from PixelType_header import * +from CameraParams_const import * +from CameraParams_header import * +from MvErrorDefine_const import * + +# Python3.8版本修改Dll加载策略, 默认不再搜索Path环境变量, 同时增加winmode参数以兼容旧版本 +dllname = "MvCameraControl.dll" +try: + if "winmode" in ctypes.WinDLL.__init__.__code__.co_varnames: + MvCamCtrldll = WinDLL(dllname, winmode=0) + else: + MvCamCtrldll = WinDLL(dllname) +except Exception as e: + print(f"加载MvCameraControl.dll失败: {e}") + + + +# 用于回调函数传入相机实例 +class _MV_PY_OBJECT_(Structure): + pass + + +_MV_PY_OBJECT_._fields_ = [ + ('PyObject', py_object), +] +MV_PY_OBJECT = _MV_PY_OBJECT_ + + +class MvCamera(): + + def __init__(self): + self._handle = c_void_p() # 记录当前连接设备的句柄 + self.handle = pointer(self._handle) # 创建句柄指针 + + ''' + Part1 ch: 相机的控制和取流接口 | en: Camera control and streaming + ''' + + # ch:初始化SDK | en: Initialize SDK + @staticmethod + def MV_CC_Initialize(): + MvCamCtrldll.MV_CC_Initialize.restype = c_int + # C原型:int __stdcall MV_CC_Initialize(); + return MvCamCtrldll.MV_CC_Initialize() + + # ch:反初始化SDK | en: Finalize SDK + @staticmethod + def MV_CC_Finalize(): + MvCamCtrldll.MV_CC_Finalize.restype = c_int + # C原型:int __stdcall MV_CC_Finalize(); + return MvCamCtrldll.MV_CC_Finalize() + + # ch:获取SDK版本号 | en:Get SDK Version + @staticmethod + def MV_CC_GetSDKVersion(): + MvCamCtrldll.MV_CC_GetSDKVersion.restype = c_uint + # C原型:unsigned int __stdcall MV_CC_GetSDKVersion(); + return MvCamCtrldll.MV_CC_GetSDKVersion() + + # ch:获取支持的传输层 | en:Get supported Transport Layer + @staticmethod + def MV_CC_EnumerateTls(): + MvCamCtrldll.MV_CC_EnumerateTls.restype = c_uint + # C原型:int __stdcall MV_CC_EnumerateTls(); + return MvCamCtrldll.MV_CC_EnumerateTls() + + # ch:枚举设备 | en:Enumerate Device + @staticmethod + def MV_CC_EnumDevices(nTLayerType, stDevList): + MvCamCtrldll.MV_CC_EnumDevices.argtype = (c_uint, c_void_p) + MvCamCtrldll.MV_CC_EnumDevices.restype = c_uint + # C原型:int __stdcall MV_CC_EnumDevices(unsigned int nTLayerType, MV_CC_DEVICE_INFO_LIST* pstDevList) + return MvCamCtrldll.MV_CC_EnumDevices(c_uint(nTLayerType), byref(stDevList)) + + # ch:根据厂商名字枚举设备 | en:Enumerate device according to manufacture name + @staticmethod + def MV_CC_EnumDevicesEx(nTLayerType, stDevList, strManufacturerName): + MvCamCtrldll.MV_CC_EnumDevicesEx.argtype = (c_uint, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_EnumDevicesEx.restype = c_uint + # C原型:int __stdcall MV_CC_EnumDevicesEx(IN unsigned int nTLayerType, IN OUT MV_CC_DEVICE_INFO_LIST* pstDevList, + # IN const char* strManufacturerName); + return MvCamCtrldll.MV_CC_EnumDevicesEx(c_uint(nTLayerType), byref(stDevList), + strManufacturerName.encode('ascii')) + + # ch:枚举设备扩展(可指定排序方式枚举、根据厂商名字过滤) | en: Enumerate device according to the specified ordering + @staticmethod + def MV_CC_EnumDevicesEx2(nTLayerType, stDevList, strManufacturerName, enSortMethod): + MvCamCtrldll.MV_CC_EnumDevicesEx2.argtype = (c_uint, c_void_p, c_void_p, c_uint) + MvCamCtrldll.MV_CC_EnumDevicesEx2.restype = c_uint + # C原型:int __stdcall MV_CC_EnumDevicesEx2(IN unsigned int nTLayerType, IN OUT MV_CC_DEVICE_INFO_LIST* pstDevList, + # IN const char* strManufacturerName, IN MV_SORT_METHOD enSortMethod); + return MvCamCtrldll.MV_CC_EnumDevicesEx2(c_uint(nTLayerType), byref(stDevList), + strManufacturerName.encode('ascii'), c_uint(enSortMethod)) + + # ch:设备是否可达 | en:Is the device accessible + @staticmethod + def MV_CC_IsDeviceAccessible(stDevInfo, nAccessMode): + MvCamCtrldll.MV_CC_IsDeviceAccessible.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_CC_IsDeviceAccessible.restype = c_uint + # C原型:bool __stdcall MV_CC_IsDeviceAccessible(IN MV_CC_DEVICE_INFO* pstDevInfo, IN unsigned int nAccessMode); + return MvCamCtrldll.MV_CC_IsDeviceAccessible(byref(stDevInfo), nAccessMode) + + # ch:枚举采集卡 | en:Enumerate frame grabbers + @staticmethod + def MV_CC_EnumInterfaces(nTLayerType, stInterfaceInfoList): + MvCamCtrldll.MV_CC_EnumInterfaces.argtype = (c_uint, c_void_p) + MvCamCtrldll.MV_CC_EnumInterfaces.restype = c_uint + # C原型:bool __stdcall MV_CC_EnumInterfaces(IN unsigned int nTLayerType, + # IN OUT MV_INTERFACE_INFO_LIST* pInterfaceInfoList); + return MvCamCtrldll.MV_CC_EnumInterfaces(c_uint(nTLayerType), byref(stInterfaceInfoList)) + + # ch:创建采集卡句柄 | en:Create frame grabber handle + def MV_CC_CreateInterface(self, stInterfaceInfo): + MvCamCtrldll.MV_CC_CreateInterface.argtype = c_void_p + MvCamCtrldll.MV_CC_CreateInterface.restype = c_uint + # C原型:MV_CC_CreateInterface(IN OUT void ** handle, IN MV_INTERFACE_INFO* pInterfaceInfo); + return MvCamCtrldll.MV_CC_CreateInterface(byref(self.handle), byref(stInterfaceInfo)) + + # ch:通过采集卡ID创建采集卡句柄 | en:Create frame grabber handle by frame grabber ID + def MV_CC_CreateInterfaceByID(self, InterfaceID): + MvCamCtrldll.MV_CC_CreateInterfaceByID.argtype = c_void_p + MvCamCtrldll.MV_CC_CreateInterfaceByID.restype = c_uint + # C原型:MV_CC_CreateInterfaceByID(IN OUT void ** handle, IN char* pInterfaceID); + return MvCamCtrldll.MV_CC_CreateInterfaceByID(byref(self.handle), InterfaceID.encode('ascii')) + + # ch:打开采集卡 | en:Open frame grabber + def MV_CC_OpenInterface(self): + MvCamCtrldll.MV_CC_OpenInterface.argtype = c_void_p + MvCamCtrldll.MV_CC_OpenInterface.restype = c_uint + # C原型:int __stdcall MV_CC_OpenInterface(IN void* handle, IN char* pReserved); + return MvCamCtrldll.MV_CC_OpenInterface(self.handle, 0) + + # ch:关闭采集卡 | en:Close frame grabber + def MV_CC_CloseInterface(self): + MvCamCtrldll.MV_CC_CloseInterface.argtype = c_void_p + MvCamCtrldll.MV_CC_CloseInterface.restype = c_uint + # C原型:int __stdcall MV_CC_CloseInterface(IN void* handle); + return MvCamCtrldll.MV_CC_CloseInterface(self.handle) + + # ch:销毁采集卡句柄 | en:Destroy frame grabber handle + def MV_CC_DestroyInterface(self): + MvCamCtrldll.MV_CC_DestroyInterface.argtype = c_void_p + MvCamCtrldll.MV_CC_DestroyInterface.restype = c_uint + # C原型:int __stdcall MV_CC_DestroyInterface(IN void* handle); + return MvCamCtrldll.MV_CC_DestroyInterface(self.handle) + + # ch:通过采集卡句柄枚举设备 | en:Enumerate Devices with interface handle + def MV_CC_EnumDevicesByInterface(self, stDevList): + MvCamCtrldll.MV_CC_EnumDevicesByInterface.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_EnumDevicesByInterface.restype = c_uint + # C原型:int MV_CC_EnumDevicesByInterface(IN void* handle, OUT MV_CC_DEVICE_INFO_LIST* pstDevList) + return MvCamCtrldll.MV_CC_EnumDevicesByInterface(self.handle, byref(stDevList)) + + # ch: 设置SDK日志路径 | en: Set SDK log path + def MV_CC_SetSDKLogPath(self, SDKLogPath): + MvCamCtrldll.MV_CC_SetSDKLogPath.argtype = c_void_p + MvCamCtrldll.MV_CC_SetSDKLogPath.restype = c_uint + # C原型:int MV_CC_SetSDKLogPath(IN const char * strSDKLogPath); + return MvCamCtrldll.MV_CC_SetSDKLogPath(SDKLogPath.encode('ascii')) + + # ch:创建设备句柄 | en:Create Device Handle + def MV_CC_CreateHandle(self, stDevInfo): + MvCamCtrldll.MV_CC_CreateHandle.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_CreateHandle.restype = c_uint + # C原型:int MV_CC_CreateHandle(void ** handle, MV_CC_DEVICE_INFO* pstDevInfo) + return MvCamCtrldll.MV_CC_CreateHandle(byref(self.handle), byref(stDevInfo)) + + # ch:创建句柄(不生成日志) | en:Create Device Handle without log + def MV_CC_CreateHandleWithoutLog(self, stDevInfo): + MvCamCtrldll.MV_CC_CreateHandleWithoutLog.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_CreateHandleWithoutLog.restype = c_uint + # C原型:int MV_CC_CreateHandleWithoutLog(void ** handle, MV_CC_DEVICE_INFO* pstDevInfo) + return MvCamCtrldll.MV_CC_CreateHandleWithoutLog(byref(self.handle), byref(stDevInfo)) + + # ch:销毁设备句柄 | en:Destroy Device Handle + def MV_CC_DestroyHandle(self): + MvCamCtrldll.MV_CC_DestroyHandle.argtype = c_void_p + MvCamCtrldll.MV_CC_DestroyHandle.restype = c_uint + return MvCamCtrldll.MV_CC_DestroyHandle(self.handle) + + # ch:打开设备 | en:Open Device + def MV_CC_OpenDevice(self, nAccessMode=MV_ACCESS_Exclusive, nSwitchoverKey=0): + MvCamCtrldll.MV_CC_OpenDevice.argtype = (c_void_p, c_uint32, c_uint16) + MvCamCtrldll.MV_CC_OpenDevice.restype = c_uint + # C原型:int MV_CC_OpenDevice(void* handle, unsigned int nAccessMode, unsigned short nSwitchoverKey) + return MvCamCtrldll.MV_CC_OpenDevice(self.handle, nAccessMode, nSwitchoverKey) + + # ch:关闭设备 | en:Close Device + def MV_CC_CloseDevice(self): + MvCamCtrldll.MV_CC_CloseDevice.argtype = c_void_p + MvCamCtrldll.MV_CC_CloseDevice.restype = c_uint + return MvCamCtrldll.MV_CC_CloseDevice(self.handle) + + # ch:判断设备是否处于连接状态 | en: Is The Device Connected + def MV_CC_IsDeviceConnected(self): + MvCamCtrldll.MV_CC_IsDeviceConnected.argtype = (c_void_p) + MvCamCtrldll.MV_CC_IsDeviceConnected.restype = c_bool + # C原型:bool __stdcall MV_CC_IsDeviceConnected(IN void* handle); + return MvCamCtrldll.MV_CC_IsDeviceConnected(self.handle) + + # ch:注册图像数据回调 | en:Register the image callback function + def MV_CC_RegisterImageCallBackEx(self, CallBackFun, pUser): + MvCamCtrldll.MV_CC_RegisterImageCallBackEx.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_RegisterImageCallBackEx.restype = c_uint + # C原型:int MV_CC_RegisterImageCallBackEx(void* handle, + # void(* cbOutput)(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), + # void* pUser); + return MvCamCtrldll.MV_CC_RegisterImageCallBackEx(self.handle, CallBackFun, pUser) + + # ch:注册取流回调 | en:Register the image callback function + def MV_CC_RegisterImageCallBackForRGB(self, CallBackFun, pUser): + MvCamCtrldll.MV_CC_RegisterImageCallBackForRGB.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_RegisterImageCallBackForRGB.restype = c_uint + # C原型:int MV_CC_RegisterImageCallBackForRGB(void* handle, + # void(* cbOutput)(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), + # void* pUser); + return MvCamCtrldll.MV_CC_RegisterImageCallBackForRGB(self.handle, CallBackFun, pUser) + + # ch:注册取流回调 | en:Register the image callback function + def MV_CC_RegisterImageCallBackForBGR(self, CallBackFun, pUser): + MvCamCtrldll.MV_CC_RegisterImageCallBackForBGR.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_RegisterImageCallBackForBGR.restype = c_uint + # C原型:int MV_CC_RegisterImageCallBackForBGR(void* handle, + # void(* cbOutput)(unsigned char * pData,MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser), + # void* pUser); + return MvCamCtrldll.MV_CC_RegisterImageCallBackForBGR(self.handle, CallBackFun, pUser) + + # ch:开始取流 | en:Start Grabbing + def MV_CC_StartGrabbing(self): + MvCamCtrldll.MV_CC_StartGrabbing.argtype = c_void_p + MvCamCtrldll.MV_CC_StartGrabbing.restype = c_uint + return MvCamCtrldll.MV_CC_StartGrabbing(self.handle) + + # ch:停止取流 | en:Stop Grabbing + def MV_CC_StopGrabbing(self): + MvCamCtrldll.MV_CC_StopGrabbing.argtype = c_void_p + MvCamCtrldll.MV_CC_StopGrabbing.restype = c_uint + return MvCamCtrldll.MV_CC_StopGrabbing(self.handle) + + # ch:获取一帧RGB数据,此函数为查询式获取,每次调用查询内部缓存有无数据,有数据则获取数据,无数据返回错误码 + # en:Get one frame of RGB data, this function is using query to get data query whether the internal cache has data, + # get data if there has, return error code if no data + def MV_CC_GetImageForRGB(self, pData, nDataSize, stFrameInfo, nMsec): + MvCamCtrldll.MV_CC_GetImageForRGB.argtype = (c_void_p, c_void_p, c_uint, c_void_p, c_uint) + MvCamCtrldll.MV_CC_GetImageForRGB.restype = c_uint + # C原型:int MV_CC_GetImageForRGB(IN void* handle, IN OUT unsigned char * pData , IN unsigned int nDataSize, + # IN OUT MV_FRAME_OUT_INFO_EX* pstFrameInfo, int nMsec); + return MvCamCtrldll.MV_CC_GetImageForRGB(self.handle, pData, nDataSize, byref(stFrameInfo), nMsec) + + # ch:获取一帧BGR数据,此函数为查询式获取,每次调用查询内部缓存有无数据,有数据则获取数据,无数据返回错误码 + # en:Get one frame of BGR data, this function is using query to get data query whether the internal cache has data, + # get data if there has, return error code if no data + def MV_CC_GetImageForBGR(self, pData, nDataSize, stFrameInfo, nMsec): + MvCamCtrldll.MV_CC_GetImageForBGR.argtype = (c_void_p, c_void_p, c_uint, c_void_p, c_uint) + MvCamCtrldll.MV_CC_GetImageForBGR.restype = c_uint + # C原型:int MV_CC_GetImageForBGR(IN void* handle, IN OUT unsigned char * pData , IN unsigned int nDataSize, + # IN OUT MV_FRAME_OUT_INFO_EX* pstFrameInfo, int nMsec); + return MvCamCtrldll.MV_CC_GetImageForBGR(self.handle, pData, nDataSize, byref(stFrameInfo), nMsec) + + # ch:使用内部缓存获取一帧图片(与MV_CC_Display不能同时使用) + # en:Get a frame of an image using an internal cache(Cannot be used together with the interface of MV_CC_Display) + def MV_CC_GetImageBuffer(self, stFrame, nMsec): + MvCamCtrldll.MV_CC_GetImageBuffer.argtype = (c_void_p, c_void_p, c_uint) + MvCamCtrldll.MV_CC_GetImageBuffer.restype = c_uint + # C原型:int MV_CC_GetImageBuffer(IN void* handle, OUT MV_FRAME_OUT* pstFrame, IN unsigned int nMsec); + return MvCamCtrldll.MV_CC_GetImageBuffer(self.handle, byref(stFrame), nMsec) + + # ch:释放图像缓存(与MV_CC_GetImageBuffer配套使用) + # en:Free image buffer(this interface can free image buffer, used with MV_CC_GetImageBuffer) + def MV_CC_FreeImageBuffer(self, stFrame): + MvCamCtrldll.MV_CC_FreeImageBuffer.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_FreeImageBuffer.restype = c_uint + # C原型:int MV_CC_FreeImageBuffer(IN void* handle, IN MV_FRAME_OUT* pstFrame); + return MvCamCtrldll.MV_CC_FreeImageBuffer(self.handle, byref(stFrame)) + + # ch:采用超时机制获取一帧图片,SDK内部等待直到有数据时返回 + # en:Timeout mechanism is used to get image, and the SDK waits inside until the data is returned + def MV_CC_GetOneFrameTimeout(self, pData, nDataSize, stFrameInfo, nMsec=1000): + MvCamCtrldll.MV_CC_GetOneFrameTimeout.argtype = (c_void_p, c_void_p, c_uint, c_void_p, c_uint) + MvCamCtrldll.MV_CC_GetOneFrameTimeout.restype = c_uint + # C原型:int MV_CC_GetOneFrameTimeout(void* handle, unsigned char * pData , unsigned int nDataSize, + # MV_FRAME_OUT_INFO_EX* pFrameInfo, unsigned int nMsec) + return MvCamCtrldll.MV_CC_GetOneFrameTimeout(self.handle, pData, nDataSize, byref(stFrameInfo), nMsec) + + # ch:清除取流数据缓存 | en:if Image buffers has retrieved the data,Clear them + def MV_CC_ClearImageBuffer(self): + MvCamCtrldll.MV_CC_ClearImageBuffer.argtype = (c_void_p) + MvCamCtrldll.MV_CC_ClearImageBuffer.restype = c_uint + # C原型:int MV_CC_ClearImageBuffer(IN void* handle); + return MvCamCtrldll.MV_CC_ClearImageBuffer(self.handle) + + # ch:获取当前图像缓存区的有效图像个数 | en: Get the number of valid images in the current image buffer + def MV_CC_GetValidImageNum(self, nValidImageNum): + MvCamCtrldll.MV_CC_GetValidImageNum.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetValidImageNum.restype = c_uint + # C原型:int MV_CC_GetValidImageNum(IN void* handle, OUT unsigned int *pnValidImageNum); + return MvCamCtrldll.MV_CC_GetValidImageNum(self.handle, byref(nValidImageNum)) + + # ch:显示一帧图像 + # en:Display one frame image,the maximum resolution supported is 16384 * 163840 + def MV_CC_DisplayOneFrame(self, stDisplayInfo): + MvCamCtrldll.MV_CC_DisplayOneFrame.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_DisplayOneFrame.restype = c_uint + # C原型:int MV_CC_DisplayOneFrame(IN void* handle, IN MV_DISPLAY_FRAME_INFO* pstDisplayInfo); + return MvCamCtrldll.MV_CC_DisplayOneFrame(self.handle, byref(stDisplayInfo)) + + # ch:显示一帧图像, 支持RGB8_Packed,BGR8_Packed,Mono8三种像素格式的渲染宽高大小至int类型 + # en:Get a frame of an image using an internal cache + # This API support rendering in three pixel formats:RGB8_Packed,BGR8_Packed and Mono8,width and height to int. + def MV_CC_DisplayOneFrameEx(self, hWnd, stDisplayInfo): + MvCamCtrldll.MV_CC_DisplayOneFrameEx.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_DisplayOneFrameEx.restype = c_uint + # C原型:int MV_CC_DisplayOneFrameEx(IN void* handle, IN void* hWnd, IN MV_DISPLAY_FRAME_INFO_EX* pstDisplayInfo); + return MvCamCtrldll.MV_CC_DisplayOneFrameEx(self.handle, hWnd, byref(stDisplayInfo)) + + # ch:设置SDK内部图像缓存节点个数,大于等于1,在抓图前调用 + # en:Set the number of the internal image cache nodes in SDK, Greater than or equal to 1, + # to be called before the capture + def MV_CC_SetImageNodeNum(self, nNum): + MvCamCtrldll.MV_CC_SetImageNodeNum.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_CC_SetImageNodeNum.restype = c_uint + # C原型:int MV_CC_SetImageNodeNum(IN void* handle, unsigned int nNum); + return MvCamCtrldll.MV_CC_SetImageNodeNum(self.handle, c_uint(nNum)) + + # ch:设置取流策略 | en:Set Grab Strategy + def MV_CC_SetGrabStrategy(self, enGrabStrategy): + MvCamCtrldll.MV_CC_SetGrabStrategy.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_CC_SetGrabStrategy.restype = c_uint + # C原型:int MV_CC_SetGrabStrategy(IN void* handle, IN MV_GRAB_STRATEGY enGrabStrategy); + return MvCamCtrldll.MV_CC_SetGrabStrategy(self.handle, c_uint(enGrabStrategy)) + + # ch:设置输出缓存个数(只有在MV_GrabStrategy_LatestImages策略下才有效,范围:1-ImageNodeNum) + # en:Set The Size of Output Queue(Only work under the strategy of MV_GrabStrategy_LatestImages,rang:1-ImageNodeNum) + def MV_CC_SetOutputQueueSize(self, nOutputQueueSize): + MvCamCtrldll.MV_CC_SetOutputQueueSize.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_CC_SetOutputQueueSize.restype = c_uint + # C原型:int MV_CC_SetOutputQueueSize(IN void* handle, IN unsigned int nOutputQueueSize); + return MvCamCtrldll.MV_CC_SetOutputQueueSize(self.handle, nOutputQueueSize) + + # ch:获取设备信息,取流之前调用 | en:Get device information + def MV_CC_GetDeviceInfo(self, stDevInfo): + MvCamCtrldll.MV_CC_GetDeviceInfo.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetDeviceInfo.restype = c_uint + # C原型:int MV_CC_GetDeviceInfo(IN void * handle, IN OUT MV_CC_DEVICE_INFO* pstDevInfo); + return MvCamCtrldll.MV_CC_GetDeviceInfo(self.handle, byref(stDevInfo)) + + # ch:获取各种类型的信息 | en:Get various type of information + def MV_CC_GetAllMatchInfo(self, stInfo): + MvCamCtrldll.MV_CC_GetAllMatchInfo.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetAllMatchInfo.restype = c_uint + # C原型:int MV_CC_GetAllMatchInfo(IN void* handle, IN OUT MV_ALL_MATCH_INFO* pstInfo); + return MvCamCtrldll.MV_CC_GetAllMatchInfo(self.handle, byref(stInfo)) + + ''' + Part2 ch: 相机属性万能配置接口 | en: Camera attribute nodes universal interface + ''' + # ch:获取Integer属性值 | en:Get Integer value + def MV_CC_GetIntValueEx(self, strKey, stIntValue): + MvCamCtrldll.MV_CC_GetIntValueEx.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetIntValueEx.restype = c_uint + # C原型:int MV_CC_GetIntValueEx(IN void* handle,IN const char* strKey,OUT MVCC_INTVALUE_EX *pstIntValue); + return MvCamCtrldll.MV_CC_GetIntValueEx(self.handle, strKey.encode('ascii'), byref(stIntValue)) + + # ch:设置Integer型属性值 | en:Set Integer value + def MV_CC_SetIntValueEx(self, strKey, nValue): + MvCamCtrldll.MV_CC_SetIntValueEx.argtype = (c_void_p, c_void_p, c_uint) + MvCamCtrldll.MV_CC_SetIntValueEx.restype = c_uint + # C原型:int MV_CC_SetIntValueEx(IN void* handle,IN const char* strKey,IN int64_t nValue); + return MvCamCtrldll.MV_CC_SetIntValueEx(self.handle, strKey.encode('ascii'), c_uint(nValue)) + + # ch:获取Integer型属性值 | en:Get Integer value + def MV_CC_GetIntValue(self, strKey, stIntValue): + MvCamCtrldll.MV_CC_GetIntValue.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetIntValue.restype = c_uint + # C原型:int MV_CC_GetIntValue(void* handle,char* strKey,MVCC_INTVALUE *pIntValue) + return MvCamCtrldll.MV_CC_GetIntValue(self.handle, strKey.encode('ascii'), byref(stIntValue)) + + # ch:设置Integer型属性值 | en:Set Integer value + def MV_CC_SetIntValue(self, strKey, nValue): + MvCamCtrldll.MV_CC_SetIntValue.argtype = (c_void_p, c_void_p, c_uint32) + MvCamCtrldll.MV_CC_SetIntValue.restype = c_uint + # C原型:int MV_CC_SetIntValue(void* handle, char* strKey, unsigned int nValue) + return MvCamCtrldll.MV_CC_SetIntValue(self.handle, strKey.encode('ascii'), c_uint32(nValue)) + + # ch:获取Enum属性值 | en:Get Enum value + def MV_CC_GetEnumValue(self, strKey, stEnumValue): + MvCamCtrldll.MV_CC_GetEnumValue.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetEnumValue.restype = c_uint + # C原型:int MV_CC_GetEnumValue(void* handle,char* strKey,MVCC_ENUMVALUE *pEnumValue) + return MvCamCtrldll.MV_CC_GetEnumValue(self.handle, strKey.encode('ascii'), byref(stEnumValue)) + + # ch:设置Enum型属性值 | en:Set Enum value + def MV_CC_SetEnumValue(self, strKey, nValue): + MvCamCtrldll.MV_CC_SetEnumValue.argtype = (c_void_p, c_void_p, c_uint32) + MvCamCtrldll.MV_CC_SetEnumValue.restype = c_uint + # C原型:int MV_CC_SetEnumValue(void* handle,char* strKey,unsigned int nValue) + return MvCamCtrldll.MV_CC_SetEnumValue(self.handle, strKey.encode('ascii'), c_uint32(nValue)) + + # ch:获取Enum型节点指定值的符号 | en: Get the symbolic of the specified value of the Enum type node + def MV_CC_GetEnumEntrySymbolic(self, strKey, stEnumEntry): + MvCamCtrldll.MV_CC_GetEnumEntrySymbolic.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetEnumEntrySymbolic.restype = c_uint + # C原型:int MV_CC_GetEnumEntrySymbolic(IN void* handle,IN const char* strKey, + # IN OUT MVCC_ENUMENTRY* pstEnumEntry); + return MvCamCtrldll.MV_CC_GetEnumEntrySymbolic(self.handle, strKey.encode('ascii'), byref(stEnumEntry)) + + # ch:设置Enum型属性值 | en:Set Enum value + def MV_CC_SetEnumValueByString(self, strKey, sValue): + MvCamCtrldll.MV_CC_SetEnumValueByString.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SetEnumValueByString.restype = c_uint + # C原型:int MV_CC_SetEnumValueByString(void* handle,char* strKey,char* sValue) + return MvCamCtrldll.MV_CC_SetEnumValueByString(self.handle, strKey.encode('ascii'), sValue.encode('ascii')) + + # ch:获取Float型属性值 | en:Get Float value + def MV_CC_GetFloatValue(self, strKey, stFloatValue): + MvCamCtrldll.MV_CC_GetFloatValue.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetFloatValue.restype = c_uint + # C原型:int MV_CC_GetFloatValue(void* handle,char* strKey,MVCC_FLOATVALUE *pFloatValue) + return MvCamCtrldll.MV_CC_GetFloatValue(self.handle, strKey.encode('ascii'), byref(stFloatValue)) + + # ch:设置Float型属性值 | en:Set float value + def MV_CC_SetFloatValue(self, strKey, fValue): + MvCamCtrldll.MV_CC_SetFloatValue.argtype = (c_void_p, c_void_p, c_float) + MvCamCtrldll.MV_CC_SetFloatValue.restype = c_uint + # C原型:int MV_CC_SetFloatValue(void* handle,char* strKey,float fValue) + return MvCamCtrldll.MV_CC_SetFloatValue(self.handle, strKey.encode('ascii'), c_float(fValue)) + + # ch:获取Boolean型属性值 | en:Get Boolean value + def MV_CC_GetBoolValue(self, strKey, BoolValue): + MvCamCtrldll.MV_CC_GetBoolValue.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetBoolValue.restype = c_uint + # C原型:int MV_CC_GetBoolValue(void* handle,char* strKey,bool *pBoolValue) + return MvCamCtrldll.MV_CC_GetBoolValue(self.handle, strKey.encode('ascii'), byref(BoolValue)) + + # ch:设置Boolean型属性值 | en:Set Boolean value + def MV_CC_SetBoolValue(self, strKey, bValue): + MvCamCtrldll.MV_CC_SetBoolValue.argtype = (c_void_p, c_void_p, c_bool) + MvCamCtrldll.MV_CC_SetBoolValue.restype = c_uint + # C原型:int MV_CC_SetBoolValue(void* handle,char* strKey,bool bValue) + return MvCamCtrldll.MV_CC_SetBoolValue(self.handle, strKey.encode('ascii'), bValue) + + # ch:获取String型属性值 | en:Get String value + def MV_CC_GetStringValue(self, strKey, StringValue): + MvCamCtrldll.MV_CC_GetStringValue.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetStringValue.restype = c_uint + # C原型:int MV_CC_GetStringValue(void* handle,char* strKey,MVCC_STRINGVALUE *pStringValue) + return MvCamCtrldll.MV_CC_GetStringValue(self.handle, strKey.encode('ascii'), byref(StringValue)) + + # ch:设置String型属性值 | en:Set String value + def MV_CC_SetStringValue(self, strKey, sValue): + MvCamCtrldll.MV_CC_SetStringValue.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SetStringValue.restype = c_uint + # C原型:int MV_CC_SetStringValue(void* handle,char* strKey,char * sValue) + return MvCamCtrldll.MV_CC_SetStringValue(self.handle, strKey.encode('ascii'), sValue.encode('ascii')) + + # ch:设置Command型属性值 | en:Send Command + def MV_CC_SetCommandValue(self, strKey): + MvCamCtrldll.MV_CC_SetCommandValue.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SetCommandValue.restype = c_uint + # C原型:int MV_CC_SetCommandValue(void* handle,char* strKey) + return MvCamCtrldll.MV_CC_SetCommandValue(self.handle, strKey.encode('ascii')) + + # ch:读内存 | en:Read Memory + def MV_CC_ReadMemory(self, pBuffer, nAddress, nLength): + MvCamCtrldll.MV_CC_ReadMemory.argtype = (c_void_p, c_void_p, c_uint, c_uint) + MvCamCtrldll.MV_CC_ReadMemory.restype = c_uint + # C原型:int MV_CC_ReadMemory(IN void* handle , void *pBuffer, int64_t nAddress, int64_t nLength); + return MvCamCtrldll.MV_CC_ReadMemory(self.handle, pBuffer, c_uint(nAddress), nLength) + + # ch:写内存 | en:Write Memory + def MV_CC_WriteMemory(self, pBuffer, nAddress, nLength): + MvCamCtrldll.MV_CC_WriteMemory.argtype = (c_void_p, c_void_p, c_uint, c_uint) + MvCamCtrldll.MV_CC_WriteMemory.restype = c_uint + # C原型:int MV_CC_WriteMemory(IN void* handle, const void *pBuffer, int64_t nAddress, int64_t nLength); + return MvCamCtrldll.MV_CC_WriteMemory(self.handle, pBuffer, c_uint(nAddress), nLength) + + # ch:清除GenICam节点缓存 | en:Invalidate GenICam Nodes + def MV_CC_InvalidateNodes(self): + MvCamCtrldll.MV_CC_InvalidateNodes.argtype = (c_void_p) + MvCamCtrldll.MV_CC_InvalidateNodes.restype = c_uint + # C原型:int MV_CC_InvalidateNodes(IN void* handle); + return MvCamCtrldll.MV_CC_InvalidateNodes(self.handle) + + # ch:获取设备属性树XML | en:Get camera feature tree XML + def MV_XML_GetGenICamXML(self, pData, nDataSize, pnDataLen): + MvCamCtrldll.MV_XML_GetGenICamXML.argtype = (c_void_p, c_void_p, c_uint, c_void_p) + MvCamCtrldll.MV_XML_GetGenICamXML.restype = c_uint + # C原型:int MV_XML_GetGenICamXML(IN void* handle, IN OUT unsigned char* pData, + # IN unsigned int nDataSize, OUT unsigned int* pnDataLen); + return MvCamCtrldll.MV_XML_GetGenICamXML(self.handle, pData, c_uint(nDataSize), byref(pnDataLen)) + + # ch:获得当前节点的访问模式 | en:Get Access mode of cur node + def MV_XML_GetNodeAccessMode(self, strName, penAccessMode): + MvCamCtrldll.MV_XML_GetNodeAccessMode.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_XML_GetNodeAccessMode.restype = c_uint + # C原型:int MV_XML_GetNodeAccessMode(IN void* handle, + # IN const char * strName, OUT MV_XML_AccessMode *penAccessMode); + return MvCamCtrldll.MV_XML_GetNodeAccessMode(self.handle, strName.encode('ascii'), byref(penAccessMode)) + + # ch:获得当前节点的类型 | en:Get Interface Type of cur node + def MV_XML_GetNodeInterfaceType(self, strName, penInterfaceType): + MvCamCtrldll.MV_XML_GetNodeInterfaceType.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_XML_GetNodeInterfaceType.restype = c_uint + # C原型:int MV_XML_GetNodeInterfaceType(IN void* handle, + # IN const char * strName, OUT MV_XML_InterfaceType *penInterfaceType); + return MvCamCtrldll.MV_XML_GetNodeInterfaceType(self.handle, strName.encode('ascii'), byref(penInterfaceType)) + + # ch:保存设备属性 | en:Save camera feature + def MV_CC_FeatureSave(self, strFileName): + MvCamCtrldll.MV_CC_FeatureSave.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_FeatureSave.restype = c_uint + # C原型:int MV_CC_FeatureSave(void* handle, char* pFileName) + return MvCamCtrldll.MV_CC_FeatureSave(self.handle, strFileName.encode('ascii')) + + # ch:导入设备属性 | en:Load camera feature + def MV_CC_FeatureLoad(self, strFileName): + MvCamCtrldll.MV_CC_FeatureLoad.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_FeatureLoad.restype = c_uint + # C原型:int MV_CC_FeatureLoad(void* handle, char* pFileName) + return MvCamCtrldll.MV_CC_FeatureLoad(self.handle, strFileName.encode('ascii')) + + # ch:从设备读取文件 | en:Read the file from the camera + def MV_CC_FileAccessRead(self, stFileAccess): + MvCamCtrldll.MV_CC_FileAccessRead.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_FileAccessRead.restype = c_uint + # C原型:int MV_CC_FileAccessRead(void* handle, MV_CC_FILE_ACCESS * pstFileAccess) + return MvCamCtrldll.MV_CC_FileAccessRead(self.handle, byref(stFileAccess)) + + # ch:从设备读取文件,文件是Data数据 | en:Read the file from the camera + def MV_CC_FileAccessReadEx(self, stFileAccessEx): + MvCamCtrldll.MV_CC_FileAccessReadEx.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_FileAccessReadEx.restype = c_uint + # C原型:int MV_CC_FileAccessReadEx(IN void* handle, IN OUT MV_CC_FILE_ACCESS_EX * pstFileAccessEx) + return MvCamCtrldll.MV_CC_FileAccessReadEx(self.handle, byref(stFileAccessEx)) + + # ch:将文件写入设备 | en:Write the file to camera + def MV_CC_FileAccessWrite(self, stFileAccess): + MvCamCtrldll.MV_CC_FileAccessWrite.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_FileAccessWrite.restype = c_uint + # C原型:int MV_CC_FileAccessWrite(void* handle, MV_CC_FILE_ACCESS * pstFileAccess) + return MvCamCtrldll.MV_CC_FileAccessWrite(self.handle, byref(stFileAccess)) + + # ch:将文件写入设备,参数是文件data | en:Write the file to camera + def MV_CC_FileAccessWriteEx(self, stFileAccessEx): + MvCamCtrldll.MV_CC_FileAccessWriteEx.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_FileAccessWriteEx.restype = c_uint + # C原型:int MV_CC_FileAccessWriteEx(IN void* handle, IN MV_CC_FILE_ACCESS_EX * pstFileAccessEx) + return MvCamCtrldll.MV_CC_FileAccessWriteEx(self.handle, byref(stFileAccessEx)) + + # ch:获取文件存取进度 | en:Get File Access Progress + def MV_CC_GetFileAccessProgress(self, stFileAccessProgress): + MvCamCtrldll.MV_CC_GetFileAccessProgress.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetFileAccessProgress.restype = c_uint + # C原型:int MV_CC_GetFileAccessProgress(void* handle, MV_CC_FILE_ACCESS_PROGRESS * pstFileAccessProgress) + return MvCamCtrldll.MV_CC_GetFileAccessProgress(self.handle, byref(stFileAccessProgress)) + + ''' Part3 ch: 相机升级 | en: Camera upgrade ''' + + # ch:设备本地升级 | en: Device Local Upgrade + def MV_CC_LocalUpgrade(self, strFilePathName): + MvCamCtrldll.MV_CC_LocalUpgrade.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_LocalUpgrade.restype = c_uint + # C原型:int MV_CC_LocalUpgrade(IN void* handle, const void* strFilePathName); + return MvCamCtrldll.MV_CC_LocalUpgrade(self.handle, strFilePathName.encode('ascii')) + + # ch:获取升级进度 | en: Get Upgrade Progress + def MV_CC_GetUpgradeProcess(self, nProcess): + MvCamCtrldll.MV_CC_GetUpgradeProcess.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_GetUpgradeProcess.restype = c_uint + # C原型:int MV_CC_GetUpgradeProcess(IN void* handle, unsigned int* pnProcess); + return MvCamCtrldll.MV_CC_GetUpgradeProcess(self.handle, byref(nProcess)) + + ''' Part4 ch: 注册异常回调和事件接口 | en: Enrol abnormal callbacks and event interface ''' + + # ch:注册异常消息回调 | en:Register Exception Message CallBack, call after open device + def MV_CC_RegisterExceptionCallBack(self, ExceptionCallBackFun, pUser): + MvCamCtrldll.MV_CC_RegisterExceptionCallBack.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_RegisterExceptionCallBack.restype = c_uint + # C原型:int MV_CC_RegisterExceptionCallBack(void* handle, + # void(* cbException)(unsigned int nMsgType, void* pUser),void* pUser) + return MvCamCtrldll.MV_CC_RegisterExceptionCallBack(self.handle, ExceptionCallBackFun, pUser) + + # ch:注册全部事件回调,在打开设备之后调用 | en:Register event callback, which is called after the device is opened + def MV_CC_RegisterAllEventCallBack(self, EventCallBackFun, pUser): + MvCamCtrldll.MV_CC_RegisterAllEventCallBack.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_RegisterAllEventCallBack.restype = c_uint + # C原型:int MV_CC_RegisterAllEventCallBack(void* handle, + # void(__stdcall* cbEvent)(MV_EVENT_OUT_INFO * pEventInfo, void* pUser), void* pUser); + return MvCamCtrldll.MV_CC_RegisterAllEventCallBack(self.handle, EventCallBackFun, pUser) + + # ch:注册单个事件回调,在打开设备之后调用 | en:Register single event callback, which is called after the device is opened + def MV_CC_RegisterEventCallBackEx(self, pEventName, EventCallBackFun, pUser): + MvCamCtrldll.MV_CC_RegisterEventCallBackEx.argtype = (c_void_p, c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_CC_RegisterEventCallBackEx.restype = c_uint + # C原型:int MV_CC_RegisterEventCallBackEx(void* handle, char* pEventName, + # void(* cbEvent)(MV_EVENT_OUT_INFO * pEventInfo, void* pUser),void* pUser) + return MvCamCtrldll.MV_CC_RegisterEventCallBackEx(self.handle, pEventName.encode('ascii'), EventCallBackFun, + pUser) + + # ch:开启设备指定事件 | en: Enable specified event of device + def MV_CC_EventNotificationOn(self, strEventName): + MvCamCtrldll.MV_CC_EventNotificationOn.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_EventNotificationOn.restype = c_uint + # C原型:int MV_CC_EventNotificationOn(IN void* handle, IN const char* strEventName) + return MvCamCtrldll.MV_CC_EventNotificationOn(self.handle, strEventName.encode('ascii')) + + # ch:关闭设备指定事件 | en: Disable specified event of device + def MV_CC_EventNotificationOff(self, strEventName): + MvCamCtrldll.MV_CC_EventNotificationOff.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_EventNotificationOff.restype = c_uint + # C原型:int MV_CC_EventNotificationOff(IN void* handle, IN const char* strEventName) + return MvCamCtrldll.MV_CC_EventNotificationOff(self.handle, strEventName.encode('ascii')) + + '''Part5 ch: 仅GigE设备支持的接口 | en: Only support GigE interface ''' + + # ch:设置枚举超时时间,仅支持GigE协议,范围 0-UINT_MAX | en:Set enumerate device timeout,only GigE support + # 在调用MV_CC_EnumDevices等枚举接口前使用该接口,可设置枚举GIGE设备的网卡最大超时时间(默认100ms),来加快枚举GIGE设备的速度 + # Before calling enum device interfaces,call MV_GIGE_SetEnumDevTimeout to set max timeout, + # can reduce the maximum timeout to speed up the enumeration of GigE devices + def MV_GIGE_SetEnumDevTimeout(self, nMilTimeout): + MvCamCtrldll.MV_GIGE_SetEnumDevTimeout.argtype = (c_uint) + MvCamCtrldll.MV_GIGE_SetEnumDevTimeout.restype = c_uint + # C原型:int MV_GIGE_SetEnumDevTimeout(IN unsigned int nMilTimeout) + return MvCamCtrldll.MV_GIGE_SetEnumDevTimeout(c_uint(nMilTimeout)) + + # ch:强制修改IP | en:Force IP + def MV_GIGE_ForceIpEx(self, nIP, nSubNetMask, nDefaultGateWay): + MvCamCtrldll.MV_GIGE_ForceIpEx.argtype = (c_void_p, c_uint, c_uint, c_uint) + MvCamCtrldll.MV_GIGE_ForceIpEx.restype = c_uint + # C原型:int MV_GIGE_ForceIpEx(void* handle, unsigned int nIP, + # unsigned int nSubNetMask, unsigned int nDefaultGateWay) + return MvCamCtrldll.MV_GIGE_ForceIpEx(self.handle, c_uint(nIP), c_uint(nSubNetMask), c_uint(nDefaultGateWay)) + + # ch:配置IP方式 | en: IP configuration method + def MV_GIGE_SetIpConfig(self, nType): + MvCamCtrldll.MV_GIGE_SetIpConfig.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_GIGE_SetIpConfig.restype = c_uint + # C原型:int MV_GIGE_SetIpConfig(void* handle, unsigned int nType) + return MvCamCtrldll.MV_GIGE_SetIpConfig(self.handle, c_uint(nType)) + + # ch:设置仅使用某种模式,type: MV_NET_TRANS_x,不设置时,默认优先使用driver + # en: Set to use only one mode,type: MV_NET_TRANS_x. When do not set, priority is to use driver by default + def MV_GIGE_SetNetTransMode(self, nType): + MvCamCtrldll.MV_GIGE_SetNetTransMode.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_GIGE_SetNetTransMode.restype = c_uint + # C原型:int MV_GIGE_SetNetTransMode(IN void* handle, unsigned int nType); + return MvCamCtrldll.MV_GIGE_SetNetTransMode(self.handle, c_uint(nType)) + + # ch:获取网络传输信息 | en: Get net transmission information + def MV_GIGE_GetNetTransInfo(self, pstInfo): + MvCamCtrldll.MV_GIGE_GetNetTransInfo.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_GetNetTransInfo.restype = c_uint + # C原型:int MV_GIGE_GetNetTransInfo(IN void* handle, MV_NETTRANS_INFO* pstInfo); + return MvCamCtrldll.MV_GIGE_GetNetTransInfo(self.handle, byref(pstInfo)) + + # ch:设置枚举命令的回复包类型 | en: Setting the ACK mode of devices Discovery + def MV_GIGE_SetDiscoveryMode(self, nMode): + MvCamCtrldll.MV_GIGE_SetDiscoveryMode.argtype = (c_uint) + MvCamCtrldll.MV_GIGE_SetDiscoveryMode.restype = c_uint + # C原型:int MV_GIGE_SetDiscoveryMode(unsigned int nMode); + return MvCamCtrldll.MV_GIGE_SetDiscoveryMode(c_uint(nMode)) + + # ch:设置GVSP取流超时时间| en: Set GVSP streaming timeout + def MV_GIGE_SetGvspTimeout(self, nMillisec): + MvCamCtrldll.MV_GIGE_SetGvspTimeout.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_GIGE_SetGvspTimeout.restype = c_uint + # C原型:int MV_GIGE_SetGvspTimeout(void* handle, unsigned int nMillisec); + return MvCamCtrldll.MV_GIGE_SetGvspTimeout(self.handle, c_uint(nMillisec)) + + # ch:获取GVSP取流超时时间 | en: Get GVSP streaming timeout + def MV_GIGE_GetGvspTimeout(self, pnMillisec): + MvCamCtrldll.MV_GIGE_GetGvspTimeout.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_GetGvspTimeout.restype = c_uint + # C原型:int MV_GIGE_GetGvspTimeout(IN void* handle, unsigned int* pnMillisec); + return MvCamCtrldll.MV_GIGE_GetGvspTimeout(self.handle, byref(pnMillisec)) + + # ch:设置GVCP命令超时时间| en: Set GVCP cammand timeout + def MV_GIGE_SetGvcpTimeout(self, nMillisec): + MvCamCtrldll.MV_GIGE_SetGvcpTimeout.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_GIGE_SetGvcpTimeout.restype = c_uint + # C原型:int MV_GIGE_SetGvcpTimeout(void* handle, unsigned int nMillisec); + return MvCamCtrldll.MV_GIGE_SetGvcpTimeout(self.handle, c_uint(nMillisec)) + + # ch:获取GVCP命令超时时间 | en: Get GVCP cammand timeout + def MV_GIGE_GetGvcpTimeout(self, pnMillisec): + MvCamCtrldll.MV_GIGE_GetGvcpTimeout.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_GetGvcpTimeout.restype = c_uint + # C原型:int MV_GIGE_GetGvcpTimeout(IN void* handle, unsigned int* pnMillisec); + return MvCamCtrldll.MV_GIGE_GetGvcpTimeout(self.handle, byref(pnMillisec)) + + # ch:设置重传GVCP命令次数| en: Set the number of retry GVCP cammand + def MV_GIGE_SetRetryGvcpTimes(self, nRetryGvcpTimes): + MvCamCtrldll.MV_GIGE_SetRetryGvcpTimes.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_GIGE_SetRetryGvcpTimes.restype = c_uint + # C原型:int MV_GIGE_SetRetryGvcpTimes(IN void* handle, unsigned int nRetryGvcpTimes); + return MvCamCtrldll.MV_GIGE_SetRetryGvcpTimes(self.handle, c_uint(nRetryGvcpTimes)) + + # ch:获取重传GVCP命令次数| en: Get the number of retry GVCP cammand + def MV_GIGE_GetRetryGvcpTimes(self, pnRetryGvcpTimes): + MvCamCtrldll.MV_GIGE_GetRetryGvcpTimes.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_GetRetryGvcpTimes.restype = c_uint + # C原型:int MV_GIGE_GetRetryGvcpTimes(IN void* handle, unsigned int* pnRetryGvcpTimes); + return MvCamCtrldll.MV_GIGE_GetRetryGvcpTimes(self.handle, byref(pnRetryGvcpTimes)) + + # ch:获取网络最佳包大小 | en:Get the optimal Packet Size, Only support GigE Camera + def MV_CC_GetOptimalPacketSize(self): + MvCamCtrldll.MV_CC_GetOptimalPacketSize.argtype = (c_void_p) + MvCamCtrldll.MV_CC_GetOptimalPacketSize.restype = c_uint + # C原型:int __stdcall MV_CC_GetOptimalPacketSize(void* handle); + return MvCamCtrldll.MV_CC_GetOptimalPacketSize(self.handle) + + # ch:设置是否打开重发包支持,及重发包设置| en: Set whethe to enable resend, and set resend + def MV_GIGE_SetResend(self, bEnable, nMaxResendPercent=10, nResendTimeout=50): + MvCamCtrldll.MV_GIGE_SetResend.argtype = (c_void_p, c_uint, c_uint, c_uint) + MvCamCtrldll.MV_GIGE_SetResend.restype = c_uint + # C原型:int MV_GIGE_SetResend(void* handle, unsigned int bEnable, + # unsigned int nMaxResendPercent = 10, unsigned int nResendTimeout = 50); + return MvCamCtrldll.MV_GIGE_SetResend(self.handle, c_uint(bEnable), c_uint(nMaxResendPercent), + c_uint(nResendTimeout)) + + # ch:设置重传命令最大尝试次数 | en: set the max resend retry times + def MV_GIGE_SetResendMaxRetryTimes(self, nRetryTimes): + MvCamCtrldll.MV_GIGE_SetResendMaxRetryTimes.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_GIGE_SetResendMaxRetryTimes.restype = c_uint + # C原型:int MV_GIGE_SetResendMaxRetryTimes(void* handle, unsigned int nRetryTimes); + return MvCamCtrldll.MV_GIGE_SetResendMaxRetryTimes(self.handle, c_uint(nRetryTimes)) + + # ch:获取重传命令最大尝试次数 | en: get the max resend retry times + def MV_GIGE_GetResendMaxRetryTimes(self, nRetryTimes): + MvCamCtrldll.MV_GIGE_GetResendMaxRetryTimes.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_GetResendMaxRetryTimes.restype = c_uint + # C原型:int MV_GIGE_GetResendMaxRetryTimes(void* handle, unsigned int* pnRetryTimes); + return MvCamCtrldll.MV_GIGE_GetResendMaxRetryTimes(self.handle, byref(nRetryTimes)) + + # ch:设置同一重传包多次请求之间的时间间隔 | en: set time interval between same resend requests + def MV_GIGE_SetResendTimeInterval(self, nMillisec): + MvCamCtrldll.MV_GIGE_SetResendTimeInterval.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_GIGE_SetResendTimeInterval.restype = c_uint + # C原型:int MV_GIGE_SetResendTimeInterval(void* handle, unsigned int nMillisec) + return MvCamCtrldll.MV_GIGE_SetResendTimeInterval(self.handle, c_uint(nMillisec)) + + # ch:获取同一重传包多次请求之间的时间间隔 | en: get time interval between same resend requests + def MV_GIGE_GetResendTimeInterval(self, nMillisec): + MvCamCtrldll.MV_GIGE_GetResendTimeInterval.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_GetResendTimeInterval.restype = c_uint + # C原型:int MV_GIGE_GetResendTimeInterval(void* handle, unsigned int* pnMillisec) + return MvCamCtrldll.MV_GIGE_GetResendTimeInterval(self.handle, byref(nMillisec)) + + # ch:设置传输模式,可以为单播模式、组播模式等 |en:Set transmission type,Unicast or Multicast + def MV_GIGE_SetTransmissionType(self, stTransmissionType): + MvCamCtrldll.MV_GIGE_SetTransmissionType.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_SetTransmissionType.restype = c_uint + # C原型:int MV_GIGE_SetTransmissionType(void* handle, MV_TRANSMISSION_TYPE * pstTransmissionType) + return MvCamCtrldll.MV_GIGE_SetTransmissionType(self.handle, byref(stTransmissionType)) + + # ch:发出动作命令 | en:Issue Action Command + def MV_GIGE_IssueActionCommand(self, pstActionCmdInfo, pstActionCmdResults): + MvCamCtrldll.MV_GIGE_IssueActionCommand.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_IssueActionCommand.restype = c_uint + # C原型:int MV_GIGE_IssueActionCommand(IN MV_ACTION_CMD_INFO* pstActionCmdInfo, + # OUT MV_ACTION_CMD_RESULT_LIST* pstActionCmdResults); + return MvCamCtrldll.MV_GIGE_IssueActionCommand(byref(pstActionCmdInfo), byref(pstActionCmdResults)) + + # ch:获取组播状态 | en:Get Multicast Status + def MV_GIGE_GetMulticastStatus(self, pstDevInfo, pbStatus): + MvCamCtrldll.MV_GIGE_GetMulticastStatus.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_GIGE_GetMulticastStatus.restype = c_uint + # C原型:int MV_GIGE_GetMulticastStatus(IN MV_CC_DEVICE_INFO* pstDevInfo, OUT bool* pbStatus); + return MvCamCtrldll.MV_GIGE_GetMulticastStatus(byref(pstDevInfo), byref(pbStatus)) + + ''' Part6 ch: 仅CameraLink 设备支持的接口 | en: Only support camlink device interface''' + + # ch:获取串口信息列表| en: Get serial port information list + def MV_CAML_GetSerialPortList(self, stSerialPortList): + MvCamCtrldll.MV_CAML_GetSerialPortList.argtype = c_void_p + MvCamCtrldll.MV_CAML_GetSerialPortList.restype = c_uint + # C原型:int __stdcall MV_CAML_GetSerialPortList(IN OUT MV_CAML_SERIAL_PORT_LIST* pstSerialPortList); + return MvCamCtrldll.MV_CAML_GetSerialPortList(byref(stSerialPortList)) + + # ch:设置指定串口,camera link仅在该串口下枚举| en: Set the specified enumeration serial port + def MV_CAML_SetEnumSerialPorts(self, stSerialPortList): + MvCamCtrldll.MV_CAML_SetEnumSerialPorts.argtype = c_void_p + MvCamCtrldll.MV_CAML_SetEnumSerialPorts.restype = c_uint + # C原型:int __stdcall MV_CAML_SetEnumSerialPorts(IN MV_CAML_SERIAL_PORT_LIST* pstSerialPortList); + return MvCamCtrldll.MV_CAML_SetEnumSerialPorts(byref(stSerialPortList)) + + # ch:设置设备波特率| en: Set device bauderate using one of the CL_BAUDRATE_XXXX value + def MV_CAML_SetDeviceBaudrate(self, nBaudrate): + MvCamCtrldll.MV_CAML_SetDeviceBaudrate.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_CAML_SetDeviceBaudrate.restype = c_uint + # C原型:int MV_CAML_SetDeviceBaudrate(IN void* handle, unsigned int nBaudrate); + return MvCamCtrldll.MV_CAML_SetDeviceBaudrate(self.handle, c_uint(nBaudrate)) + + # ch:获取设备波特率 | en:Returns the current device bauderate, using one of the CL_BAUDRATE_XXXX value + def MV_CAML_GetDeviceBaudrate(self, pnCurrentBaudrate): + MvCamCtrldll.MV_CAML_GetDeviceBaudrate.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CAML_GetDeviceBaudrate.restype = c_uint + # C原型:int MV_CAML_GetDeviceBaudrate(IN void* handle,unsigned int* pnCurrentBaudrate); + return MvCamCtrldll.MV_CAML_GetDeviceBaudrate(self.handle, byref(pnCurrentBaudrate)) + + # ch:获取设备与主机间连接支持的波特率 | en:Returns supported bauderates of the combined device and host interface + def MV_CAML_GetSupportBaudrates(self, pnBaudrateAblity): + MvCamCtrldll.MV_CAML_GetSupportBaudrates.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CAML_GetSupportBaudrates.restype = c_uint + # C原型:int MV_CAML_GetSupportBaudrates(IN void* handle,unsigned int* pnBaudrateAblity); + return MvCamCtrldll.MV_CAML_GetSupportBaudrates(self.handle, byref(pnBaudrateAblity)) + + # ch:设置串口操作等待时长 | en: Sets the timeout for operations on the serial port + def MV_CAML_SetGenCPTimeOut(self, nMillisec): + MvCamCtrldll.MV_CAML_SetGenCPTimeOut.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_CAML_SetGenCPTimeOut.restype = c_uint + # C原型:int MV_CAML_SetGenCPTimeOut(IN void* handle, unsigned int nMillisec); + return MvCamCtrldll.MV_CAML_SetGenCPTimeOut(self.handle, c_uint(nMillisec)) + + ''' Part7 ch: 仅U3V设备支持的接口 | en: Only support U3V device interface ''' + + # ch:设置U3V的传输包大小 | en: Set transfer size of U3V device + def MV_USB_SetTransferSize(self, nTransferSize): + MvCamCtrldll.MV_USB_SetTransferSize.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_USB_SetTransferSize.restype = c_uint + # C原型:int MV_USB_SetTransferSize(IN void* handle, unsigned int nTransferSize); + return MvCamCtrldll.MV_USB_SetTransferSize(self.handle, c_uint(nTransferSize)) + + # ch:获取U3V的传输包大小 | en:Get transfer size of U3V device + def MV_USB_GetTransferSize(self, pnTransferSize): + MvCamCtrldll.MV_USB_GetTransferSize.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_USB_GetTransferSize.restype = c_uint + # C原型:int MV_USB_GetTransferSize(IN void* handle, unsigned int* pnTransferSize); + return MvCamCtrldll.MV_USB_GetTransferSize(self.handle, byref(pnTransferSize)) + + # ch:设置U3V的传输通道个数 | en: Set transfer ways of U3V device + def MV_USB_SetTransferWays(self, nTransferWays): + MvCamCtrldll.MV_USB_SetTransferWays.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_USB_SetTransferWays.restype = c_uint + # C原型:int MV_USB_SetTransferWays(IN void* handle, unsigned int nTransferWays); + return MvCamCtrldll.MV_USB_SetTransferWays(self.handle, c_uint(nTransferWays)) + + # ch:获取U3V的传输通道个数 | en:Get transfer ways of U3V device + def MV_USB_GetTransferWays(self, pnTransferWays): + MvCamCtrldll.MV_USB_GetTransferWays.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_USB_GetTransferWays.restype = c_uint + # C原型:int MV_USB_GetTransferWays(IN void* handle, unsigned int* pnTransferWays); + return MvCamCtrldll.MV_USB_GetTransferWays(self.handle, byref(pnTransferWays)) + + # ch:注册流异常消息回调,在打开设备之后调用(只支持U3V相机) + # en: Register the stream exception callback, which is called after the device is opened. + # Only the U3V camera is supported + def MV_USB_RegisterStreamExceptionCallBack(self, CallBackFun, pUser): + MvCamCtrldll.MV_USB_RegisterStreamExceptionCallBack.argtype = (c_void_p, c_void_p, c_void_p) + MvCamCtrldll.MV_USB_RegisterStreamExceptionCallBack.restype = c_uint + # C原型:int MV_USB_RegisterStreamExceptionCallBack( + # void* handle, + # void(__stdcall* cbException)(MV_CC_STREAM_EXCEPTION_TYPE enExceptionType, void* pUser), + # void* pUser); + return MvCamCtrldll.MV_USB_RegisterStreamExceptionCallBack(self.handle, CallBackFun, pUser) + + # ch:设置U3V的事件缓存节点个数 | en: Set the number of U3V device event cache nodes + def MV_USB_SetEventNodeNum(self, nEventNodeNum): + MvCamCtrldll.MV_USB_SetEventNodeNum.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_USB_SetEventNodeNum.restype = c_uint + # C原型:int MV_USB_SetEventNodeNum(IN void* handle, unsigned int nEventNodeNum) + return MvCamCtrldll.MV_USB_SetEventNodeNum(self.handle, c_uint(nEventNodeNum)) + + # ch:设置U3V的同步读写超时时间,范围为0 ~ UINT_MAX(最小值包含0,最大值根据操作系统位数决定) | en: Set Sync timeout + def MV_USB_SetSyncTimeOut(self, nMills): + MvCamCtrldll.MV_USB_SetSyncTimeOut.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_USB_SetSyncTimeOut.restype = c_uint + # C原型:int MV_USB_SetSyncTimeOut(IN void* handle, unsigned int nMills); + return MvCamCtrldll.MV_USB_SetSyncTimeOut(self.handle, c_uint(nMills)) + + # ch:获取U3V相机同步读写超时时间 | en: Get Sync timeout + def MV_USB_GetSyncTimeOut(self, nMills): + MvCamCtrldll.MV_USB_GetSyncTimeOut.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_USB_GetSyncTimeOut.restype = c_uint + # C原型:int MV_USB_GetSyncTimeOut(IN void* handle, unsigned int* pnMills); + return MvCamCtrldll.MV_USB_GetSyncTimeOut(self.handle, byref(nMills)) + + ''' Part8 ch: GenTL相关接口 | en: GenTL related interface ''' + + # ch:通过GenTL枚举Interfaces | en:Enumerate Interfaces with GenTL + def MV_CC_EnumInterfacesByGenTL(stIFList, strGenTLPath): + MvCamCtrldll.MV_CC_EnumInterfacesByGenTL.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_EnumInterfacesByGenTL.restype = c_uint + # C原型:int MV_CC_EnumInterfacesByGenTL(IN OUT MV_GENTL_IF_INFO_LIST* pstIFList, IN const char * strGenTLPath); + return MvCamCtrldll.MV_CC_EnumInterfacesByGenTL(byref(stIFList), strGenTLPath.encode('ascii')) + + # ch:通过GenTL Interface枚举设备 | en:Enumerate Devices with GenTL interface + def MV_CC_EnumDevicesByGenTL(stIFInfo, stDevList): + MvCamCtrldll.MV_CC_EnumDevicesByGenTL.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_EnumDevicesByGenTL.restype = c_uint + # C原型:int MV_CC_EnumDevicesByGenTL(IN MV_GENTL_IF_INFO* pstIFInfo, IN OUT MV_GENTL_DEV_INFO_LIST* pstDevList); + return MvCamCtrldll.MV_CC_EnumDevicesByGenTL(stIFInfo, byref(stDevList)) + + # ch:卸载cti库 | en: Unload cti library + @staticmethod + def MV_CC_UnloadGenTLLibrary(GenTLPath): + MvCamCtrldll.MV_CC_UnloadGenTLLibrary.argtype = (c_void_p) + MvCamCtrldll.MV_CC_UnloadGenTLLibrary.restype = c_uint + # C原型:int MV_CC_UnloadGenTLLibrary(IN const char * pGenTLPath); + return MvCamCtrldll.MV_CC_UnloadGenTLLibrary(GenTLPath.encode('ascii')) + + # ch:通过GenTL设备信息创建设备句柄 | en:Create Device Handle with GenTL Device Info + def MV_CC_CreateHandleByGenTL(self, stDevInfo): + MvCamCtrldll.MV_CC_CreateHandleByGenTL.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_CreateHandleByGenTL.restype = c_uint + # C原型:int MV_CC_CreateHandleByGenTL(OUT void ** handle, IN const MV_GENTL_DEV_INFO* pstDevInfo); + return MvCamCtrldll.MV_CC_CreateHandleByGenTL(byref(self.handle), byref(stDevInfo)) + + ''' Part9 ch: 图像保存、格式转换等相关接口 | en: Related image save and format convert interface ''' + + # ch:保存图片,支持Bmp和Jpeg | en:Save image, support Bmp and Jpeg. + def MV_CC_SaveImageEx2(self, stSaveParam): + MvCamCtrldll.MV_CC_SaveImageEx2.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SaveImageEx2.restype = c_uint + # C原型:int MV_CC_SaveImageEx2(void* handle, MV_SAVE_IMAGE_PARAM_EX* pSaveParam) + return MvCamCtrldll.MV_CC_SaveImageEx2(self.handle, byref(stSaveParam)) + + # ch:保存图片,支持Bmp和Jpeg MV_CC_SaveImageEx3比MV_CC_SaveImageEx2 支持图像大小到Int + # en:Save image, support Bmp and Jpeg.this API support the parameter nWidth nHeight to unsigned int. + def MV_CC_SaveImageEx3(self, stSaveParam): + MvCamCtrldll.MV_CC_SaveImageEx3.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SaveImageEx3.restype = c_uint + # C原型:int MV_CC_SaveImageEx3(IN void* handle, MV_SAVE_IMAGE_PARAM_EX3* pstSaveParam) + return MvCamCtrldll.MV_CC_SaveImageEx3(self.handle, byref(stSaveParam)) + + # ch:保存图像到文件 | en:Save the image file + def MV_CC_SaveImageToFile(self, stSaveFileParam): + MvCamCtrldll.MV_CC_SaveImageToFile.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SaveImageToFile.restype = c_uint + # C原型:int MV_CC_SaveImageToFile(IN void* handle, MV_SAVE_IMG_TO_FILE_PARAM* pstSaveFileParam); + return MvCamCtrldll.MV_CC_SaveImageToFile(self.handle, byref(stSaveFileParam)) + + # ch:保存图像到文件,支持保存的图像长乘宽乘像素大小至UINT_MAX, 其中MV_CC_SaveImageToFile支持最大至USHRT_MAX + # en:Save the image file,Comparing with the API MV_CC_SaveImageToFile, + # this API support the parameter nWidth * nHeight * pixelsize to UINT_MAX. + def MV_CC_SaveImageToFileEx(self, stSaveFileParam): + MvCamCtrldll.MV_CC_SaveImageToFileEx.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SaveImageToFileEx.restype = c_uint + # C原型:int MV_CC_SaveImageToFileEx(IN void* handle, MV_SAVE_IMAGE_TO_FILE_PARAM_EX* pstSaveFileParam); + return MvCamCtrldll.MV_CC_SaveImageToFileEx(self.handle, byref(stSaveFileParam)) + + # ch:保存3D点云数据,支持PLY、CSV和OBJ三种格式 | en:Save 3D point data, support PLY、CSV and OBJ + def MV_CC_SavePointCloudData(self, stPointDataParam): + MvCamCtrldll.MV_CC_SavePointCloudData.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SavePointCloudData.restype = c_uint + # C原型:int MV_CC_SavePointCloudData(IN void* handle, MV_SAVE_POINT_CLOUD_PARAM* pstPointDataParam); + return MvCamCtrldll.MV_CC_SavePointCloudData(self.handle, byref(stPointDataParam)) + + # ch:图像旋转 | en: Rotate image + def MV_CC_RotateImage(self, stRotateParam): + MvCamCtrldll.MV_CC_RotateImage.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_RotateImage.restype = c_uint + # C原型:int MV_CC_RotateImage(IN void* handle, IN OUT MV_CC_ROTATE_IMAGE_PARAM* pstRotateParam); + return MvCamCtrldll.MV_CC_RotateImage(self.handle, byref(stRotateParam)) + + # ch:图像翻转 | en:Flip image + def MV_CC_FlipImage(self, stFlipParam): + MvCamCtrldll.MV_CC_FlipImage.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_FlipImage.restype = c_uint + # C原型:int MV_CC_FlipImage(IN void* handle, IN OUT MV_CC_FLIP_IMAGE_PARAM* pstFlipParam); + return MvCamCtrldll.MV_CC_FlipImage(self.handle, byref(stFlipParam)) + + # ch:像素格式转换 | en:Pixel format conversion + def MV_CC_ConvertPixelType(self, stConvertParam): + MvCamCtrldll.MV_CC_ConvertPixelType.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_ConvertPixelType.restype = c_uint + # C原型:int MV_CC_ConvertPixelType(void* handle, MV_CC_PIXEL_CONVERT_PARAM* pstCvtParam) + return MvCamCtrldll.MV_CC_ConvertPixelType(self.handle, byref(stConvertParam)) + + # ch:像素格式转换,接口支持转换的图像长乘宽乘像素大小至UINT_MAX + # en:Pixel format conversion,comparing with the API MV_CC_ConvertPixelType, + # this API support the parameter nWidth * nHeight * pixelsize to UINT_MAX. + def MV_CC_ConvertPixelTypeEx(self, stConvertParam): + MvCamCtrldll.MV_CC_ConvertPixelTypeEx.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_ConvertPixelTypeEx.restype = c_uint + # C原型:int MV_CC_ConvertPixelTypeEx(IN void* handle, IN OUT MV_CC_PIXEL_CONVERT_PARAM_EX* pstCvtParam); + return MvCamCtrldll.MV_CC_ConvertPixelTypeEx(self.handle, byref(stConvertParam)) + + # ch:插值算法类型设置 | en:Interpolation algorithm type setting + def MV_CC_SetBayerCvtQuality(self, nBayerCvtQuality): + MvCamCtrldll.MV_CC_SetBayerCvtQuality.argtype = (c_void_p, c_uint) + MvCamCtrldll.MV_CC_SetBayerCvtQuality.restype = c_uint + # C原型:int MV_CC_SetBayerCvtQuality(IN void* handle, IN unsigned int nBayerCvtQuality); + return MvCamCtrldll.MV_CC_SetBayerCvtQuality(self.handle, c_uint(nBayerCvtQuality)) + + # ch:插值算法平滑使能设置 | en: Filter type of the bell interpolation quality algorithm setting + def MV_CC_SetBayerFilterEnable(self, bFilterEnable): + MvCamCtrldll.MV_CC_SetBayerFilterEnable.argtype = (c_void_p, c_bool) + MvCamCtrldll.MV_CC_SetBayerFilterEnable.restype = c_uint + # C原型:int __stdcall MV_CC_SetBayerFilterEnable(IN void* handle, IN bool bFilterEnable); + return MvCamCtrldll.MV_CC_SetBayerFilterEnable(self.handle, c_bool(bFilterEnable)) + + # ch:设置Bayer格式的Gamma值 | en: Set Gamma value + def MV_CC_SetBayerGammaValue(self, fBayerGammaValue): + MvCamCtrldll.MV_CC_SetBayerGammaValue.argtype = (c_void_p, c_float) + MvCamCtrldll.MV_CC_SetBayerGammaValue.restype = c_uint + # C原型:int __stdcall MV_CC_SetBayerGammaValue(IN void* handle, IN float fBayerGammaValue); + return MvCamCtrldll.MV_CC_SetBayerGammaValue(self.handle, c_float(fBayerGammaValue)) + + # ch:设置Mono8/bayer格式的Gamma值 | en:Set Gamma value + def MV_CC_SetGammaValue(self, enSrcPixelType, fGammaValue): + MvCamCtrldll.MV_CC_SetGammaValue.argtype = (c_void_p, c_int, c_float) + MvCamCtrldll.MV_CC_SetGammaValue.restype = c_uint + # C原型:int MV_CC_SetGammaValue(IN void* handle, enum MvGvspPixelType enSrcPixelType, IN float fGammaValue); + return MvCamCtrldll.MV_CC_SetGammaValue(self.handle, c_int(enSrcPixelType), c_float(fGammaValue)) + + # ch:设置Bayer格式的Gamma信息 | en: Set Gamma param + def MV_CC_SetBayerGammaParam(self, stGammaParam): + MvCamCtrldll.MV_CC_SetBayerGammaParam.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SetBayerGammaParam.restype = c_uint + # C原型:int __stdcall MV_CC_SetBayerGammaParam(IN void* handle, IN MV_CC_GAMMA_PARAM* pstGammaParam); + return MvCamCtrldll.MV_CC_SetBayerGammaParam(self.handle, byref(stGammaParam)) + + # ch:设置Bayer格式的CCM使能和矩阵,量化系数默认1024 | en:Set CCM param,Scale default 1024 + def MV_CC_SetBayerCCMParam(self, stCCMParam): + MvCamCtrldll.MV_CC_SetBayerCCMParam.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SetBayerCCMParam.restype = c_uint + # C原型:int __stdcall MV_CC_SetBayerCCMParam(IN void* handle, IN MV_CC_CCM_PARAM* pstCCMParam); + return MvCamCtrldll.MV_CC_SetBayerCCMParam(self.handle, byref(stCCMParam)) + + # ch:设置Bayer格式的CCM使能和矩阵 | en:Set CCM param + def MV_CC_SetBayerCCMParamEx(self, stCCMParam): + MvCamCtrldll.MV_CC_SetBayerCCMParamEx.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_SetBayerCCMParamEx.restype = c_uint + # C原型:int __stdcall MV_CC_SetBayerCCMParamEx(IN void* handle, IN MV_CC_CCM_PARAM_EX* pstCCMParam); + return MvCamCtrldll.MV_CC_SetBayerCCMParamEx(self.handle, byref(stCCMParam)) + + # ch:图像对比度调节 | en:Adjust image contrast + def MV_CC_ImageContrast(self, stConstrastParam): + MvCamCtrldll.MV_CC_ImageContrast.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_ImageContrast.restype = c_uint + # C原型:int __stdcall MV_CC_ImageContrast(IN void* handle, IN OUT MV_CC_CONTRAST_PARAM* pstContrastParam); + return MvCamCtrldll.MV_CC_ImageContrast(self.handle, byref(stConstrastParam)) + + # ch:无损解码 | en:High Bandwidth Decode + def MV_CC_HBDecode(self, stDecodeParam): + MvCamCtrldll.MV_CC_HB_Decode.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_HB_Decode.restype = c_uint + # C原型:int __stdcall MV_CC_HB_Decode(IN void* handle, IN OUT MV_CC_HB_DECODE_PARAM* pstDecodeParam); + return MvCamCtrldll.MV_CC_HB_Decode(self.handle, byref(stDecodeParam)) + + # ch:在图像上绘制矩形框辅助线 | en:Draw Rect Auxiliary Line + def MV_CC_DrawRect(self, stRectInfo): + MvCamCtrldll.MV_CC_DrawRect.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_DrawRect.restype = c_uint + # C原型: int __stdcall MV_CC_DrawRect(IN void* handle, IN MVCC_RECT_INFO* pRectInfo); + return MvCamCtrldll.MV_CC_DrawRect(self.handle, byref(stRectInfo)) + + # ch:在图像上绘制圆形辅助线 | en:Draw Circle Auxiliary Line + def MV_CC_DrawCircle(self, stCircleInfo): + MvCamCtrldll.MV_CC_DrawCircle.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_DrawCircle.restype = c_uint + # C原型: int __stdcall MV_CC_DrawCircle(IN void* handle, IN MVCC_CIRCLE_INFO* pCircleInfo); + return MvCamCtrldll.MV_CC_DrawCircle(self.handle, byref(stCircleInfo)) + + # ch:在图像上绘制线条 | en:Draw Line Auxiliary Line + def MV_CC_DrawLines(self, stLineInfo): + MvCamCtrldll.MV_CC_DrawLines.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_DrawLines.restype = c_uint + # C原型: int __stdcall MV_CC_DrawLines(IN void* handle, IN MVCC_LINES_INFO* pLinesInfo); + return MvCamCtrldll.MV_CC_DrawLines(self.handle, byref(stLineInfo)) + + # ch:开始录像 | en:Start Record + def MV_CC_StartRecord(self, stRecordParam): + MvCamCtrldll.MV_CC_StartRecord.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_StartRecord.restype = c_uint + # C原型:int __stdcall MV_CC_StartRecord(IN void* handle, IN MV_CC_RECORD_PARAM* pstRecordParam); + return MvCamCtrldll.MV_CC_StartRecord(self.handle, byref(stRecordParam)) + + # ch: 输入录像数据 | en:Input RAW data to Record + def MV_CC_InputOneFrame(self, stInputFrameInfo): + MvCamCtrldll.MV_CC_InputOneFrame.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_InputOneFrame.restype = c_uint + # C原型:int __stdcall MV_CC_InputOneFrame(IN void* handle, IN MV_CC_INPUT_FRAME_INFO * pstInputFrameInfo); + return MvCamCtrldll.MV_CC_InputOneFrame(self.handle, byref(stInputFrameInfo)) + + # ch:停止录像 | en:Stop Record + def MV_CC_StopRecord(self): + MvCamCtrldll.MV_CC_StopRecord.argtype = (c_void_p) + MvCamCtrldll.MV_CC_StopRecord.restype = c_uint + # C原型:int __stdcall MV_CC_StopRecord(IN void* handle); + return MvCamCtrldll.MV_CC_StopRecord(self.handle) + + # ch:打开获取或设置相机参数的GUI界面 | en:Open the GUI interface for getting or setting camera parameters + def MV_CC_OpenParamsGUI(self): + MvCamCtrldll.MV_CC_OpenParamsGUI.argtype = (c_void_p) + MvCamCtrldll.MV_CC_OpenParamsGUI.restype = c_uint + # C原型: __stdcall MV_CC_OpenParamsGUI(IN void* handle); + return MvCamCtrldll.MV_CC_OpenParamsGUI(self.handle) + + # ch:重构图像(用于分时曝光功能) | en:Reconstruct Image(For time-division exposure function) + def MV_CC_ReconstructImage(self, stReconstructParam): + MvCamCtrldll.MV_CC_ReconstructImage.argtype = (c_void_p, c_void_p) + MvCamCtrldll.MV_CC_ReconstructImage.restype = c_uint + # C原型:int __stdcall MV_CC_ReconstructImage(IN void* handle, IN OUT MV_RECONSTRUCT_IMAGE_PARAM* pstReconstructParam); + return MvCamCtrldll.MV_CC_ReconstructImage(self.handle, byref(stReconstructParam)) diff --git a/camera/MvErrorDefine_const.py b/camera/MvErrorDefine_const.py new file mode 100644 index 0000000..f1d9179 --- /dev/null +++ b/camera/MvErrorDefine_const.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +MV_OK = 0x00000000 # < \~chinese 成功,无错误 \~english Successed, no error + +# 通用错误码定义:范围0x80000000-0x800000FF +MV_E_HANDLE = 0x80000000 # < \~chinese 错误或无效的句柄 \~english Error or invalid handle +MV_E_SUPPORT = 0x80000001 # < \~chinese 不支持的功能 \~english Not supported function +MV_E_BUFOVER = 0x80000002 # < \~chinese 缓存已满 \~english Buffer overflow +MV_E_CALLORDER = 0x80000003 # < \~chinese 函数调用顺序错误 \~english Function calling order error +MV_E_PARAMETER = 0x80000004 # < \~chinese 错误的参数 \~english Incorrect parameter +MV_E_RESOURCE = 0x80000006 # < \~chinese 资源申请失败 \~english Applying resource failed +MV_E_NODATA = 0x80000007 # < \~chinese 无数据 \~english No data +MV_E_PRECONDITION = 0x80000008 # < \~chinese 前置条件有误,或运行环境已发生变化 \~english Precondition error, or running environment changed +MV_E_VERSION = 0x80000009 # < \~chinese 版本不匹配 \~english Version mismatches +MV_E_NOENOUGH_BUF = 0x8000000A # < \~chinese 传入的内存空间不足 \~english Insufficient memory +MV_E_ABNORMAL_IMAGE = 0x8000000B # < \~chinese 异常图像,可能是丢包导致图像不完整 \~english Abnormal image, maybe incomplete image because of lost packet +MV_E_LOAD_LIBRARY = 0x8000000C # < \~chinese 动态导入DLL失败 \~english Load library failed +MV_E_NOOUTBUF = 0x8000000D # < \~chinese 没有可输出的缓存 \~english No Avaliable Buffer +MV_E_ENCRYPT = 0x8000000E # < \~chinese 加密错误 \~english Encryption error +MV_E_OPENFILE = 0x8000000F # < \~chinese 打开文件出现错误 \~english open file error +MV_E_BUF_IN_USE = 0x80000010 # < \~chinese 缓存地址已使用 \~english Buffer already in use +MV_E_BUF_INVALID = 0x80000011 # < \~chinese 无效的缓存地址 \~english Buffer address invalid +MV_E_NOALIGN_BUF = 0x80000012 # < \~chinese 缓存对齐异常 \~english Buffer alignmenterror error +MV_E_NOENOUGH_BUF_NUM = 0x80000013 # < \~chinese 缓存个数不足 \~english Insufficient cache count +MV_E_PORT_IN_USE = 0x80000014 # < \~chinese 串口被占用 \~english Port is in use +MV_E_IMAGE_DECODEC = 0x80000015 # < \~chinese 解码错误(SDK校验图像异常)\~english Decoding error (SDK verification image exception) +MV_E_UNKNOW = 0x800000FF # < \~chinese 未知的错误 \~english Unknown error + +# GenICam系列错误:范围0x80000100-0x800001FF +MV_E_GC_GENERIC = 0x80000100 # < \~chinese 通用错误 \~english General error +MV_E_GC_ARGUMENT = 0x80000101 # < \~chinese 参数非法 \~english Illegal parameters +MV_E_GC_RANGE = 0x80000102 # < \~chinese 值超出范围 \~english The value is out of range +MV_E_GC_PROPERTY = 0x80000103 # < \~chinese 属性 \~english Property +MV_E_GC_RUNTIME = 0x80000104 # < \~chinese 运行环境有问题 \~english Running environment error +MV_E_GC_LOGICAL = 0x80000105 # < \~chinese 逻辑错误 \~english Logical error +MV_E_GC_ACCESS = 0x80000106 # < \~chinese 节点访问条件有误 \~english Node accessing condition error +MV_E_GC_TIMEOUT = 0x80000107 # < \~chinese 超时 \~english Timeout +MV_E_GC_DYNAMICCAST = 0x80000108 # < \~chinese 转换异常 \~english Transformation exception +MV_E_GC_UNKNOW = 0x800001FF # < \~chinese GenICam未知错误 \~english GenICam unknown error + +# GigE_STATUS对应的错误码:范围0x80000200-0x800002FF +MV_E_NOT_IMPLEMENTED = 0x80000200 # < \~chinese 命令不被设备支持 \~english The command is not supported by device +MV_E_INVALID_ADDRESS = 0x80000201 # < \~chinese 访问的目标地址不存在 \~english The target address being accessed does not exist +MV_E_WRITE_PROTECT = 0x80000202 # < \~chinese 目标地址不可写 \~english The target address is not writable +MV_E_ACCESS_DENIED = 0x80000203 # < \~chinese 设备无访问权限 \~english No permission +MV_E_BUSY = 0x80000204 # < \~chinese 设备忙,或网络断开 \~english Device is busy, or network disconnected +MV_E_PACKET = 0x80000205 # < \~chinese 网络包数据错误 \~english Network data packet error +MV_E_NETER = 0x80000206 # < \~chinese 网络相关错误 \~english Network error +MV_E_KEY_VERIFICATION = 0x8000020F # < \~chinese 秘钥校验错误 \~english SwitchKey error +MV_E_IP_CONFLICT = 0x80000221 # < \~chinese 设备IP冲突 \~english Device IP conflict + +# USB_STATUS对应的错误码:范围0x80000300-0x800003FF +MV_E_USB_READ = 0x80000300 # < \~chinese 读usb出错 \~english Reading USB error +MV_E_USB_WRITE = 0x80000301 # < \~chinese 写usb出错 \~english Writing USB error +MV_E_USB_DEVICE = 0x80000302 # < \~chinese 设备异常 \~english Device exception +MV_E_USB_GENICAM = 0x80000303 # < \~chinese GenICam相关错误 \~english GenICam error +MV_E_USB_BANDWIDTH = 0x80000304 # < \~chinese 带宽不足 该错误码新增 \~english Insufficient bandwidth, this error code is newly added +MV_E_USB_DRIVER = 0x80000305 # < \~chinese 驱动不匹配或者未装驱动 \~english Driver mismatch or unmounted drive +MV_E_USB_UNKNOW = 0x800003FF # < \~chinese USB未知的错误 \~english USB unknown error + +# 升级时对应的错误码:范围0x80000400-0x800004FF +MV_E_UPG_FILE_MISMATCH = 0x80000400 # < \~chinese 升级固件不匹配 \~english Firmware mismatches +MV_E_UPG_LANGUSGE_MISMATCH = 0x80000401 # < \~chinese 升级固件语言不匹配 \~english Firmware language mismatches +MV_E_UPG_CONFLICT = 0x80000402 # < \~chinese 升级冲突(设备已经在升级了再次请求升级即返回此错误) \~english Upgrading conflicted (repeated upgrading requests during device upgrade) +MV_E_UPG_INNER_ERR = 0x80000403 # < \~chinese 升级时设备内部出现错误 \~english Camera internal error during upgrade +MV_E_UPG_UNKNOW = 0x800004FF # < \~chinese 升级时未知错误 \~english Unknown error during upgrade diff --git a/camera/PixelType_header.py b/camera/PixelType_header.py new file mode 100644 index 0000000..29baacc --- /dev/null +++ b/camera/PixelType_header.py @@ -0,0 +1,258 @@ +# -*- coding: utf-8 -*- +from ctypes import * + +PixelType_Gvsp_BGR12_Packed = 36700187 +PixelType_Gvsp_COORD3D_DEPTH_PLUS_MASK = -2112094207 +PixelType_Gvsp_RGB10V1_Packed = 35651612 +PixelType_Gvsp_BayerRG12_Packed = 17563691 +PixelType_Gvsp_RGB12_Planar = 36700195 +PixelType_Gvsp_YUV411_Packed = 34340894 +PixelType_Gvsp_YUV444_Packed = 35127328 +PixelType_Gvsp_BGR10_Packed = 36700185 +PixelType_Gvsp_YCBCR422_8 = 34603067 +PixelType_Gvsp_YCBCR709_422_8 = 34603073 +PixelType_Gvsp_RGB12_Packed = 36700186 +PixelType_Gvsp_Coord3D_ABC32f_Planar = 39846081 +PixelType_Gvsp_Mono8_Signed = 17301506 +PixelType_Gvsp_YUV422_YUYV_Packed = 34603058 +PixelType_Gvsp_Mono4p = 17039417 +PixelType_Gvsp_BayerGR12_Packed = 17563690 +PixelType_Gvsp_Coord3D_ABC32 = -2107625471 +PixelType_Gvsp_Coord3D_AB32f = -2109722622 +PixelType_Gvsp_YCBCR709_411_8_CBYYCRYY = 34340930 +PixelType_Gvsp_YCBCR709_422_8_CBYCRY = 34603077 +PixelType_Gvsp_Coord3D_AB32 = -2109722621 +PixelType_Gvsp_YCBCR601_422_8_CBYCRY = 34603076 +PixelType_Gvsp_YCBCR709_8_CBYCR = 35127360 +PixelType_Gvsp_Coord3D_AC32f = 36176066 +PixelType_Gvsp_YCBCR8_CBYCR = 35127354 +PixelType_Gvsp_YCBCR411_8_CBYYCRYY = 34340924 +PixelType_Gvsp_Coord3D_ABC32f = 39846080 +PixelType_Gvsp_YUV422_Packed = 34603039 +PixelType_Gvsp_Coord3D_ABC16 = 36700345 +PixelType_Gvsp_RGB10_Planar = 36700194 +PixelType_Gvsp_RGB8_Planar = 35127329 +PixelType_Gvsp_RGB10_Packed = 36700184 +PixelType_Gvsp_Coord3D_C32 = -2128596986 +PixelType_Gvsp_RGB16_Packed = 36700211 +PixelType_Gvsp_YCBCR422_8_CBYCRY = 34603075 +PixelType_Gvsp_YCBCR601_411_8_CBYYCRYY = 34340927 +PixelType_Gvsp_BGRA8_Packed = 35651607 +PixelType_Gvsp_Jpeg = -2145910783 +PixelType_Gvsp_YCBCR601_422_8 = 34603070 +PixelType_Gvsp_Coord3D_C32f = 18874559 +PixelType_Gvsp_BayerGB12_Packed = 17563692 +PixelType_Gvsp_BayerRG16 = 17825839 +PixelType_Gvsp_BayerGB10_Packed = 17563688 +PixelType_Gvsp_RGB12V1_Packed = 35913780 +PixelType_Gvsp_RGB16_Planar = 36700196 +PixelType_Gvsp_BGR565_Packed = 34603062 +PixelType_Gvsp_Mono16 = 17825799 +PixelType_Gvsp_BayerBG10 = 17825807 +PixelType_Gvsp_Coord3D_AC32f_64 = 37748930 +PixelType_Gvsp_RGBA8_Packed = 35651606 +PixelType_Gvsp_Mono12 = 17825797 +PixelType_Gvsp_Coord3D_A32f = 18874557 +PixelType_Gvsp_YCBCR601_8_CBYCR = 35127357 +PixelType_Gvsp_BayerGB16 = 17825840 +PixelType_Gvsp_Coord3D_AC32 = -2109722620 +PixelType_Gvsp_BayerBG16 = 17825841 +PixelType_Gvsp_Coord3D_AC32f_Planar = 37748931 +PixelType_Gvsp_BayerBG10_Packed = 17563689 +PixelType_Gvsp_RGB8_Packed = 35127316 +PixelType_Gvsp_BGR8_Packed = 35127317 +PixelType_Gvsp_BayerGR16 = 17825838 +PixelType_Gvsp_BayerGR10_Packed = 17563686 +PixelType_Gvsp_Mono8 = 17301505 +PixelType_Gvsp_Mono14 = 17825829 +PixelType_Gvsp_BayerGB10 = 17825806 +PixelType_Gvsp_Undefined = -1 +PixelType_Gvsp_BayerRG8 = 17301513 +PixelType_Gvsp_BayerGB12 = 17825810 +PixelType_Gvsp_Mono12_Packed = 17563654 +PixelType_Gvsp_BayerBG8 = 17301515 +PixelType_Gvsp_BayerBG12_Packed = 17563693 +PixelType_Gvsp_Mono1p = 16842807 +PixelType_Gvsp_Mono2p = 16908344 +PixelType_Gvsp_RGB565_Packed = 34603061 +PixelType_Gvsp_RGB10V2_Packed = 35651613 +PixelType_Gvsp_BayerRG12 = 17825809 +PixelType_Gvsp_Mono10_Packed = 17563652 +PixelType_Gvsp_BayerGR8 = 17301512 +PixelType_Gvsp_BayerGB8 = 17301514 +PixelType_Gvsp_BayerGR12 = 17825808 +PixelType_Gvsp_BayerGR10 = 17825804 +PixelType_Gvsp_BayerRG10 = 17825805 +PixelType_Gvsp_BayerBG12 = 17825811 +PixelType_Gvsp_Coord3D_A32 = -2128596987 +PixelType_Gvsp_Mono10 = 17825795 +PixelType_Gvsp_BayerRG10_Packed = 17563687 +PixelType_Gvsp_YUV420SP_NV12 = 34373633 +PixelType_Gvsp_YUV420SP_NV21 = 34373634 +PixelType_Gvsp_Coord3D_C16 = 17825976 +PixelType_Gvsp_BayerRBGG8 = 17301574 +PixelType_Gvsp_HB_Mono8 = -2130182143 +PixelType_Gvsp_HB_Mono10 = -2129657853 +PixelType_Gvsp_HB_Mono10_Packed = -2129919996 +PixelType_Gvsp_HB_Mono12 = -2129657851 +PixelType_Gvsp_HB_Mono12_Packed = -2129919994 +PixelType_Gvsp_HB_Mono16 = -2129657849 +PixelType_Gvsp_HB_BayerGR8 = -2130182136 +PixelType_Gvsp_HB_BayerRG8 = -2130182135 +PixelType_Gvsp_HB_BayerGB8 = -2130182134 +PixelType_Gvsp_HB_BayerBG8 = -2130182133 +PixelType_Gvsp_HB_BayerRBGG8 = -2130182074 +PixelType_Gvsp_HB_BayerGR10 = -2129657844 +PixelType_Gvsp_HB_BayerRG10 = -2129657843 +PixelType_Gvsp_HB_BayerGB10 = -2129657842 +PixelType_Gvsp_HB_BayerBG10 = -2129657841 +PixelType_Gvsp_HB_BayerGR12 = -2129657840 +PixelType_Gvsp_HB_BayerRG12 = -2129657839 +PixelType_Gvsp_HB_BayerGB12 = -2129657838 +PixelType_Gvsp_HB_BayerBG12 = -2129657837 +PixelType_Gvsp_HB_BayerGR10_Packed = -2129919962 +PixelType_Gvsp_HB_BayerRG10_Packed = -2129919961 +PixelType_Gvsp_HB_BayerGB10_Packed = -2129919960 +PixelType_Gvsp_HB_BayerBG10_Packed = -2129919959 +PixelType_Gvsp_HB_BayerGR12_Packed = -2129919958 +PixelType_Gvsp_HB_BayerRG12_Packed = -2129919957 +PixelType_Gvsp_HB_BayerGB12_Packed = -2129919956 +PixelType_Gvsp_HB_BayerBG12_Packed = -2129919955 +PixelType_Gvsp_HB_YUV422_Packed = -2112880609 +PixelType_Gvsp_HB_YUV422_YUYV_Packed = -2112880590 +PixelType_Gvsp_HB_RGB8_Packed = -2112356332 +PixelType_Gvsp_HB_BGR8_Packed = -2112356331 +PixelType_Gvsp_HB_RGBA8_Packed = -2111832042 +PixelType_Gvsp_HB_BGRA8_Packed = -2111832041 +PixelType_Gvsp_HB_RGB16_Packed = -2110783437 +PixelType_Gvsp_HB_BGR16_Packed = -2110783413 +PixelType_Gvsp_HB_RGBA16_Packed = -2109734812 +PixelType_Gvsp_HB_BGRA16_Packed = -2109734831 + +__all__ = ['PixelType_Gvsp_BayerRG8', + 'PixelType_Gvsp_YCBCR422_8', + 'PixelType_Gvsp_Coord3D_ABC32', + 'PixelType_Gvsp_Coord3D_AB32f', + 'PixelType_Gvsp_COORD3D_DEPTH_PLUS_MASK', + 'PixelType_Gvsp_RGB10_Packed', + 'PixelType_Gvsp_RGB10V1_Packed', + 'PixelType_Gvsp_RGB8_Planar', + 'PixelType_Gvsp_RGBA8_Packed', + 'PixelType_Gvsp_RGB8_Packed', + 'PixelType_Gvsp_BayerBG12', + 'PixelType_Gvsp_Coord3D_AC32f_Planar', + 'PixelType_Gvsp_BayerBG10_Packed', + 'PixelType_Gvsp_YCBCR709_422_8_CBYCRY', + 'PixelType_Gvsp_Coord3D_A32f', + 'PixelType_Gvsp_YUV411_Packed', + 'PixelType_Gvsp_BayerBG12_Packed', + 'PixelType_Gvsp_RGB16_Packed', + 'PixelType_Gvsp_BayerRG12', + 'PixelType_Gvsp_BayerRG10', + 'PixelType_Gvsp_BayerRG16', + 'PixelType_Gvsp_YCBCR709_411_8_CBYYCRYY', + 'PixelType_Gvsp_BayerGB12_Packed', + 'PixelType_Gvsp_Coord3D_AC32f', + 'PixelType_Gvsp_BayerRG12_Packed', + 'PixelType_Gvsp_Coord3D_AB32', + 'PixelType_Gvsp_BGR12_Packed', + 'PixelType_Gvsp_BayerGR10_Packed', + 'PixelType_Gvsp_Coord3D_AC32', + 'PixelType_Gvsp_RGB12_Planar', + 'PixelType_Gvsp_YCBCR709_422_8', + 'PixelType_Gvsp_BGR8_Packed', + 'PixelType_Gvsp_Jpeg', + 'PixelType_Gvsp_Coord3D_AC32f_64', + 'PixelType_Gvsp_YUV422_Packed', + 'PixelType_Gvsp_Mono8_Signed', + 'PixelType_Gvsp_BayerBG10', + 'PixelType_Gvsp_BayerBG16', + 'PixelType_Gvsp_BayerGR8', + 'PixelType_Gvsp_RGB16_Planar', + 'PixelType_Gvsp_Mono4p', + 'PixelType_Gvsp_BayerRG10_Packed', + 'PixelType_Gvsp_Mono8', + 'PixelType_Gvsp_BayerGR16', + 'PixelType_Gvsp_BayerGR10', + 'PixelType_Gvsp_BGRA8_Packed', + 'PixelType_Gvsp_BayerGR12', + 'PixelType_Gvsp_Mono12_Packed', + 'PixelType_Gvsp_YCBCR709_8_CBYCR', + 'PixelType_Gvsp_Coord3D_A32', + 'PixelType_Gvsp_YCBCR601_422_8', + 'PixelType_Gvsp_Coord3D_C32', + 'PixelType_Gvsp_YCBCR411_8_CBYYCRYY', + 'PixelType_Gvsp_Undefined', + 'PixelType_Gvsp_BayerGR12_Packed', + 'PixelType_Gvsp_YCBCR601_411_8_CBYYCRYY', + 'PixelType_Gvsp_RGB10_Planar', + 'PixelType_Gvsp_BayerGB16', + 'PixelType_Gvsp_BayerGB10', + 'PixelType_Gvsp_BayerGB12', + 'PixelType_Gvsp_BGR565_Packed', + 'PixelType_Gvsp_Mono1p', + 'PixelType_Gvsp_Coord3D_ABC16', + 'PixelType_Gvsp_YUV444_Packed', + 'PixelType_Gvsp_YUV422_YUYV_Packed', + 'PixelType_Gvsp_BayerBG8', + 'PixelType_Gvsp_Coord3D_C32f', + 'PixelType_Gvsp_BGR10_Packed', + 'PixelType_Gvsp_BayerGB10_Packed', + 'PixelType_Gvsp_Coord3D_ABC32f_Planar', + 'PixelType_Gvsp_Coord3D_ABC32f', + 'PixelType_Gvsp_YCBCR422_8_CBYCRY', + 'PixelType_Gvsp_RGB12_Packed', + 'PixelType_Gvsp_Mono12', + 'PixelType_Gvsp_Mono10', + 'PixelType_Gvsp_Mono16', + 'PixelType_Gvsp_Mono2p', + 'PixelType_Gvsp_Mono14', + 'PixelType_Gvsp_RGB10V2_Packed', + 'PixelType_Gvsp_RGB12V1_Packed', + 'PixelType_Gvsp_Mono10_Packed', + 'PixelType_Gvsp_YCBCR601_8_CBYCR', + 'PixelType_Gvsp_BayerGB8', + 'PixelType_Gvsp_YCBCR8_CBYCR', + 'PixelType_Gvsp_RGB565_Packed', + 'PixelType_Gvsp_YCBCR601_422_8_CBYCRY', + 'PixelType_Gvsp_YUV420SP_NV12', + 'PixelType_Gvsp_YUV420SP_NV21', + 'PixelType_Gvsp_Coord3D_C16', + 'PixelType_Gvsp_BayerRBGG8', + 'PixelType_Gvsp_HB_Mono8', + 'PixelType_Gvsp_HB_Mono10', + 'PixelType_Gvsp_HB_Mono10_Packed', + 'PixelType_Gvsp_HB_Mono12', + 'PixelType_Gvsp_HB_Mono12_Packed', + 'PixelType_Gvsp_HB_Mono16', + 'PixelType_Gvsp_HB_BayerGR8', + 'PixelType_Gvsp_HB_BayerRG8', + 'PixelType_Gvsp_HB_BayerGB8', + 'PixelType_Gvsp_HB_BayerBG8', + 'PixelType_Gvsp_HB_BayerRBGG8', + 'PixelType_Gvsp_HB_BayerGR10', + 'PixelType_Gvsp_HB_BayerRG10', + 'PixelType_Gvsp_HB_BayerGB10', + 'PixelType_Gvsp_HB_BayerBG10', + 'PixelType_Gvsp_HB_BayerGR12', + 'PixelType_Gvsp_HB_BayerRG12', + 'PixelType_Gvsp_HB_BayerGB12', + 'PixelType_Gvsp_HB_BayerBG12', + 'PixelType_Gvsp_HB_BayerGR10_Packed', + 'PixelType_Gvsp_HB_BayerRG10_Packed', + 'PixelType_Gvsp_HB_BayerGB10_Packed', + 'PixelType_Gvsp_HB_BayerBG10_Packed', + 'PixelType_Gvsp_HB_BayerGR12_Packed', + 'PixelType_Gvsp_HB_BayerRG12_Packed', + 'PixelType_Gvsp_HB_BayerGB12_Packed', + 'PixelType_Gvsp_HB_BayerBG12_Packed', + 'PixelType_Gvsp_HB_YUV422_Packed', + 'PixelType_Gvsp_HB_YUV422_YUYV_Packed', + 'PixelType_Gvsp_HB_RGB8_Packed', + 'PixelType_Gvsp_HB_BGR8_Packed', + 'PixelType_Gvsp_HB_RGBA8_Packed', + 'PixelType_Gvsp_HB_BGRA8_Packed', + 'PixelType_Gvsp_HB_RGB16_Packed', + 'PixelType_Gvsp_HB_BGR16_Packed', + 'PixelType_Gvsp_HB_RGBA16_Packed', + 'PixelType_Gvsp_HB_BGRA16_Packed'] diff --git a/camera/PyUICBasicDemo.py b/camera/PyUICBasicDemo.py new file mode 100644 index 0000000..91399c3 --- /dev/null +++ b/camera/PyUICBasicDemo.py @@ -0,0 +1,146 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'PyUICBasicDemo.ui' +# +# Created by: PyQt5 UI code generator 5.15.4 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(747, 486) + self.centralWidget = QtWidgets.QWidget(MainWindow) + self.centralWidget.setObjectName("centralWidget") + self.ComboDevices = QtWidgets.QComboBox(self.centralWidget) + self.ComboDevices.setGeometry(QtCore.QRect(10, 20, 511, 22)) + self.ComboDevices.setObjectName("ComboDevices") + self.widgetDisplay = QtWidgets.QWidget(self.centralWidget) + self.widgetDisplay.setGeometry(QtCore.QRect(10, 60, 511, 401)) + self.widgetDisplay.setObjectName("widgetDisplay") + self.groupInit = QtWidgets.QGroupBox(self.centralWidget) + self.groupInit.setGeometry(QtCore.QRect(530, 20, 211, 101)) + self.groupInit.setObjectName("groupInit") + self.gridLayoutWidget = QtWidgets.QWidget(self.groupInit) + self.gridLayoutWidget.setGeometry(QtCore.QRect(9, 19, 201, 81)) + self.gridLayoutWidget.setObjectName("gridLayoutWidget") + self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget) + self.gridLayout.setContentsMargins(11, 11, 11, 11) + self.gridLayout.setSpacing(6) + self.gridLayout.setObjectName("gridLayout") + self.bnClose = QtWidgets.QPushButton(self.gridLayoutWidget) + self.bnClose.setEnabled(False) + self.bnClose.setObjectName("bnClose") + self.gridLayout.addWidget(self.bnClose, 2, 2, 1, 1) + self.bnOpen = QtWidgets.QPushButton(self.gridLayoutWidget) + self.bnOpen.setObjectName("bnOpen") + self.gridLayout.addWidget(self.bnOpen, 2, 1, 1, 1) + self.bnEnum = QtWidgets.QPushButton(self.gridLayoutWidget) + self.bnEnum.setObjectName("bnEnum") + self.gridLayout.addWidget(self.bnEnum, 1, 1, 1, 2) + self.groupGrab = QtWidgets.QGroupBox(self.centralWidget) + self.groupGrab.setEnabled(False) + self.groupGrab.setGeometry(QtCore.QRect(530, 130, 211, 171)) + self.groupGrab.setObjectName("groupGrab") + self.gridLayoutWidget_2 = QtWidgets.QWidget(self.groupGrab) + self.gridLayoutWidget_2.setGeometry(QtCore.QRect(9, 19, 202, 141)) + self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") + self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2) + self.gridLayout_2.setContentsMargins(11, 11, 11, 11) + self.gridLayout_2.setSpacing(6) + self.gridLayout_2.setObjectName("gridLayout_2") + self.bnSaveImage = QtWidgets.QPushButton(self.gridLayoutWidget_2) + self.bnSaveImage.setEnabled(False) + self.bnSaveImage.setObjectName("bnSaveImage") + self.gridLayout_2.addWidget(self.bnSaveImage, 4, 0, 1, 2) + self.radioContinueMode = QtWidgets.QRadioButton(self.gridLayoutWidget_2) + self.radioContinueMode.setObjectName("radioContinueMode") + self.gridLayout_2.addWidget(self.radioContinueMode, 0, 0, 1, 1) + self.radioTriggerMode = QtWidgets.QRadioButton(self.gridLayoutWidget_2) + self.radioTriggerMode.setObjectName("radioTriggerMode") + self.gridLayout_2.addWidget(self.radioTriggerMode, 0, 1, 1, 1) + self.bnStop = QtWidgets.QPushButton(self.gridLayoutWidget_2) + self.bnStop.setEnabled(False) + self.bnStop.setObjectName("bnStop") + self.gridLayout_2.addWidget(self.bnStop, 2, 1, 1, 1) + self.bnStart = QtWidgets.QPushButton(self.gridLayoutWidget_2) + self.bnStart.setEnabled(False) + self.bnStart.setObjectName("bnStart") + self.gridLayout_2.addWidget(self.bnStart, 2, 0, 1, 1) + self.bnSoftwareTrigger = QtWidgets.QPushButton(self.gridLayoutWidget_2) + self.bnSoftwareTrigger.setEnabled(False) + self.bnSoftwareTrigger.setObjectName("bnSoftwareTrigger") + self.gridLayout_2.addWidget(self.bnSoftwareTrigger, 3, 0, 1, 2) + self.groupParam = QtWidgets.QGroupBox(self.centralWidget) + self.groupParam.setEnabled(False) + self.groupParam.setGeometry(QtCore.QRect(530, 310, 211, 151)) + self.groupParam.setObjectName("groupParam") + self.gridLayoutWidget_3 = QtWidgets.QWidget(self.groupParam) + self.gridLayoutWidget_3.setGeometry(QtCore.QRect(10, 20, 201, 131)) + self.gridLayoutWidget_3.setObjectName("gridLayoutWidget_3") + self.gridLayoutParam = QtWidgets.QGridLayout(self.gridLayoutWidget_3) + self.gridLayoutParam.setContentsMargins(11, 11, 11, 11) + self.gridLayoutParam.setSpacing(6) + self.gridLayoutParam.setObjectName("gridLayoutParam") + self.label_6 = QtWidgets.QLabel(self.gridLayoutWidget_3) + self.label_6.setObjectName("label_6") + self.gridLayoutParam.addWidget(self.label_6, 3, 0, 1, 1) + self.edtGain = QtWidgets.QLineEdit(self.gridLayoutWidget_3) + self.edtGain.setObjectName("edtGain") + self.gridLayoutParam.addWidget(self.edtGain, 1, 1, 1, 1) + self.label_5 = QtWidgets.QLabel(self.gridLayoutWidget_3) + self.label_5.setObjectName("label_5") + self.gridLayoutParam.addWidget(self.label_5, 1, 0, 1, 1) + self.label_4 = QtWidgets.QLabel(self.gridLayoutWidget_3) + self.label_4.setObjectName("label_4") + self.gridLayoutParam.addWidget(self.label_4, 0, 0, 1, 1) + self.edtExposureTime = QtWidgets.QLineEdit(self.gridLayoutWidget_3) + self.edtExposureTime.setObjectName("edtExposureTime") + self.gridLayoutParam.addWidget(self.edtExposureTime, 0, 1, 1, 1) + self.bnGetParam = QtWidgets.QPushButton(self.gridLayoutWidget_3) + self.bnGetParam.setObjectName("bnGetParam") + self.gridLayoutParam.addWidget(self.bnGetParam, 4, 0, 1, 1) + self.bnSetParam = QtWidgets.QPushButton(self.gridLayoutWidget_3) + self.bnSetParam.setObjectName("bnSetParam") + self.gridLayoutParam.addWidget(self.bnSetParam, 4, 1, 1, 1) + self.edtFrameRate = QtWidgets.QLineEdit(self.gridLayoutWidget_3) + self.edtFrameRate.setObjectName("edtFrameRate") + self.gridLayoutParam.addWidget(self.edtFrameRate, 3, 1, 1, 1) + self.gridLayoutParam.setColumnStretch(0, 2) + self.gridLayoutParam.setColumnStretch(1, 3) + MainWindow.setCentralWidget(self.centralWidget) + self.statusBar = QtWidgets.QStatusBar(MainWindow) + self.statusBar.setObjectName("statusBar") + MainWindow.setStatusBar(self.statusBar) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) + self.groupInit.setTitle(_translate("MainWindow", "初始化")) + self.bnClose.setText(_translate("MainWindow", "关闭设备")) + self.bnOpen.setText(_translate("MainWindow", "打开设备")) + self.bnEnum.setText(_translate("MainWindow", "查找设备")) + self.groupGrab.setTitle(_translate("MainWindow", "采集")) + self.bnSaveImage.setText(_translate("MainWindow", "保存图像")) + self.radioContinueMode.setText(_translate("MainWindow", "连续模式")) + self.radioTriggerMode.setText(_translate("MainWindow", "触发模式")) + self.bnStop.setText(_translate("MainWindow", "停止采集")) + self.bnStart.setText(_translate("MainWindow", "开始采集")) + self.bnSoftwareTrigger.setText(_translate("MainWindow", "软触发一次")) + self.groupParam.setTitle(_translate("MainWindow", "参数")) + self.label_6.setText(_translate("MainWindow", "帧率")) + self.edtGain.setText(_translate("MainWindow", "0")) + self.label_5.setText(_translate("MainWindow", "增益")) + self.label_4.setText(_translate("MainWindow", "曝光")) + self.edtExposureTime.setText(_translate("MainWindow", "0")) + self.bnGetParam.setText(_translate("MainWindow", "获取参数")) + self.bnSetParam.setText(_translate("MainWindow", "设置参数")) + self.edtFrameRate.setText(_translate("MainWindow", "0")) diff --git a/camera/PyUICBasicDemo.ui b/camera/PyUICBasicDemo.ui new file mode 100644 index 0000000..4fb89a4 --- /dev/null +++ b/camera/PyUICBasicDemo.ui @@ -0,0 +1,261 @@ + + + MainWindow + + + + 0 + 0 + 747 + 486 + + + + MainWindow + + + + + + 10 + 20 + 511 + 22 + + + + + + + 10 + 60 + 511 + 401 + + + + + + + 530 + 20 + 211 + 101 + + + + 初始化 + + + + + 9 + 19 + 201 + 81 + + + + + + + false + + + 关闭设备 + + + + + + + 打开设备 + + + + + + + 查找设备 + + + + + + + + + false + + + + 530 + 130 + 211 + 171 + + + + 采集 + + + + + 9 + 19 + 202 + 141 + + + + + + + false + + + 保存图像 + + + + + + + 连续模式 + + + + + + + 触发模式 + + + + + + + false + + + 停止采集 + + + + + + + false + + + 开始采集 + + + + + + + false + + + 软触发一次 + + + + + + + + + false + + + + 530 + 310 + 211 + 151 + + + + 参数 + + + + + 10 + 20 + 201 + 131 + + + + + + + 帧率 + + + + + + + 0 + + + + + + + 增益 + + + + + + + 曝光 + + + + + + + 0 + + + + + + + 获取参数 + + + + + + + 设置参数 + + + + + + + 0 + + + + + + + + + + + + ComboDevices + + + + diff --git a/camera/__pycache__/CamOperation_class.cpython-310.pyc b/camera/__pycache__/CamOperation_class.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12e5feaf9081bf1a6330f62574fd0cc66d82fa21 GIT binary patch literal 9574 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 literal 0 HcmV?d00001 diff --git a/camera/__pycache__/CameraParams_const.cpython-310.pyc b/camera/__pycache__/CameraParams_const.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ab912716117420e3a132d6e456da0b900bf4b7e GIT binary patch literal 1701 zcmZuxTT|0O6i!Qk0v5TeD1vwKLR-KKGmb;L-9l`dbdt2z^RiRfDp6>iwut(~jK9L4 z;J@*iSD*S9eDa(mr7g6b{dUiH&iQut!HS%QTgcr;?hej(alVH+ z_fh)+?(-1OvWnV|@GOtz3_Ovu@Knyh8rliulQ>csyDsM)Wp$yAw^G`4$##@LC5RDB z5v&kw6Pyqz80aY&*d8Ktm|%op6v4wWOfW*A5^Q^s6Ldro%+(E;%9ljZ%$e3(k>Mqs zahODAN8jPSc4}j5vt!38!%26{IW(D;=eB0(X0F4|AY0PyKB4K5JD0q}P1ooPT*SbD zy(m1}^_2^q-MVDi%63TF&cBCly4=occ(p4?^+H za$7h$1l1zWH5_3U^FX_j9Td~2s6s@YN%`zT$U5BCHA56E+x2<63q=P7(6fCK0g2kg zo>HjB7GPYjg_BqnASdP0ekCE6JhDdA0jIFs` zY&}mVfgVyno!VL-$Zx#d9LPU=K{{dM^~k4E&q(N^V|^n@N*5iQ&yz0)I=0qRvMg`%B;q5BQ~TWQc|%!hy5iDI+bXeJJ;wU3G8dgF7V zg{vR?UgDEip`|!(CiW_a)kY=3{HaiBR1TYBuU>1m*1mi{jlDXo%cFzpYx-U`KOm^8 i8X52(3c08n#T6mVYPbq)VuCorPDWRa7>bF+qW=MS&A=Z3 literal 0 HcmV?d00001 diff --git a/camera/__pycache__/CameraParams_header.cpython-310.pyc b/camera/__pycache__/CameraParams_header.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4643dbfcd2eef09c9ff3eb50af60428798d684f3 GIT binary patch literal 24670 zcmdU0d35QOO_%9(_Kjs22ADx$HUx%s(lqS^+NLDwEEh0j@^0Hen}nBiptuXJ z=#ND}L{vZlK|~QZ6mdrsabKgLh^Qk7%D(gae$Rb*N!m_Rf4|S~kKfEE=iPJPz2}^J z?z!ild+uv?&YYGy{JY@8og-1ZzV2ZnmH!q3*@9pG$)$C5R-IKpS{FCZdgtkh*Xai3 zwdz!(KsI>p*8c-fe(<8?83A3Gy5Xey>N{qpUgVXtX`XYFC?qAB*2{z>i1! z6VUENv^xp-7W55(RwwF$sOv(z5bC?pt_Q!ZD2GvZGTxnnaxcn#DEFfrL3sdePDMG2 zat!rx&>6Jms%=(>+HTELJFNL?r?o&SYoR&~?M~Ncs5j_@I#VarE}c@A)@n!(s}Y@6 zXX&%ms2)=pomDw~j3+vEg zKex2MTUv?I0rGYgN(V}5wOcw!C>*ROEFa$t&(ZHoT%_Np-VYfLvDQF_H6p_YthIU^ z91a!uI)R4?JY1iP`XdCc6Kd=Axc)EUv%xJvGN*2%TY`*E9Y)}kAfr=)j818jP(9L> z)FYD4*B^kSA5a%V($`x@LDHi{(o3wP-JbtBS8C!Iq2Hu00sTwVrJ%prIu`Vg75bN1 z$GP;U8{hHn+w%CP8`TMJJM#1k&t`oYcwVMH2%aZeCxPcl!t?U~Q=XTD=jG}O@Z4er zz%w8`ulzsdc_nyWsXhdromLP$gTnJF;9XV-cu0R3mVdR?t=|vp>d_YiZq=6phV=&l zPu5oeo}xbloAv3d6Bk*%Vu5`E`^8ow0tW=1>RL~eSY}jTjh=pe738=|eFS`CRvdie zBF8n>ptRqnKdL`+LB0N%%#KH2gVxumkE8W=YX@5Ikk;2$XlkcBtI92%=JIY8I*s~T z(79G!2Rf%)XMoNbLg#wx4bn0JuGfLLC;&%r_nQQorRufNzYs1SwDliv#n9ojf!pDW{rW`r-fQZ zTbNCczAbUlaGjN<4P07p<(%g^`ZI#teap$?4RPg>>2Z#R_e8PF2?>yhA zKP&Zba-MH?>fho#-|9Ty<~-l-Jm29wFL0h0I?s1Ha=y!XzT0`e$9cZjY4<+od6B+N z_`l!5Kj1v+N5t=5TCZ<~9&c5jgU&9tE`iQ25k1}x-Eb$#2^76pm%4Lunbdwz;N_qt zD`mJz-ws;0tIvbh71ouYb*0d{!}^fh^D6y0P-P$4Uxpj>9q4n1`U2+di~5V|OX&My z>uU79TKaz3`UrJxU8Bzd{HSpJnACh+X0lO#8U4SkzJh+&TGyf9b<*!n>w0PX3H?>{ z`y|WYbtl^1slJA`H&{2K?Tym*E{DfWLibbBZz?CBz6-tYQeQ{!o2^^W`xfbax6}L6 z((hJ*)UVlly!vkRx?6n%y*^{zhF-TxuWwqP70Ev5YUXz7DHdt$(K1?}tYyFcCMbSW zeG3}3hKO z9`${2`<`_VxZNY%?%gZ5vVHzfxZMkG_o^R&+xM+|!R=n*_CrVOlSf!NHZzJJi2Og) z_gVMRms!x%Bn|!$9Db;N1P(v4?gxkag~R>RtgOl042K^>hxdusGQ6g8xE~zuS3d@a zpIAQyho1_EpBTU9Skd%W@H4TEpS!d43mMHX1#)$o7_UYD1RQ>%ehLo1vVIK?zZMQZ zs~W@qj>FHu;b-dSu(Mz2U#MS#({HTbg41t>)32QQsMP=O=uNGn$ohNzOO*ehy?~V4 zSg&9I3RHikehq35SPz2QgF@{$Q*5c+r$PS)eSV{U3rT*bf2WFg{$BrH{Q=Jh^aJWa zJpZWwsQ!fKL;4~0XFMO)539f6`G|f*{T0u@>A$JJgXbTuKY{0;gy$aXA$_0zhuFxU z>8GuS1^z|ke?;J41^!Lo-^DNNkuq0@@sllj52V|p9tHJ(SdW7GqeA^L>oFPoKLxVA z#P{%ZkD>iz>Yr%;xb+0uKOyZOxBeww?%x90-e{~rKaTc~t0ypuf9Zdzf1}@%)>G*B zl=OSjdRqS*vOgnoJu4$9bMxva(fdjD6nZ^pJ&#_`ORuM`7o`1*0$&pNvcOk_|EnVP zYf@7lt6x72YEP?Ydg?BzxA?2SP@vF!7PzN$DnYryU3bQ28}zg2{j7RUdVA5LQF=E@ z@8^O0$PdpZSpRceUx){uN1x}_3mE;2_`M{3{b z(MDI$v~CjFnjo8BWIF)uR*7t@9NC&tb70AbqP$w>uQGC)ez!H=_bTx4SNW|L)HDlM zP*yGa9Kcr8;iuXJgEeXVRJ&kvf#Ih*1e*s8KQ&*l1;FrA3k6#Q3_rD4Msg5jJy=F^ zurrb+uAeRMs(X(dOw1th11KE=+U--uu|&qP1U#1t&oyYdR(P&;crN>2@H`YeJErhl zCOlz@YPs-y9e5rlJP&htu0YM<=sRC#{Rqdt*Hz5ndYQxWzQ9$pLg=Ee+DGVa0F{kG zccVj>cDo5J_Y=BD>T|3%@d{-+wDx_44%({yh0g2I3;75_htA6B>7e%LNpiun>6Jnc zebfO$?-;b(Ec7-z^j1~w)OcHIt;Y&Q6T3}or)YoNB(Aj3Rl;=@xE?56k4L)`gzE_o z*VU*wkv;J|N#BP)2Tk&k)W&L|gSP5mp|b_8kyRjc=)kh9PG^pS&a=yThWM=Xm7sWt zP(&}aMkscpe~(b?aVV}u%~pp(coGH5v{opfl{!=?oQ(FT2!&G|3bd(SheDt8?023K z=Q#jMYh?80Y=ZIV@Fx0o!UJ^FVZtK{iZS64b9lf)tvFg9Dl`Tis@rN(_o2_>LLC&; z5kh@CXdweZ=ulsW@=lk!a!Y%cnrmR4&_!RhUg(|%DyIwG(;d1SDs9cIZL~R~Vr@y* z0(FT=Rz@?)*M#~}p;FEhmUBVnY>S(lMEfx}S5(fylruEgq0uJ8aSn5(9wU;#E2zyPNfvK& zB1z7XlRTIH7>mtB(~5$AZG~LcvDMyimwH6iz@*0THgr+5 z?Xvd?(i<(*iPC! zg!{WAiT;}#ivC0*lN{5DM6o527|UAYqb#>266cI3N6nj?>ulca2zW8DZZNOy{JJrn z8D4j8);@b(0j2Xt((BGjCs|CKn_rg#MLW4JD35`pogB+2Ms(8B_7S-WdoGB*oq|#s z{yJ~H)Tp*hI2Rlmj^qmIY(~v7Sa967b*7+NGEOO+Q}avZ*!Zq~UFb{Z&sOc3Ew)-K;o|RyyTJa)l=~33Gxv7yZy*r)K+b|?@U0&TS zmeZ;9P&yUP3}yGMXZQBhNKD)50sr&)CiRV3DQXH3FVdyBnzFF%i0Ci zoQZ0@Mz(IRb7r@LPHCP7W1X9-=gB6U@+6qjBGxSjxPpbnB}}yk?ZRj{6UtZv*)&u) zmw05n;8wK93bsy;x%iyWZm8Hr{b_5P&RAJnHK(ls8zzw|U^?C>h-8MS>VRe8&M9A074vDbu%KS5!m-!A>tO|kf19fZV#=Qy z8G!o3U3(4&T9e;G;nyeZ$}42=9QOs$yIhXM)ST2vI8)FztWHBMlWdSiq*_Xf3wO;@ zq8$UXwT1m4!;f5vh|P}0j!5@xS?mv@e{fk4tI1-4=ruT74l6`Wa zCY!n<@x=O2|K6wY08oFz5rX9RsD> z9ocSE%=9JC%G&TMSp0qIj48IEHbwK_njRiettG5Cdv38c6Yot^~*Z z6^I8C!AO4`Gdq(htpVLFE*D~|B^MkS&z#+rEF_gbBW1Wo%qDAlb*82mi#eO!(Li4) z5gCjdn+oliNs6`Ldx|Rsv6@U)_HW!cJs!R$DsY0U&DQlr`+Z3c-9 z4drz~H4gP8(}=-_7{TNbK#?5cuE1`Db;G*TrpOuW;>ruo7Dm%!YcOccbdHW|EFEDf zl;HyBWa8*BtZiAoXdKSu#tRraf)W<|8N+smTiQwCXdp&O5ROPmQ<+{2a3GmF8X7*#kv#DLc+%H(LM68_C*cq)3W9V4|@+w2TZ{&4WV#Fd1Y^5-A~x1%C9I+?K9 zyZHW4JRS}7$7;Ixb>Q?dmoG8ZfpMmEdbg%eh^5chsELo**>lTA15-ozjApwl>XxD3 zIpaEy`aBe648U0Le7u@eS98gWpAPi)Ci(*L;MST0Vf25CI}l>U#*8f1#+>Za%`oes zEXPxmwHQ+++fW?gQ9Kl!(YbB}&o8(V5QE~%OTlPjuGEyZ_8-fFP<!mAON}kZot}a!pNnWY?Kyq0M01M}qy2Tw#b6y(8N*R|hLR+cS(j^KR&iP_l$e z+?x}c;y~LCeU@jn37dRR(5&%5Fc^x(67d;E7sPmOcSlD|&B-zC$9Xe}FP@Z3SWV@Y z)|&VjhyOq{(i5#ENEcXt%@u?gv!mIu+^8-{EFRAmlA|^G%SJ0fTwgdA3rG4B@tp&q z8C4JhuOGOaiQ$qL!F@85A4}(%Kow)g>c*5IQQIs9CgEyIBMIt2FitsweO)FTn`t__ z!Tp!6EX3Tb#VPoVy%{Hx?0AmF7E_co@w{Du6w}MJqEIHeYgA*$Dp#p_xlTKqv{K1@ z!O2r%)v_^;DmBL-8m$-uW^%AMKBGo^Aos)WD2S;JxB`=LDM`?T^^z=%*FFyHL-##Z z0Lcx^q|2?~`=l!cF=z$h3W92+)bltgIHj5@mw#0N;@<$ zOdHbt5)|On7#q(qe~yegVkj4#UC7X31VIp2TaJ^#xy_Y>7>-|k$@2(t3icwfPt_bb zeWmzhhaoql8NA6U;Ih=^NvtLZ=GMTWyEhV;#h`jYa<$8Vm}(w!mFpdn@eN^oHTgOt zi^Zei{+`;}>;tQHE@NU$db^xks99|N!?OrSOa=-=mh4Y#AjCb7_f~sP>Gp%)W|uoL zn6hlarBs3-=ICE@=n{BB=UaIu3P!q0!QhM=Z3IjQT@i>Oo=0%ccpgjHPGR&lIm=Q8 z=V&Azh~v7hDqNpo`~zV37MD3O#b5(F0^MF9Gdx;5+%Clz-M!&~*>gS>ye@V*6T_E7 zneNeaZdOMV*#I!$oAc>-aJ#Cu{F1r69D-wN|7%2v%Qm855&d z4fe%S$yv;O=>mbt-e>?92c;w83^un7Jig^}B!)fL7(5iK<{~)B6l`p%-MEd-+9@=s z`iE0d-4^^xm!K7!2tv>3&KVu)c69u?%bZxzmobwLw-cKf+m#(n*LL4+#<>O~y^(15 z3}f911`oLGh$+ud6u%z)I+brIFq#`l)*Pb4PO=O$u~T61PnR7ru-Sp%&YCRdni1jj zVv^=F4C*w{eZl2IOnHam*_>(`>dY1j*)b%9d-YHO!;4C?x(OFx*-_jOw@79~Tx(5% zoM{b)qd}ai>Bwgg>2wIu>Mg|v#MB%xMHXG#=32X9D7rxbY^=%Hi3NJY{UMXEoPqBd z;I!Q3OH8%p3y8n$f?3pn?Rr9_h+JO!DXEB7mXT0&{xJAW+4p0Va_{Et#V{ z6Ye!NGu`29raP81Aw`!f6EUQqN{27%r!B{Wm!ldaJsfP-jvawwDB2xxzl_;?gpmaE z0ap}a@UH{Gu(>nF_aT+vo$T3y_cgU4PIr<7wJ!8XH0g>#OwC0iy7ct{Qqi@~3uey^ z;G2h7C>jp*BI}8C&kUwvfz4SiQ)2w~!+a1kt7D!CEhclUHC7Eqd6z9Q<`CpF9CD>i za*?_fYnEb5u_Z^p+$6N7J7n7jfKagw4cyzsVh5We+1nEc_b2)g@D=CrNL6)9P&^n_ z@-3B|p5@d$*dGpZx7;3%Z)K_k%Whk73EClO?&%3d6S2r(6vjm#w7$3kFRHV*i9y`_ z$k#)A>$P!jFE$n1A+TKKbs+(eDirsne0FjdvMfkD4NoKnbE)hYZXG2NSZoP*!xwaq zW|IXOU3G$|xKO0V-A-j%pg3n7$>zimHt`KdB?`qwXf*X|So%&me-;T z0*N=$_5;fmY>cgf|4~QcH7~8q2XwTI(uC4D62&>xiik=|#RI5$eq~p-jM!i&F3UQj zkw6zML?&m-4TG2`4XL;c6sBkpW`myl<5g#%H_#spZQmNkp&&4b+%N;RaQ|RrFlO_< zU1qd9YmX%*v6u*K3)@V`+Dv(hc~^ZHQJgRQP8C~E#Bjjt4M|MPey!rlTp_G%L2QV8uBh{Oh?A*1tnxG&Tt);E?s4<_!i7CAm!-<}aES;E%F%5Y`v>mni%TIU zjeUx_8QNm-$AC87z$9e^W80j?+?mYl;sUg&wx#ZF@wwuQ5}ji?o8P>Yrn|yV8TWjiBxK~*db;Y%8c`yR-U4Zeli#3 zHn9W&Y<^K=yrNh)&#WCW@Pp&Zl}vP!qd(7K=00Cdv(&U z*eV*s_Jch~W&kVESbN!96<1eShNJv$n-~0<)C3NU_|gQiOp*I{$$p$x!N?$kwe@DI zN*i?|(%o$z$iYyHqOc0zVe{6~<|Ux)3H^aeFE6f%ju-xBn!BaqK6`xy(=_zLHdA=T zW=?|HMHp8Y8;_@ligPEW?!=i-npMnvC>rPrbt6XTvJWCXh9gyQ8v^= zsmo+4y^d&Znw2A~y}Dav1XJ`m20fSjO{gHJX&LACNU;^~#i4WA$?B4XP0833v1m_c z#cm<1WF@7n3`lwrm*9qgU%%udnb8Ru$8^HNS;)jp>jjFWJ58?&BV!206*YM)D7K-p z9COj%RaiV!?tBAb2cZUAJ}F?EszF3Dx^n_xIvb5ey5rje(U62D729!{C5JV|y&7LE zR%CVq*Oki}H_4z%T^MIb(WapV<#9KWDWHQi=2#Yi$|-LH60x^XwaT2dgl2B|ZL+(e9X3CqD3;C&(+o}gJyxr;{TolV zoSm>@B-C`X@WuVW+BFiIxf6qm$skT8jfggF-CjEFziD9)>R!Sq46tGKkH z3i)9EwF%PRfmpD(Y}z+nA-s}d^CJ<-&-2nUz|h%5vs3HEcue}mN$780FY2hO+i=V@ zl^c&!>W)nVGLLt*WY$<|`WY zNBTo08?C68`ye^cRuM?hOcKGt=(do!$Lg28*dsQ|M&TUKD+scBBO8>6V$p2t=FGOcD|i=ni7DQcTZVJFVRm`q05W?I&9Z53Hvn^{vQ;wk4`Z6-6t zJ5EW6iiL=#FcFgyl{WK_wxspTQKsAq*t}>cStK{F%IgZ7_a3EPqVn#9a#6o-oz1J6 z((%LCq1jG&qf{b4`6kTf^_I=sHFH#&?w-!<1l8Y{U~4;*J^3ZD^qhLYV@S!(8h>C? zdHA*WWfyr-{Rctzek8bm>FuPy<&n!48O1c|MVrY>8G7|gn;Ev!8L&Dx$c14u?^PXr$(c!=QJ1ivTvDZ%duenId@g7*;ct3LZ~mi|icYk~=acLS()_w*RTCD?@h z3g7&g;O_+I5PX*4GJ>xXTt{#P!3_jw5&W6p0|Z|p_!+^E2reXeir{I2ZxVcqAVV-l z@Djn<1kDt+g`kz7jbJW;{1whTmKG8$B9J8NGM1JTtRRrTk=dW6l>`S6tRgs&U^T%Z z05E|B&k^>|!L`^V$cCfrkCd@Z8|}B2v7?T(|K?zFptf%(2FoCZj$f`o(X*Z`oVV!u zIlcwQT@yGGeZrxWA3+FUzn@s6@V75;nvG^N!}f2SX5-T77Gfl5dY$jIBzOCJrIym~ z?ZE6`5&VVVzX(1?@D+jr!9NIICU_gc4+yR%co?AAjAJowP54Kta>Vi{hSGY}$|vma zu+4I|St!>;eSsZ`&cW_(W{<-vWP7RI6>M||0Ud&U4C}-LY-WjWz&@6xl_(V(2Qx@l zNS@oil&=nCZIifkL~)E>$;3G)G4-vj}Ia|tdd_yfVk1S15G5Ije4GeMEy9Ryz_@Nn`z z&(gmLt|#~m!J`D70Pwt+43o6)=U+vMaoBtvB={6T7r_w0RRljF2odB7x(Pl_&_l4B zU@O792;M^Qae^>_oM6e3ImFn`zRpN*I4BeQbv8Mf;7Wp12%aS9CAg2EkKlQNeu730 zF2a(JB|m}u<>4Hb+6m?pEFf4+u!LYgf_(|(59JPKX@FE-&(f(Z9m!IZrA;iwQ4)`U zjF!ETHG_P&fu(IMt!HUFTa~Qa9a=B$A=mNsPBvV_l45BsOQ*4PC`+fa^g5Q#VCgWH z-oVn~EG1BqNQ;^?(H7Uj5qx(hTOGwxlBMHWO0j)u{giiO_BoF4Ew((7CC!%1y9njV zYdf?(0WFG6i9~XAG?AF@@5PJ$s9O8#+8K)YGdT zudm+onyudEq<7@Xk>6`2Mx39zVFW)@R z6TbPL$9)St|MV^LJnCEQ`G;?bXOC~G=kLB{p1=84cpmZXSzw@pw=>k&AjFdDjqkYBO=xy-Um)eMy z91Tbr@2lR``(E_=OEsV<BlRGQ|qrIT|kYbw&&+7B{pt_+hFul zz+dt;EtR(h_rK(K@s@i3%YNTdQbkMuEB?l%4L;bf``_c1SO?6Z@u+`^>BaZpA^(NO zv;H<8s7?0+ZSf>*Z~AbJ`O#yhH!U(Qp)HcPVALg9S(Z043Q{LtqF$1Rqi?To@tCnf zPaggU{+z#6G{bU9E2Vej@r-}YQdlj<%oeP9-rvF+k(;>mGNU4AY4d`=xpF+L>tI{q nMok+DOMUs?{O7n@I08o_3+w%_`n}XMdP~XQAe1mq^F99!aDmhf literal 0 HcmV?d00001 diff --git a/camera/__pycache__/MvCameraControl_class.cpython-310.pyc b/camera/__pycache__/MvCameraControl_class.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0308dfe7a1b78a1cc88895482cafdebc9cdbe96b GIT binary patch literal 29747 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 U(Ztr+TOCbJjZJSg#HYpo4~G|TdH?_b literal 0 HcmV?d00001 diff --git a/camera/__pycache__/MvErrorDefine_const.cpython-310.pyc b/camera/__pycache__/MvErrorDefine_const.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83da1bbce1123f3088130dafc2c1e9e6c89b7d5c GIT binary patch literal 1997 zcma)+S#RV-5P+RIlF2c-lf5^ay|YJVZ(b0h$L>s8vD;SLPBismMOyWeG;tCpaSEoe1udM0X`F!>oP}AOgE?$N8|Psj7hnMwVG);L z3726RS6~HKVHMY44cB2EufP?&3Rm$OT*K>d9dE!5ya_k)7Tm(ya2q#Z1Mk2c+=NZM z3wQAz+{62DA0NO2dD{Ye#i$922XQ>)O{@36*bjhwc@ILSE0*kYV!v|V=|W*O%g z+l=#!3yh15ON`5mD~zj*YmDcN9@ROnn6buKXKXMw87CR17+Z|zj1=l38e@&I&e&jV zGEOosFm5t>bVcKW7;B7m#s*`P@to14OCCF8tTEOZ&r8%>@1Pm&7x5m<(w{7Lg$_aq zbES~xNfMjPN!@%W-j@dE%ROI&VQhj6IT1!gG9$TN?i-oLx$&j*tK&dq0+!0X#7IBZ zfyz{@opW-WTB$P7vD9(i+bt+2tdwU&SH~t2VWA??lg=)TMNovQYlP{$xH^vW%pR*s zklHu>By*c_BK3}<`W8x`WL79$QcI(J=Ytf&^zumRal)iALQ}m}ek3M_iZEH9eVANl zDjL^BCSlxDbUp5(tW)2YY04+8Id#c(mJEWv7LoFOk!F0#<+|#srs|?3lr}jTK&4f> z>{TIxfbKhms_+A&GHDadq@Ouml>&7`D>^;xx}El2UlQT($qZ(ySmhX1-QJV^f@VYQ zP(|gqRE8vg?o zWV@G-8D+=58X0Tk8na#|n&oPOQ;bT<69^O5MM4@aGEjt(srpGKYchbM#K zVJG@Q4u@yMVDQz^>7aOjb~^gF{oRkhwLU*N!|#s=U(mPC8y(ZqsM9;~zu*6|{kQI) J8Yi_T{swF1kKX_Q literal 0 HcmV?d00001 diff --git a/camera/__pycache__/PixelType_header.cpython-310.pyc b/camera/__pycache__/PixelType_header.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3472dd5cd9433e062cffff9d1cd5131473c0e527 GIT binary patch literal 6032 zcmd^@*;*4@7RM`*Nd-j#nPn6Kl?;Rs6cG|IC^8rZ&2lIrD?rJRn4pLwmGhm4=-a;Q zH|W0Tue(oQ_Y356TJgjRyLOcoh27-hbL8eSI>+Ty#uZe~l~lo1RLSS5iZ9T4zDO6i znl5q;Rr4jP;mdT1Yw0pyp<2F5SGbO@ay`{?1J(02YT!n?#!b}7&D6v#)Xc5a!fn*b z?bOECshvCMI(JeBcTp#IQy2G8H}_Hx-=JRZqZ@pa`naEN@&NVoAPw*>8syt_i|^2F z9-=$!p&|B?hkfK_Klyl={2ZWR9-#mSX@o~9$RQf#F$(cr8smF(m&fTI-=}e&p!@uQ zCU}w_@DxpQn5H;FVVf=p%okBmPXE_zQjJuk?k#(O3RX-}somZz-(*(M89cTUG{s z`5m<~;L5uOwN}OJ)?7+kPHR&--P$ds+NJg2+jXVdt#v9*Zmk)w_mo<VWhw zn7JG1g0u-w72Zx=8^%)vDi1KC5th1?rekda-~Og_y0qI^+@sXGw0=AVlwP;ii(x^i zR6=kW_)VE~Yu7MAIbQ#YvG=i>7q4Zo)Q6{kLT><5)kE3<3_;LmcnQyM;PsNg@BbA) z+If7tifGgE6xXKS#{~j>asdNwLF(^mGolKu+OV5B{p`FoNu=iuK7%HOQ|@d zF6}1v6B)aCr-ZODul>M+tVx>G2vj)g^XGdci4_hJjZJgi4oS%zZu!(JDH!n{^^U1V z%+*LZ9*MI;bfRtY zMOQc^Ur2)XTaIwTHY%b33sGs1T!R^bbcu5(``2k6>TSk_?Clo$4LVA^CFY61pKcwt zfk45OL>GoT*O8TMqYEOjyqs<;d!meND<$al74{6rp{T%aDJ;gi*e!~>PxfhbpOc#! z((Y9KR?*1YyfM9D*^f)e#dWgH7g8>-Z{${Vic^xr3E_}F(Oo5Z5a}BUj+j+$S6;q! z$sjBG;fOFp-hHs)1_I`kU2=$pRJ2umHNIx5*q**&ar(+}G1oP=HCc#_$vQ{uQ&V(! z$_I@(wQ+h|=apPqKWgPWW#6pZfzwHKvc(k+Q`>0!^R}P8_Md~cpZ#gu&%QuOuNalK zW)-aLuVL=#l|s(6(Zr51x2oN2V%t1N!=-sPMw+AKMTJd86)We_TJ(ntgFFXH)bCwh zQWw^2dZI|`_c`w$qV(nKVPW45M@8+*&d!EaTDfQ~iP3|C_(84~IwLsQGSu;w(vCU>@saY7f=U8fGAK7 zbOTR-N5D;B8n_MI1uB3_pc%LVv;%P<0JH+nfDrH)=mWyQIB*d-4~zm0z#MQ7@BzI* z5O@f*08PLwungP+CV@quAGiTj1M|RDU=_FzbOHmwWuO+Q0eS!r&;bkqPk{+w3@8I0 z0K>oxP!CK2OTcp=23!MH0P*)xC9?+j0WZ)9TmnXb1>g=qzzg6d@CtYhsK7dq0Nwx_ z00T*26W9W_0S$Ny>;SvK97#tr_+Eh($ literal 0 HcmV?d00001 diff --git a/config/app_config.json b/config/app_config.json new file mode 100644 index 0000000..bd9d635 --- /dev/null +++ b/config/app_config.json @@ -0,0 +1,19 @@ +{ + "app": { + "name": "腾智微丝产线包装系统", + "version": "1.0.0", + "features": { + "enable_serial_ports": false, + "enable_keyboard_listener": false + } + }, + "database": { + "type": "sqlite", + "path": "db/jtDB.db", + "host": "", + "port": "", + "user": "", + "password": "", + "name": "" + } +} \ No newline at end of file diff --git a/config/application.yaml b/config/application.yaml new file mode 100644 index 0000000..37e2a29 --- /dev/null +++ b/config/application.yaml @@ -0,0 +1,5 @@ +app: + debug: true + name: jt-mes-system + version: 1.0.0 + description: 佳腾管理系统 diff --git a/dao/login_dao.py b/dao/login_dao.py new file mode 100644 index 0000000..12f2e75 --- /dev/null +++ b/dao/login_dao.py @@ -0,0 +1,52 @@ +from db.pgsql import PostgreSQL +from db.system_config_dao import SystemConfigDAO + +def check_user_login(user_id: str, password: str) -> bool: + db = PostgreSQL() + try: + db.connect() + sql = "SELECT 1 FROM sys_user WHERE user_id=%s AND password=md5(%s)" + result = db.execute_query(sql, (user_id, password)) + return bool(len(result) > 0) + finally: + db.disconnect() + +def get_user_info(user_id: str): + db = PostgreSQL() + try: + db.connect() + sql = """ + SELECT user_id, nick_name AS user_name, position_id, + f_getname('GETCORPEXP', '', '', org_id) AS corp_name, + org_id AS corp_id, default_org_id + FROM sys_user + WHERE user_id = %s + """ + result = db.execute_query(sql, (user_id,)) + if result: + user_name = result[0]['user_name'] + corp_name = result[0]['corp_name'] + corp_id = result[0]['corp_id'] + position_id = result[0]['position_id'] + default_org_id = result[0]['default_org_id'] + + # 如果有默认账套ID,使用默认账套ID替代登录账套ID + if default_org_id: + corp_id = default_org_id + # 查询默认账套的名称 + corp_name_sql = """ + SELECT corp_exp + FROM sys_org + WHERE org_id = %s + """ + corp_result = db.execute_query(corp_name_sql, (corp_id,)) + if corp_result: + corp_name = corp_result[0]['corp_exp'] + + # 将用户的当前账套ID保存到内存中 + SystemConfigDAO.save_user_selected_corp(user_id, corp_id) + + return user_name, corp_name, corp_id, position_id + return None, None, None, None + finally: + db.disconnect() \ No newline at end of file diff --git a/db/jtDB.db b/db/jtDB.db new file mode 100644 index 0000000000000000000000000000000000000000..ee2c5b8d0fad0c571b469f1ab893c3bb4a11593b GIT binary patch literal 16384 zcmeI(O>f#T7zc2hRPCtLvKQivld2)LrIw?iMWs8j?wzP)a;05-%+Y+j^a} z(>~nxY1SR*KnpEs_pSOrib;$gKaqdrVxe@-oj6tWaXcA@DK*$r#yNXU#2CxzwxQcy zaDB1bzZ?78ImZq^ecvhkX2$L_w%afK&?f{0AOHafKmY;|fB*y_009X63j%Fpv$VIz zyJ>haP|4Lm?+$y3x|*s{f3>@D>Pg{C^2LcGX(hKZ3WsW6&#Zop`Bte|bz$Fb%8oCZ?M2zOyo>8a z!TYyg=1ni7^?GZ=56diveaGOLqBRyvd3*lH(vP3^nri?1Rwwb2tWV=5P$##AOHafK;S^nri?1Rwwb z2tWV=5P$##AOHafK;Tgc:98] - ================================================================= +2025-06-05 11:34:24,245 - INFO - root - [:99] - 应用程序启动 +2025-06-05 11:34:24,245 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 11:34:24,245 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 11:34:24,245 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 11:34:24,441 - INFO - root - [main:125] - ===================================================== +2025-06-05 11:34:24,441 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 11:34:24,441 - INFO - root - [main:127] - ===================================================== +2025-06-05 11:34:24,442 - INFO - root - [save_config:79] - 已保存配置文件: config/app_config.json +2025-06-05 11:34:24,442 - INFO - root - [load_config:59] - 已创建默认配置文件: config/app_config.json +2025-06-05 11:34:24,442 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 11:34:24,444 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 11:34:24,444 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 11:34:34,803 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 11:34:34,842 - INFO - root - [__init__:37] - 主窗口已创建,用户: system +2025-06-05 11:34:34,871 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 11:35:29,328 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 11:35:54,132 - INFO - root - [:98] - ================================================================= +2025-06-05 11:35:54,132 - INFO - root - [:99] - 应用程序启动 +2025-06-05 11:35:54,132 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 11:35:54,132 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 11:35:54,132 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 11:35:54,282 - INFO - root - [main:125] - ===================================================== +2025-06-05 11:35:54,282 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 11:35:54,282 - INFO - root - [main:127] - ===================================================== +2025-06-05 11:35:54,282 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 11:35:54,282 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 11:35:54,282 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 11:35:54,282 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 11:36:04,270 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 11:36:04,294 - INFO - root - [__init__:37] - 主窗口已创建,用户: system +2025-06-05 11:36:04,320 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 11:36:08,016 - INFO - root - [show_main_page:46] - 显示主页面 +2025-06-05 11:45:17,771 - INFO - root - [:98] - ================================================================= +2025-06-05 11:45:17,771 - INFO - root - [:99] - 应用程序启动 +2025-06-05 11:45:17,771 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 11:45:17,771 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 11:45:17,771 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 11:45:17,930 - INFO - root - [main:125] - ===================================================== +2025-06-05 11:45:17,930 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 11:45:17,930 - INFO - root - [main:127] - ===================================================== +2025-06-05 11:45:17,931 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 11:45:17,931 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 11:45:17,932 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 11:45:17,932 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 11:45:23,609 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 11:45:23,639 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: name 'QTableWidgetItem' is not defined +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 38, in __init__ + self.initialize_data() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 69, in initialize_data + self.project_table.setItem(row, col, QTableWidgetItem(project_data[row][col-1])) +NameError: name 'QTableWidgetItem' is not defined +2025-06-05 11:45:33,313 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 11:45:33,325 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: name 'QTableWidgetItem' is not defined +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 38, in __init__ + self.initialize_data() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 69, in initialize_data + self.project_table.setItem(row, col, QTableWidgetItem(project_data[row][col-1])) +NameError: name 'QTableWidgetItem' is not defined +2025-06-05 11:45:35,955 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 11:46:11,973 - INFO - root - [:98] - ================================================================= +2025-06-05 11:46:11,973 - INFO - root - [:99] - 应用程序启动 +2025-06-05 11:46:11,973 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 11:46:11,973 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 11:46:11,973 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 11:46:12,247 - INFO - root - [main:125] - ===================================================== +2025-06-05 11:46:12,248 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 11:46:12,248 - INFO - root - [main:127] - ===================================================== +2025-06-05 11:46:12,248 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 11:46:12,248 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 11:46:12,248 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 11:46:12,248 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 11:46:25,834 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 11:46:25,865 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 11:46:25,892 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 11:46:35,886 - INFO - root - [handle_input:87] - 上料按钮被点击 +2025-06-05 11:46:40,963 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 11:47:56,169 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 11:55:57,029 - INFO - root - [:98] - ================================================================= +2025-06-05 11:55:57,029 - INFO - root - [:99] - 应用程序启动 +2025-06-05 11:55:57,029 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 11:55:57,029 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 11:55:57,029 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 11:55:57,198 - INFO - root - [main:125] - ===================================================== +2025-06-05 11:55:57,198 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 11:55:57,198 - INFO - root - [main:127] - ===================================================== +2025-06-05 11:55:57,198 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 11:55:57,198 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 11:55:57,200 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 11:55:57,200 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 11:56:03,320 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 11:56:03,375 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 11:56:03,406 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 11:56:30,957 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 11:57:04,947 - INFO - root - [:98] - ================================================================= +2025-06-05 11:57:04,947 - INFO - root - [:99] - 应用程序启动 +2025-06-05 11:57:04,947 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 11:57:04,947 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 11:57:04,948 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 11:57:05,122 - INFO - root - [main:125] - ===================================================== +2025-06-05 11:57:05,122 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 11:57:05,122 - INFO - root - [main:127] - ===================================================== +2025-06-05 11:57:05,122 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 11:57:05,122 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 11:57:05,123 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 11:57:05,123 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 11:57:10,115 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 11:57:10,160 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 11:57:10,186 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 12:02:35,861 - INFO - root - [:98] - ================================================================= +2025-06-05 12:02:35,861 - INFO - root - [:99] - 应用程序启动 +2025-06-05 12:02:35,861 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 12:02:35,861 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 12:02:35,861 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 12:02:36,025 - INFO - root - [main:125] - ===================================================== +2025-06-05 12:02:36,025 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 12:02:36,025 - INFO - root - [main:127] - ===================================================== +2025-06-05 12:02:36,025 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 12:02:36,025 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 12:02:36,025 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 12:02:36,025 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:04:42,704 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:04:42,737 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:04:42,763 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:05:12,176 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 13:08:14,584 - INFO - root - [:98] - ================================================================= +2025-06-05 13:08:14,584 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:08:14,584 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:08:14,584 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:08:14,585 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:08:14,751 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:08:14,751 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:08:14,751 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:08:14,751 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:08:14,751 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:08:14,752 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:08:14,752 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:09:17,895 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:09:17,926 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:09:17,947 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:16:27,879 - INFO - root - [:98] - ================================================================= +2025-06-05 13:16:27,879 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:16:27,879 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:16:27,879 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:16:27,879 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:16:28,051 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:16:28,051 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:16:28,051 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:16:28,052 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:16:28,052 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:16:28,053 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:16:28,053 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:16:35,771 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:16:35,804 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:16:35,828 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:17:40,839 - INFO - root - [:98] - ================================================================= +2025-06-05 13:17:40,839 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:17:40,839 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:17:40,839 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:17:40,839 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:17:40,992 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:17:40,992 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:17:40,992 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:17:40,994 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:17:40,994 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:17:40,994 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:17:40,994 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:17:47,297 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:17:47,332 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:17:47,357 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:18:35,198 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 13:20:25,192 - INFO - root - [:98] - ================================================================= +2025-06-05 13:20:25,192 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:20:25,192 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:20:25,192 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:20:25,192 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:20:25,350 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:20:25,350 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:20:25,350 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:20:25,351 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:20:25,351 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:20:25,352 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:20:25,352 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:20:33,824 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:20:33,859 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:20:33,884 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:26:00,531 - INFO - root - [:98] - ================================================================= +2025-06-05 13:26:00,532 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:26:00,532 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:26:00,532 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:26:00,532 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:26:00,682 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:26:00,683 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:26:00,683 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:26:00,684 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:26:00,684 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:26:00,684 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:26:00,684 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:26:05,256 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:26:05,291 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:26:05,325 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:28:36,849 - CRITICAL - root - [global_exception_handler:18] - 未捕获的异常: Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/main.py", line 200, in + main() + File "/Users/meng/work/tengzhi/jiateng_ws/main.py", line 190, in main + exit_code = app.exec() +KeyboardInterrupt + +2025-06-05 13:28:38,594 - INFO - root - [:98] - ================================================================= +2025-06-05 13:28:38,594 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:28:38,594 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:28:38,594 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:28:38,594 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:28:38,756 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:28:38,756 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:28:38,756 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:28:38,757 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:28:38,757 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:28:38,757 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:28:38,757 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:28:43,480 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:28:43,508 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:28:43,530 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:29:00,226 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 13:29:00,490 - INFO - root - [:98] - ================================================================= +2025-06-05 13:29:00,490 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:29:00,490 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:29:00,490 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:29:00,490 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:29:00,652 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:29:00,652 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:29:00,652 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:29:00,652 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:29:00,652 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:29:00,652 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:29:00,652 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:29:02,309 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 13:33:14,122 - INFO - root - [:98] - ================================================================= +2025-06-05 13:33:14,123 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:33:14,123 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:33:14,123 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:33:14,123 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:33:14,284 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:33:14,284 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:33:14,284 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:33:14,285 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:33:14,285 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:33:14,285 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:33:14,285 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:33:19,790 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:33:19,823 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:33:19,848 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:33:55,434 - CRITICAL - root - [global_exception_handler:18] - 未捕获的异常: Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 35, in paintEvent + def paintEvent(self, event): +KeyboardInterrupt + +2025-06-05 13:34:58,099 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 13:38:32,158 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 13:38:32,511 - INFO - root - [:98] - ================================================================= +2025-06-05 13:38:32,512 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:38:32,512 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:38:32,512 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:38:32,512 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:38:32,675 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:38:32,676 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:38:32,676 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:38:32,677 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:38:32,677 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:38:32,677 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:38:32,677 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:38:36,772 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:38:36,807 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:38:36,831 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:38:51,525 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 13:44:54,947 - INFO - root - [:98] - ================================================================= +2025-06-05 13:44:54,947 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:44:54,947 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:44:54,947 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:44:54,947 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:44:55,111 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:44:55,111 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:44:55,111 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:44:55,112 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:44:55,112 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:44:55,112 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:44:55,112 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:45:02,117 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:45:02,154 - INFO - root - [__init__:40] - 主窗口已创建,用户: system +2025-06-05 13:45:02,177 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:51:11,906 - INFO - root - [:98] - ================================================================= +2025-06-05 13:51:11,906 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:51:11,906 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:51:11,906 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:51:11,906 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:51:12,074 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:51:12,074 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:51:12,074 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:51:12,074 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:51:12,074 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:51:12,074 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:51:12,074 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:51:17,014 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:51:17,056 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 13:51:17,081 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:51:19,906 - INFO - root - [test_configure_inspection_columns:59] - 测试动态配置检验列数:将检验列数从3列调整为5列 +2025-06-05 13:58:17,559 - CRITICAL - root - [global_exception_handler:18] - 未捕获的异常: Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/main.py", line 200, in + main() + File "/Users/meng/work/tengzhi/jiateng_ws/main.py", line 190, in main + exit_code = app.exec() +KeyboardInterrupt + +2025-06-05 13:58:17,930 - INFO - root - [:98] - ================================================================= +2025-06-05 13:58:17,930 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:58:17,930 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:58:17,930 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:58:17,930 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:58:18,084 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:58:18,084 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:58:18,084 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:58:18,085 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:58:18,085 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:58:18,085 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:58:18,085 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:58:23,492 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:58:23,529 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 13:58:23,558 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:58:26,380 - INFO - root - [test_configure_inspection_columns:59] - 测试动态配置检验列数:将检验列数从3列调整为5列 +2025-06-05 13:58:35,578 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 13:58:39,366 - INFO - root - [:98] - ================================================================= +2025-06-05 13:58:39,366 - INFO - root - [:99] - 应用程序启动 +2025-06-05 13:58:39,366 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 13:58:39,366 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 13:58:39,366 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 13:58:39,525 - INFO - root - [main:125] - ===================================================== +2025-06-05 13:58:39,525 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 13:58:39,525 - INFO - root - [main:127] - ===================================================== +2025-06-05 13:58:39,525 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 13:58:39,525 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 13:58:39,525 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 13:58:39,525 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 13:58:43,713 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 13:58:43,743 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 13:58:43,776 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 13:58:46,866 - INFO - root - [test_configure_inspection_columns:59] - 测试动态配置检验列数:将检验列数从3列调整为5列 +2025-06-05 13:59:50,895 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 14:00:20,910 - INFO - root - [:98] - ================================================================= +2025-06-05 14:00:20,910 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:00:20,910 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:00:20,910 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:00:20,910 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:00:21,060 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:00:21,060 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:00:21,060 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:00:21,061 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:00:21,061 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:00:21,061 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:00:21,061 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:00:25,715 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:00:25,756 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 14:00:25,783 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:00:28,865 - INFO - root - [test_configure_inspection_columns:59] - 测试动态配置检验列数:将检验列数从3列调整为5列 +2025-06-05 14:03:12,404 - INFO - root - [:98] - ================================================================= +2025-06-05 14:03:12,405 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:03:12,405 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:03:12,405 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:03:12,405 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:03:12,563 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:03:12,564 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:03:12,564 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:03:12,565 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:03:12,565 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:03:12,565 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:03:12,565 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:03:17,387 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:03:17,423 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 14:03:17,448 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:03:20,361 - INFO - root - [test_configure_inspection_columns:59] - 测试动态配置检验列数:将检验列数从3列调整为5列 +2025-06-05 14:03:27,087 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 14:03:41,980 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 14:03:47,848 - INFO - root - [:98] - ================================================================= +2025-06-05 14:03:47,849 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:03:47,849 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:03:47,849 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:03:47,849 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:03:48,004 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:03:48,004 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:03:48,004 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:03:48,005 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:03:48,005 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:03:48,005 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:03:48,005 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:03:52,151 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:03:52,188 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 14:03:52,210 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:03:55,339 - INFO - root - [test_configure_inspection_columns:59] - 测试动态配置检验列数:将检验列数从3列调整为5列 +2025-06-05 14:08:04,883 - INFO - root - [:98] - ================================================================= +2025-06-05 14:08:04,883 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:08:04,883 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:08:04,883 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:08:04,883 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:08:05,039 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:08:05,040 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:08:05,040 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:08:05,040 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:08:05,040 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:08:05,041 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:08:05,041 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:08:13,904 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:08:13,939 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 14:08:13,965 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:08:16,859 - INFO - root - [test_configure_inspection_columns:59] - 测试动态配置检验列数:将检验列数从3列调整为5列 +2025-06-05 14:08:35,948 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 14:09:58,429 - INFO - root - [:98] - ================================================================= +2025-06-05 14:09:58,429 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:09:58,429 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:09:58,429 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:09:58,429 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:09:58,584 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:09:58,585 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:09:58,585 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:09:58,585 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:09:58,585 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:09:58,585 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:09:58,585 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:10:02,365 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:10:02,404 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 14:10:02,427 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:10:46,426 - INFO - root - [:98] - ================================================================= +2025-06-05 14:10:46,426 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:10:46,426 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:10:46,426 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:10:46,426 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:10:46,580 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:10:46,580 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:10:46,580 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:10:46,580 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:10:46,580 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:10:46,581 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:10:46,581 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:10:51,294 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:10:51,330 - INFO - root - [__init__:41] - 主窗口已创建,用户: system +2025-06-05 14:10:51,351 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:15:11,426 - INFO - root - [:98] - ================================================================= +2025-06-05 14:15:11,426 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:15:11,426 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:15:11,426 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:15:11,426 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:15:11,585 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:15:11,585 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:15:11,585 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:15:11,586 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:15:11,586 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:15:11,587 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:15:11,587 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:15:18,529 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:15:18,568 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:15:18,598 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:23:42,561 - INFO - root - [:98] - ================================================================= +2025-06-05 14:23:42,561 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:23:42,561 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:23:42,561 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:23:42,561 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:23:42,716 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:23:42,716 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:23:42,716 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:23:42,717 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:23:42,717 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:23:42,718 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:23:42,718 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:23:46,686 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:23:46,724 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:23:46,749 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:24:56,270 - INFO - root - [:98] - ================================================================= +2025-06-05 14:24:56,270 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:24:56,270 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:24:56,270 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:24:56,270 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:24:56,424 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:24:56,424 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:24:56,424 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:24:56,425 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:24:56,425 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:24:56,425 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:24:56,425 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:24:59,856 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:24:59,894 - INFO - root - [__init__:42] - 主窗口已创建,用户: system +2025-06-05 14:24:59,916 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:25:32,487 - INFO - root - [:98] - ================================================================= +2025-06-05 14:25:32,487 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:25:32,487 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:25:32,487 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:25:32,487 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:25:32,643 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:25:32,643 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:25:32,644 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:25:32,644 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:25:32,644 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:25:32,644 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:25:32,645 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:25:36,901 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:25:36,937 - INFO - root - [__init__:42] - 主窗口已创建,用户: system +2025-06-05 14:25:36,962 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:25:48,019 - INFO - root - [:98] - ================================================================= +2025-06-05 14:25:48,019 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:25:48,019 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:25:48,019 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:25:48,019 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:25:48,182 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:25:48,182 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:25:48,182 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:25:48,183 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:25:48,183 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:25:48,183 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:25:48,183 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:25:51,858 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:25:51,895 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: MainWindow.configure_inspection_columns() takes 1 positional argument but 2 were given +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 42, in __init__ + self.configure_inspection_columns(5) +TypeError: MainWindow.configure_inspection_columns() takes 1 positional argument but 2 were given +2025-06-05 14:25:56,100 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 14:27:06,572 - INFO - root - [:98] - ================================================================= +2025-06-05 14:27:06,572 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:27:06,572 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:27:06,572 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:27:06,572 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:27:06,725 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:27:06,725 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:27:06,726 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:27:06,726 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:27:06,726 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:27:06,726 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:27:06,726 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:27:09,932 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:27:09,969 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:27:09,999 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:29:49,472 - INFO - root - [:98] - ================================================================= +2025-06-05 14:29:49,472 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:29:49,472 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:29:49,472 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:29:49,472 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:29:49,631 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:29:49,631 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:29:49,631 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:29:49,631 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:29:49,631 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:29:49,632 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:29:49,632 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:29:53,203 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:29:53,238 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:29:53,266 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:30:20,290 - INFO - root - [:98] - ================================================================= +2025-06-05 14:30:20,290 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:30:20,290 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:30:20,290 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:30:20,291 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:30:20,441 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:30:20,441 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:30:20,441 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:30:20,442 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:30:20,442 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:30:20,442 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:30:20,442 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:30:27,226 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:30:27,262 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:30:27,287 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:35:07,737 - INFO - root - [:98] - ================================================================= +2025-06-05 14:35:07,737 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:35:07,737 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:35:07,737 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:35:07,737 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:35:07,894 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:35:07,895 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:35:07,895 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:35:07,895 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:35:07,895 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:35:07,895 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:35:07,895 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:35:26,738 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:35:26,775 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:35:26,799 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:35:41,347 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 14:35:46,222 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 14:42:32,829 - INFO - root - [:98] - ================================================================= +2025-06-05 14:42:32,830 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:42:32,830 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:42:32,830 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:42:32,830 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:42:33,008 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:42:33,008 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:42:33,008 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:42:33,008 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:42:33,008 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:42:33,010 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:42:33,010 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:42:38,650 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:42:38,703 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:42:38,726 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:43:45,996 - INFO - root - [:98] - ================================================================= +2025-06-05 14:43:45,997 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:43:45,997 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:43:45,997 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:43:45,997 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:43:46,159 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:43:46,159 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:43:46,159 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:43:46,160 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:43:46,160 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:43:46,160 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:43:46,161 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:43:49,953 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:43:49,993 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:43:50,021 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:44:00,906 - INFO - root - [:98] - ================================================================= +2025-06-05 14:44:00,906 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:44:00,906 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:44:00,906 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:44:00,907 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:44:01,060 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:44:01,060 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:44:01,060 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:44:01,061 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:44:01,061 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:44:01,062 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:44:01,062 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:44:04,334 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:44:04,371 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:44:04,393 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:44:18,476 - INFO - root - [:98] - ================================================================= +2025-06-05 14:44:18,476 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:44:18,476 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:44:18,476 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:44:18,476 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:44:18,637 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:44:18,638 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:44:18,638 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:44:18,639 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:44:18,639 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:44:18,639 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:44:18,639 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:44:22,094 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:44:22,131 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:44:22,155 - INFO - root - [handle_login:84] - 主窗口已显示 +2025-06-05 14:46:26,647 - INFO - root - [:98] - ================================================================= +2025-06-05 14:46:26,647 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:46:26,648 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:46:26,648 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:46:26,648 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:46:26,809 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:46:26,809 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:46:26,809 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:46:26,810 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:46:26,810 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:46:26,811 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:46:26,811 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:46:31,167 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:46:31,202 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:46:31,227 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:47:40,633 - INFO - root - [:98] - ================================================================= +2025-06-05 14:47:40,633 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:47:40,633 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:47:40,633 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:47:40,633 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:47:40,792 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:47:40,792 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:47:40,792 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:47:40,793 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:47:40,793 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:47:40,794 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:47:40,794 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:47:43,240 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 14:47:47,406 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:47:47,444 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:47:47,475 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:48:46,860 - INFO - root - [:98] - ================================================================= +2025-06-05 14:48:46,860 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:48:46,860 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:48:46,860 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:48:46,860 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:48:47,023 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:48:47,024 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:48:47,024 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:48:47,025 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:48:47,025 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:48:47,026 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:48:47,026 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:48:50,945 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:48:50,985 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:48:51,014 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:49:03,959 - INFO - root - [:98] - ================================================================= +2025-06-05 14:49:03,959 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:49:03,959 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:49:03,959 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:49:03,959 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:49:04,113 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:49:04,113 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:49:04,114 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:49:04,114 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:49:04,114 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:49:04,114 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:49:04,114 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:49:07,415 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:49:07,451 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:49:07,476 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:49:16,677 - INFO - root - [:98] - ================================================================= +2025-06-05 14:49:16,677 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:49:16,677 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:49:16,677 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:49:16,677 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:49:16,833 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:49:16,833 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:49:16,833 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:49:16,834 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:49:16,834 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:49:16,834 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:49:16,834 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:49:20,646 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:49:20,684 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:49:20,710 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:50:21,344 - INFO - root - [:98] - ================================================================= +2025-06-05 14:50:21,344 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:50:21,344 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:50:21,344 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:50:21,344 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:50:21,498 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:50:21,498 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:50:21,498 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:50:21,498 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:50:21,499 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:50:21,499 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:50:21,499 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:50:24,876 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:50:24,913 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:50:24,944 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:50:46,538 - INFO - root - [:98] - ================================================================= +2025-06-05 14:50:46,538 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:50:46,538 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:50:46,538 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:50:46,538 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:50:46,687 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:50:46,687 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:50:46,687 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:50:46,688 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:50:46,688 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:50:46,688 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:50:46,688 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:50:50,456 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:50:50,540 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: 'PySide6.QtWidgets.QWidget.setFont' called with wrong argument types: + PySide6.QtWidgets.QWidget.setFont(int) +Supported signatures: + PySide6.QtWidgets.QWidget.setFont(arg__1: PySide6.QtGui.QFont | str | collections.abc.Sequence[str], /) +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 10, in __init__ + super().__init__() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 14, in __init__ + self.init_ui() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 46, in init_ui + self.create_right_panel() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 233, in create_right_panel + self.create_record_table() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 448, in create_record_table + self.record_title.setFont(30) +TypeError: 'PySide6.QtWidgets.QWidget.setFont' called with wrong argument types: + PySide6.QtWidgets.QWidget.setFont(int) +Supported signatures: + PySide6.QtWidgets.QWidget.setFont(arg__1: PySide6.QtGui.QFont | str | collections.abc.Sequence[str], /) +2025-06-05 14:51:12,482 - INFO - root - [:98] - ================================================================= +2025-06-05 14:51:12,482 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:51:12,482 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:51:12,482 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:51:12,482 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:51:12,632 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:51:12,632 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:51:12,632 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:51:12,633 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:51:12,633 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:51:12,633 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:51:12,633 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:51:15,954 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:51:15,992 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:51:16,017 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:51:50,890 - INFO - root - [:98] - ================================================================= +2025-06-05 14:51:50,890 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:51:50,890 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:51:50,890 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:51:50,890 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:51:51,049 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:51:51,049 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:51:51,049 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:51:51,050 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:51:51,050 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:51:51,050 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:51:51,050 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:51:54,659 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:51:54,699 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:51:54,728 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:52:35,941 - INFO - root - [:98] - ================================================================= +2025-06-05 14:52:35,942 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:52:35,942 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:52:35,942 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:52:35,942 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:52:36,095 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:52:36,095 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:52:36,095 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:52:36,095 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:52:36,095 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:52:36,096 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:52:36,096 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:52:41,025 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:52:41,040 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: 'MainWindow' object has no attribute 'record_title' +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 10, in __init__ + super().__init__() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 14, in __init__ + self.init_ui() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 47, in init_ui + self.create_right_panel() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 231, in create_right_panel + self.create_process_table() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 249, in create_process_table + self.record_title.setFont(self.second_title_font) +AttributeError: 'MainWindow' object has no attribute 'record_title' +2025-06-05 14:54:23,076 - INFO - root - [:98] - ================================================================= +2025-06-05 14:54:23,076 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:54:23,076 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:54:23,076 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:54:23,076 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:54:23,228 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:54:23,228 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:54:23,229 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:54:23,229 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:54:23,229 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:54:23,229 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:54:23,229 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:54:26,384 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:54:26,423 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:54:26,451 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:55:14,703 - INFO - root - [:98] - ================================================================= +2025-06-05 14:55:14,704 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:55:14,704 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:55:14,704 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:55:14,704 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:55:14,979 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:55:14,980 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:55:14,980 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:55:14,980 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:55:14,980 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:55:14,981 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:55:14,981 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:55:19,212 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:55:19,254 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:55:19,279 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 14:55:31,648 - INFO - root - [:98] - ================================================================= +2025-06-05 14:55:31,648 - INFO - root - [:99] - 应用程序启动 +2025-06-05 14:55:31,648 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 14:55:31,648 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 14:55:31,648 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 14:55:31,802 - INFO - root - [main:125] - ===================================================== +2025-06-05 14:55:31,802 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 14:55:31,802 - INFO - root - [main:127] - ===================================================== +2025-06-05 14:55:31,802 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 14:55:31,802 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 14:55:31,803 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 14:55:31,803 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 14:55:35,820 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 14:55:35,856 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 14:55:35,886 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:00:46,575 - INFO - root - [:98] - ================================================================= +2025-06-05 15:00:46,575 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:00:46,575 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:00:46,575 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:00:46,575 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:00:46,740 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:00:46,741 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:00:46,741 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:00:46,741 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:00:46,741 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:00:46,741 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:00:46,741 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:01:16,104 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:01:16,137 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:01:16,166 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:01:27,783 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 15:01:31,017 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 15:06:48,480 - INFO - root - [:98] - ================================================================= +2025-06-05 15:06:48,480 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:06:48,480 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:06:48,480 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:06:48,480 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:06:48,650 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:06:48,650 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:06:48,650 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:06:48,651 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:06:48,651 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:06:48,653 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:06:48,654 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:06:52,624 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:06:52,671 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:06:52,699 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:07:21,162 - INFO - root - [:98] - ================================================================= +2025-06-05 15:07:21,162 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:07:21,162 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:07:21,162 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:07:21,163 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:07:21,326 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:07:21,326 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:07:21,326 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:07:21,328 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:07:21,328 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:07:21,328 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:07:21,328 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:07:24,776 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:07:24,817 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:07:24,837 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:08:59,453 - INFO - root - [:98] - ================================================================= +2025-06-05 15:08:59,453 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:08:59,453 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:08:59,453 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:08:59,454 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:08:59,610 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:08:59,610 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:08:59,610 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:08:59,612 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:08:59,612 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:08:59,612 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:08:59,612 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:09:03,196 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:09:03,240 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:09:03,269 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:09:49,402 - INFO - root - [:98] - ================================================================= +2025-06-05 15:09:49,402 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:09:49,403 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:09:49,403 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:09:49,403 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:09:49,560 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:09:49,560 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:09:49,560 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:09:49,560 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:09:49,561 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:09:49,561 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:09:49,561 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:09:55,201 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:09:55,238 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:09:55,265 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:10:38,320 - INFO - root - [:98] - ================================================================= +2025-06-05 15:10:38,321 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:10:38,321 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:10:38,321 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:10:38,321 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:10:38,474 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:10:38,474 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:10:38,475 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:10:38,475 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:10:38,475 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:10:38,475 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:10:38,475 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:10:42,630 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:10:42,668 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:10:42,696 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:11:26,153 - INFO - root - [:98] - ================================================================= +2025-06-05 15:11:26,153 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:11:26,153 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:11:26,153 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:11:26,153 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:11:26,307 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:11:26,307 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:11:26,307 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:11:26,308 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:11:26,308 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:11:26,308 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:11:26,308 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:11:30,602 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:11:30,639 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:11:30,670 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:12:39,536 - INFO - root - [:98] - ================================================================= +2025-06-05 15:12:39,536 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:12:39,536 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:12:39,536 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:12:39,536 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:12:39,698 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:12:39,698 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:12:39,698 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:12:39,699 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:12:39,699 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:12:39,699 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:12:39,700 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:12:42,813 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:12:42,849 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:12:42,873 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:20:30,031 - INFO - root - [:98] - ================================================================= +2025-06-05 15:20:30,031 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:20:30,031 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:20:30,031 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:20:30,032 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:20:30,183 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:20:30,183 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:20:30,183 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:20:30,184 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:20:30,184 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:20:30,185 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:20:30,185 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:20:33,418 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:20:33,459 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:20:33,487 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:22:16,109 - INFO - root - [:98] - ================================================================= +2025-06-05 15:22:16,109 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:22:16,109 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:22:16,109 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:22:16,109 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:22:16,269 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:22:16,269 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:22:16,269 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:22:16,269 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:22:16,269 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:22:16,270 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:22:16,270 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:22:20,547 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:22:20,578 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:22:20,606 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:26:02,763 - INFO - root - [:98] - ================================================================= +2025-06-05 15:26:02,763 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:26:02,764 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:26:02,764 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:26:02,764 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:26:02,920 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:26:02,920 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:26:02,920 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:26:02,920 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:26:02,920 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:26:02,920 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:26:02,921 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:27:36,410 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:27:36,450 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:27:36,473 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:29:10,081 - INFO - root - [:98] - ================================================================= +2025-06-05 15:29:10,081 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:29:10,082 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:29:10,082 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:29:10,082 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:29:10,239 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:29:10,239 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:29:10,239 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:29:10,240 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:29:10,241 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:29:10,241 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:29:10,241 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:29:13,653 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:29:13,692 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:29:13,717 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:29:30,860 - INFO - root - [:98] - ================================================================= +2025-06-05 15:29:30,861 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:29:30,861 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:29:30,861 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:29:30,861 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:29:31,018 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:29:31,018 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:29:31,018 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:29:31,019 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:29:31,019 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:29:31,019 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:29:31,019 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:29:34,373 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:29:34,412 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:29:34,438 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:33:49,552 - INFO - root - [:98] - ================================================================= +2025-06-05 15:33:49,552 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:33:49,552 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:33:49,552 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:33:49,552 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:33:49,720 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:33:49,720 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:33:49,720 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:33:49,721 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:33:49,721 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:33:49,721 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:33:49,722 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:33:54,898 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:33:54,934 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:33:54,960 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:35:29,562 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 15:35:32,617 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 15:35:39,970 - INFO - root - [:98] - ================================================================= +2025-06-05 15:35:39,970 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:35:39,970 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:35:39,970 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:35:39,970 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:35:40,132 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:35:40,132 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:35:40,132 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:35:40,132 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:35:40,133 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:35:40,133 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:35:40,134 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:35:43,954 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:35:43,995 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:35:44,023 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:39:12,092 - INFO - root - [:98] - ================================================================= +2025-06-05 15:39:12,092 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:39:12,092 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:39:12,092 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:39:12,092 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:39:12,244 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:39:12,245 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:39:12,245 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:39:12,245 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:39:12,245 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:39:12,246 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:39:12,246 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:39:15,632 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:39:15,669 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:39:15,693 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:39:38,715 - INFO - root - [:98] - ================================================================= +2025-06-05 15:39:38,715 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:39:38,715 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:39:38,715 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:39:38,715 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:39:38,868 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:39:38,868 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:39:38,869 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:39:38,869 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:39:38,869 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:39:38,869 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:39:38,869 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:39:43,910 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:39:43,949 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:39:43,972 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:39:56,846 - INFO - root - [:98] - ================================================================= +2025-06-05 15:39:56,846 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:39:56,846 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:39:56,846 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:39:56,846 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:39:56,998 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:39:56,998 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:39:56,998 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:39:56,999 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:39:56,999 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:39:56,999 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:39:56,999 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:40:05,041 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:40:05,077 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:40:05,105 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:44:52,865 - INFO - root - [:98] - ================================================================= +2025-06-05 15:44:52,865 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:44:52,865 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:44:52,865 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:44:52,865 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:44:53,023 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:44:53,023 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:44:53,023 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:44:53,024 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:44:53,024 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:44:53,024 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:44:53,025 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:44:57,267 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:44:57,305 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:44:57,334 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 15:45:46,063 - INFO - root - [handle_input:91] - 上料按钮被点击 +2025-06-05 15:45:48,060 - INFO - root - [handle_output:97] - 下料按钮被点击 +2025-06-05 15:50:16,896 - INFO - root - [handle_input:91] - 上料按钮被点击 +2025-06-05 15:52:41,410 - INFO - root - [:98] - ================================================================= +2025-06-05 15:52:41,410 - INFO - root - [:99] - 应用程序启动 +2025-06-05 15:52:41,410 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 15:52:41,410 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 15:52:41,410 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 15:52:41,566 - INFO - root - [main:125] - ===================================================== +2025-06-05 15:52:41,566 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 15:52:41,566 - INFO - root - [main:127] - ===================================================== +2025-06-05 15:52:41,567 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 15:52:41,567 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 15:52:41,567 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 15:52:41,567 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 15:52:44,788 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 15:52:44,824 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 15:52:44,852 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:01:54,238 - INFO - root - [:98] - ================================================================= +2025-06-05 16:01:54,238 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:01:54,238 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:01:54,238 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:01:54,238 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:01:54,396 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:01:54,396 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:01:54,396 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:01:54,396 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:01:54,396 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:01:54,397 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:01:54,397 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:01:58,601 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:01:58,632 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:01:58,653 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:02:15,862 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:02:17,494 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:03:26,246 - INFO - root - [:98] - ================================================================= +2025-06-05 16:03:26,246 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:03:26,246 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:03:26,246 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:03:26,246 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:03:26,402 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:03:26,402 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:03:26,402 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:03:26,402 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:03:26,402 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:03:26,403 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:03:26,403 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:07:22,524 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:07:22,568 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:07:22,600 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:08:57,317 - INFO - root - [:98] - ================================================================= +2025-06-05 16:08:57,317 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:08:57,317 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:08:57,317 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:08:57,317 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:08:57,481 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:08:57,481 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:08:57,481 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:08:57,482 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:08:57,482 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:08:57,483 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:08:57,483 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:09:00,918 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:09:00,954 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:09:00,978 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:10:51,477 - CRITICAL - root - [global_exception_handler:18] - 未捕获的异常: Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/main.py", line 200, in + main() + File "/Users/meng/work/tengzhi/jiateng_ws/main.py", line 190, in main + exit_code = app.exec() +KeyboardInterrupt + +2025-06-05 16:11:44,868 - INFO - root - [:98] - ================================================================= +2025-06-05 16:11:44,868 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:11:44,868 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:11:44,868 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:11:44,868 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:11:45,027 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:11:45,027 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:11:45,027 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:11:45,027 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:11:45,027 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:11:45,027 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:11:45,027 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:11:51,143 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:11:51,179 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:11:51,205 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:12:12,083 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:12:14,274 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:13:10,540 - INFO - root - [:98] - ================================================================= +2025-06-05 16:13:10,540 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:13:10,540 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:13:10,540 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:13:10,540 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:13:10,691 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:13:10,691 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:13:10,691 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:13:10,691 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:13:10,691 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:13:10,692 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:13:10,692 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:13:15,462 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:13:15,493 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:13:15,517 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:15:12,151 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:16:15,369 - INFO - root - [:98] - ================================================================= +2025-06-05 16:16:15,369 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:16:15,369 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:16:15,369 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:16:15,369 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:16:15,526 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:16:15,526 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:16:15,526 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:16:15,526 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:16:15,526 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:16:15,526 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:16:15,526 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:16:51,722 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:16:51,755 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:16:51,781 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:17:09,357 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:17:54,063 - INFO - root - [:98] - ================================================================= +2025-06-05 16:17:54,063 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:17:54,063 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:17:54,063 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:17:54,063 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:17:54,220 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:17:54,220 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:17:54,220 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:17:54,221 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:17:54,221 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:17:54,221 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:17:54,221 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:17:58,052 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:17:58,086 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:17:58,117 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:18:46,004 - INFO - root - [:98] - ================================================================= +2025-06-05 16:18:46,005 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:18:46,005 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:18:46,005 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:18:46,005 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:18:46,171 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:18:46,171 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:18:46,171 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:18:46,171 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:18:46,172 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:18:46,172 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:18:46,172 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:18:48,162 - CRITICAL - root - [global_exception_handler:18] - 未捕获的异常: Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/main.py", line 200, in + main() + File "/Users/meng/work/tengzhi/jiateng_ws/main.py", line 190, in main + exit_code = app.exec() +KeyboardInterrupt + +2025-06-05 16:18:52,696 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:18:52,733 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:18:52,766 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:20:18,874 - INFO - root - [:98] - ================================================================= +2025-06-05 16:20:18,874 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:20:18,874 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:20:18,874 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:20:18,874 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:20:19,024 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:20:19,024 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:20:19,024 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:20:19,024 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:20:19,024 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:20:19,025 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:20:19,025 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:20:49,519 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:20:49,554 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:20:49,589 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:21:15,439 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:22:55,240 - INFO - root - [:98] - ================================================================= +2025-06-05 16:22:55,240 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:22:55,240 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:22:55,240 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:22:55,240 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:22:55,399 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:22:55,400 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:22:55,400 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:22:55,400 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:22:55,400 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:22:55,401 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:22:55,401 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:23:00,592 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:23:00,634 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:23:00,665 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:23:59,397 - INFO - root - [:98] - ================================================================= +2025-06-05 16:23:59,397 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:23:59,397 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:23:59,397 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:23:59,397 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:23:59,554 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:23:59,555 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:23:59,555 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:23:59,555 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:23:59,555 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:23:59,556 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:23:59,556 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:24:04,207 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:24:04,247 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:24:04,272 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:28:46,384 - INFO - root - [:98] - ================================================================= +2025-06-05 16:28:46,384 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:28:46,384 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:28:46,384 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:28:46,385 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:28:46,541 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:28:46,541 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:28:46,541 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:28:46,541 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:28:46,542 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:28:46,542 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:28:46,542 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:28:47,855 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:28:52,644 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:28:52,685 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:28:52,711 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:29:29,686 - INFO - root - [:98] - ================================================================= +2025-06-05 16:29:29,686 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:29:29,686 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:29:29,686 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:29:29,686 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:29:29,852 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:29:29,852 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:29:29,852 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:29:29,852 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:29:29,853 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:29:29,853 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:29:29,853 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:29:40,825 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:29:40,840 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: 'PySide6.QtWidgets.QLineEdit' object has no attribute 'setTextAlignment' +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 10, in __init__ + super().__init__() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 14, in __init__ + self.init_ui() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 40, in init_ui + self.create_left_panel() + File "/Users/meng/work/tengzhi/jiateng_ws/ui/main_window_ui.py", line 156, in create_left_panel + self.order_edit.setTextAlignment(Qt.AlignCenter) +AttributeError: 'PySide6.QtWidgets.QLineEdit' object has no attribute 'setTextAlignment' +2025-06-05 16:29:47,695 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:29:57,240 - INFO - root - [:98] - ================================================================= +2025-06-05 16:29:57,240 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:29:57,240 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:29:57,240 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:29:57,240 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:29:57,400 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:29:57,401 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:29:57,401 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:29:57,401 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:29:57,401 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:29:57,401 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:29:57,401 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:30:00,984 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:30:01,019 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:30:01,047 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:30:37,677 - INFO - root - [:98] - ================================================================= +2025-06-05 16:30:37,677 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:30:37,677 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:30:37,677 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:30:37,677 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:30:37,824 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:30:37,824 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:30:37,824 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:30:37,824 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:30:37,824 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:30:37,825 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:30:37,825 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:30:41,638 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:30:41,676 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:30:41,699 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:30:50,606 - INFO - root - [:98] - ================================================================= +2025-06-05 16:30:50,606 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:30:50,606 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:30:50,607 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:30:50,607 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:30:50,774 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:30:50,774 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:30:50,774 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:30:50,774 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:30:50,774 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:30:50,775 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:30:50,775 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:30:54,147 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:30:54,187 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:30:54,217 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:33:54,373 - INFO - root - [:98] - ================================================================= +2025-06-05 16:33:54,373 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:33:54,373 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:33:54,373 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:33:54,373 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:33:54,526 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:33:54,526 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:33:54,526 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:33:54,526 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:33:54,526 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:33:54,527 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:33:54,527 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:33:57,913 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:33:57,950 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:33:57,975 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:34:30,914 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 16:34:44,156 - INFO - root - [:98] - ================================================================= +2025-06-05 16:34:44,157 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:34:44,157 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:34:44,157 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:34:44,157 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:34:44,307 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:34:44,308 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:34:44,308 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:34:44,308 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:34:44,308 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:34:44,308 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:34:44,308 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:34:47,538 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:34:47,577 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:34:47,602 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:38:54,467 - INFO - root - [:98] - ================================================================= +2025-06-05 16:38:54,467 - INFO - root - [:99] - 应用程序启动 +2025-06-05 16:38:54,467 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 16:38:54,467 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 16:38:54,467 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 16:38:54,687 - INFO - root - [main:125] - ===================================================== +2025-06-05 16:38:54,687 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 16:38:54,687 - INFO - root - [main:127] - ===================================================== +2025-06-05 16:38:54,687 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 16:38:54,687 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 16:38:54,687 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 16:38:54,688 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 16:38:59,885 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 16:38:59,918 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 16:38:59,946 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 16:57:31,634 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 17:08:45,559 - INFO - root - [:98] - ================================================================= +2025-06-05 17:08:45,559 - INFO - root - [:99] - 应用程序启动 +2025-06-05 17:08:45,559 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 17:08:45,559 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 17:08:45,559 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 17:08:45,714 - INFO - root - [main:125] - ===================================================== +2025-06-05 17:08:45,715 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 17:08:45,715 - INFO - root - [main:127] - ===================================================== +2025-06-05 17:08:45,715 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 17:08:45,715 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 17:08:45,716 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 17:08:45,716 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 17:08:53,663 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 17:08:53,707 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 17:08:53,733 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 17:12:48,563 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 17:18:28,768 - INFO - root - [:98] - ================================================================= +2025-06-05 17:18:28,768 - INFO - root - [:99] - 应用程序启动 +2025-06-05 17:18:28,768 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 17:18:28,768 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 17:18:28,769 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 17:18:28,925 - INFO - root - [main:125] - ===================================================== +2025-06-05 17:18:28,926 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 17:18:28,926 - INFO - root - [main:127] - ===================================================== +2025-06-05 17:18:28,926 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 17:18:28,927 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 17:18:28,927 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 17:18:28,928 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 17:18:32,759 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 17:18:32,807 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 17:18:32,834 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 17:27:15,059 - INFO - root - [:98] - ================================================================= +2025-06-05 17:27:15,059 - INFO - root - [:99] - 应用程序启动 +2025-06-05 17:27:15,059 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 17:27:15,059 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 17:27:15,059 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 17:27:15,230 - INFO - root - [main:125] - ===================================================== +2025-06-05 17:27:15,230 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 17:27:15,230 - INFO - root - [main:127] - ===================================================== +2025-06-05 17:27:15,230 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 17:27:15,230 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 17:27:15,231 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 17:27:15,232 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 17:27:18,964 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 17:27:19,013 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: 'MainWindow' object has no attribute 'tray_edit' +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 39, in __init__ + self.initialize_data() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 61, in initialize_data + self.tray_edit.setText("BAT-2025-001") +AttributeError: 'MainWindow' object has no attribute 'tray_edit' +2025-06-05 17:27:19,687 - INFO - root - [:98] - ================================================================= +2025-06-05 17:27:19,687 - INFO - root - [:99] - 应用程序启动 +2025-06-05 17:27:19,687 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 17:27:19,687 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 17:27:19,687 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 17:27:19,850 - INFO - root - [main:125] - ===================================================== +2025-06-05 17:27:19,850 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 17:27:19,850 - INFO - root - [main:127] - ===================================================== +2025-06-05 17:27:19,850 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 17:27:19,850 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 17:27:19,850 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 17:27:19,850 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 17:27:26,352 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 17:27:26,369 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: 'MainWindow' object has no attribute 'tray_edit' +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 39, in __init__ + self.initialize_data() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 61, in initialize_data + self.tray_edit.setText("BAT-2025-001") +AttributeError: 'MainWindow' object has no attribute 'tray_edit' +2025-06-05 17:27:28,963 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 17:27:41,803 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 17:27:41,844 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: 'MainWindow' object has no attribute 'tray_edit' +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 39, in __init__ + self.initialize_data() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 61, in initialize_data + self.tray_edit.setText("BAT-2025-001") +AttributeError: 'MainWindow' object has no attribute 'tray_edit' +2025-06-05 17:27:44,550 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-05 17:28:12,314 - INFO - root - [:98] - ================================================================= +2025-06-05 17:28:12,314 - INFO - root - [:99] - 应用程序启动 +2025-06-05 17:28:12,314 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 17:28:12,314 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 17:28:12,314 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 17:28:12,477 - INFO - root - [main:125] - ===================================================== +2025-06-05 17:28:12,477 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 17:28:12,477 - INFO - root - [main:127] - ===================================================== +2025-06-05 17:28:12,477 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 17:28:12,477 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 17:28:12,478 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 17:28:12,478 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 17:30:03,594 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 17:30:03,635 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 17:30:03,668 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 17:30:47,992 - INFO - root - [:98] - ================================================================= +2025-06-05 17:30:47,992 - INFO - root - [:99] - 应用程序启动 +2025-06-05 17:30:47,992 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-05 17:30:47,992 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-05 17:30:47,992 - INFO - root - [:102] - 日志文件: logs/app_2025-06-05.log +2025-06-05 17:30:48,152 - INFO - root - [main:125] - ===================================================== +2025-06-05 17:30:48,152 - INFO - root - [main:126] - 应用程序启动 +2025-06-05 17:30:48,153 - INFO - root - [main:127] - ===================================================== +2025-06-05 17:30:48,153 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-05 17:30:48,153 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-05 17:30:48,153 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-05 17:30:48,153 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-05 17:30:52,025 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-05 17:30:52,070 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-05 17:30:52,095 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) +2025-06-05 17:30:56,545 - INFO - root - [handle_stop:113] - 暂停按钮被点击 +2025-06-05 17:31:00,109 - INFO - root - [main:191] - 应用程序退出,退出码: 0 diff --git a/logs/app_2025-06-06.log b/logs/app_2025-06-06.log new file mode 100644 index 0000000..a2d72dc --- /dev/null +++ b/logs/app_2025-06-06.log @@ -0,0 +1,15 @@ +2025-06-06 15:33:51,679 - INFO - root - [:98] - ================================================================= +2025-06-06 15:33:51,679 - INFO - root - [:99] - 应用程序启动 +2025-06-06 15:33:51,679 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-06 15:33:51,679 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-06 15:33:51,679 - INFO - root - [:102] - 日志文件: logs/app_2025-06-06.log +2025-06-06 15:33:51,934 - INFO - root - [main:125] - ===================================================== +2025-06-06 15:33:51,935 - INFO - root - [main:126] - 应用程序启动 +2025-06-06 15:33:51,935 - INFO - root - [main:127] - ===================================================== +2025-06-06 15:33:51,935 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-06 15:33:51,935 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-06 15:33:51,937 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-06 15:33:51,937 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-06 15:33:56,785 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-06 15:33:56,832 - INFO - root - [__init__:44] - 主窗口已创建,用户: system +2025-06-06 15:33:56,863 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) diff --git a/logs/app_2025-06-07.log b/logs/app_2025-06-07.log new file mode 100644 index 0000000..1e1472f --- /dev/null +++ b/logs/app_2025-06-07.log @@ -0,0 +1,172 @@ +2025-06-07 09:03:35,618 - INFO - root - [:98] - ================================================================= +2025-06-07 09:03:35,618 - INFO - root - [:99] - 应用程序启动 +2025-06-07 09:03:35,618 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-07 09:03:35,618 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-07 09:03:35,618 - INFO - root - [:102] - 日志文件: logs/app_2025-06-07.log +2025-06-07 09:03:35,784 - INFO - root - [main:125] - ===================================================== +2025-06-07 09:03:35,784 - INFO - root - [main:126] - 应用程序启动 +2025-06-07 09:03:35,784 - INFO - root - [main:127] - ===================================================== +2025-06-07 09:03:35,784 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-07 09:03:35,784 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-07 09:03:35,786 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-07 09:03:35,786 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-07 09:03:39,742 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-07 09:03:39,796 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: name 'MvCamCtrldll' is not defined +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 37, in __init__ + self.camera_display = CameraDisplayWidget() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_display_widget.py", line 37, in __init__ + self.camera_manager = CameraManager.get_instance() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_manager.py", line 27, in get_instance + CameraManager._instance = CameraManager() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_manager.py", line 47, in __init__ + MvCamera.MV_CC_Initialize() + File "/Users/meng/work/tengzhi/jiateng_ws/camera/MvCameraControl_class.py", line 50, in MV_CC_Initialize + MvCamCtrldll.MV_CC_Initialize.restype = c_int +NameError: name 'MvCamCtrldll' is not defined +2025-06-07 09:05:18,994 - INFO - root - [:98] - ================================================================= +2025-06-07 09:05:18,994 - INFO - root - [:99] - 应用程序启动 +2025-06-07 09:05:18,994 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-07 09:05:18,994 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-07 09:05:18,994 - INFO - root - [:102] - 日志文件: logs/app_2025-06-07.log +2025-06-07 09:05:19,168 - INFO - root - [main:125] - ===================================================== +2025-06-07 09:05:19,168 - INFO - root - [main:126] - 应用程序启动 +2025-06-07 09:05:19,168 - INFO - root - [main:127] - ===================================================== +2025-06-07 09:05:19,169 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-07 09:05:19,169 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-07 09:05:19,169 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-07 09:05:19,169 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-07 09:05:24,244 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-07 09:05:24,289 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: name 'MvCamCtrldll' is not defined +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 37, in __init__ + self.camera_display = CameraDisplayWidget() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_display_widget.py", line 37, in __init__ + self.camera_manager = CameraManager.get_instance() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_manager.py", line 27, in get_instance + CameraManager._instance = CameraManager() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_manager.py", line 47, in __init__ + MvCamera.MV_CC_Initialize() + File "/Users/meng/work/tengzhi/jiateng_ws/camera/MvCameraControl_class.py", line 50, in MV_CC_Initialize + MvCamCtrldll.MV_CC_Initialize.restype = c_int +NameError: name 'MvCamCtrldll' is not defined +2025-06-07 09:06:11,419 - INFO - root - [:98] - ================================================================= +2025-06-07 09:06:11,419 - INFO - root - [:99] - 应用程序启动 +2025-06-07 09:06:11,420 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-07 09:06:11,420 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-07 09:06:11,420 - INFO - root - [:102] - 日志文件: logs/app_2025-06-07.log +2025-06-07 09:06:11,559 - INFO - root - [main:125] - ===================================================== +2025-06-07 09:06:11,559 - INFO - root - [main:126] - 应用程序启动 +2025-06-07 09:06:11,559 - INFO - root - [main:127] - ===================================================== +2025-06-07 09:06:11,559 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-07 09:06:11,559 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-07 09:06:11,560 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-07 09:06:11,560 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-07 09:06:15,973 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-07 09:06:16,015 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: name 'MvCamCtrldll' is not defined +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 37, in __init__ + self.camera_display = CameraDisplayWidget() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_display_widget.py", line 37, in __init__ + self.camera_manager = CameraManager.get_instance() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_manager.py", line 27, in get_instance + CameraManager._instance = CameraManager() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_manager.py", line 47, in __init__ + MvCamera.MV_CC_Initialize() + File "/Users/meng/work/tengzhi/jiateng_ws/camera/MvCameraControl_class.py", line 50, in MV_CC_Initialize + MvCamCtrldll.MV_CC_Initialize.restype = c_int +NameError: name 'MvCamCtrldll' is not defined +2025-06-07 09:06:24,249 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-07 09:07:01,441 - INFO - root - [:98] - ================================================================= +2025-06-07 09:07:01,441 - INFO - root - [:99] - 应用程序启动 +2025-06-07 09:07:01,441 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-07 09:07:01,441 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-07 09:07:01,441 - INFO - root - [:102] - 日志文件: logs/app_2025-06-07.log +2025-06-07 09:07:01,585 - INFO - root - [main:125] - ===================================================== +2025-06-07 09:07:01,585 - INFO - root - [main:126] - 应用程序启动 +2025-06-07 09:07:01,585 - INFO - root - [main:127] - ===================================================== +2025-06-07 09:07:01,585 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-07 09:07:01,585 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-07 09:07:01,586 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-07 09:07:01,586 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-07 09:07:05,135 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-07 09:07:05,179 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: 'MainWindow' object has no attribute 'camera_display' +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 38, in __init__ + self.material_content_layout.addWidget(self.camera_display) +AttributeError: 'MainWindow' object has no attribute 'camera_display' +2025-06-07 09:07:08,971 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-07 09:07:27,619 - INFO - root - [:98] - ================================================================= +2025-06-07 09:07:27,619 - INFO - root - [:99] - 应用程序启动 +2025-06-07 09:07:27,619 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-07 09:07:27,619 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-07 09:07:27,619 - INFO - root - [:102] - 日志文件: logs/app_2025-06-07.log +2025-06-07 09:07:27,757 - INFO - root - [main:125] - ===================================================== +2025-06-07 09:07:27,757 - INFO - root - [main:126] - 应用程序启动 +2025-06-07 09:07:27,757 - INFO - root - [main:127] - ===================================================== +2025-06-07 09:07:27,758 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-07 09:07:27,758 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-07 09:07:27,758 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-07 09:07:27,758 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-07 09:07:31,806 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-07 09:07:31,858 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: 'MainWindow' object has no attribute 'camera_display' +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 58, in __init__ + self.connect_signals() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 83, in connect_signals + self.camera_display.signal_camera_status.connect(self.handle_camera_status) +AttributeError: 'MainWindow' object has no attribute 'camera_display' +2025-06-07 09:08:04,413 - INFO - root - [:98] - ================================================================= +2025-06-07 09:08:04,413 - INFO - root - [:99] - 应用程序启动 +2025-06-07 09:08:04,413 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-07 09:08:04,413 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-07 09:08:04,413 - INFO - root - [:102] - 日志文件: logs/app_2025-06-07.log +2025-06-07 09:08:04,549 - INFO - root - [main:125] - ===================================================== +2025-06-07 09:08:04,550 - INFO - root - [main:126] - 应用程序启动 +2025-06-07 09:08:04,550 - INFO - root - [main:127] - ===================================================== +2025-06-07 09:08:04,550 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-07 09:08:04,550 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-07 09:08:04,550 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-07 09:08:04,550 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-07 09:08:07,854 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-07 09:08:07,897 - CRITICAL - root - [handle_login:86] - 创建或显示主窗口时发生错误: name 'MvCamCtrldll' is not defined +Traceback (most recent call last): + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/login_widget.py", line 82, in handle_login + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/main_window.py", line 37, in __init__ + self.camera_display = CameraDisplayWidget() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_display_widget.py", line 37, in __init__ + self.camera_manager = CameraManager.get_instance() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_manager.py", line 27, in get_instance + CameraManager._instance = CameraManager() + File "/Users/meng/work/tengzhi/jiateng_ws/widgets/camera_manager.py", line 47, in __init__ + MvCamera.MV_CC_Initialize() + File "/Users/meng/work/tengzhi/jiateng_ws/camera/MvCameraControl_class.py", line 50, in MV_CC_Initialize + MvCamCtrldll.MV_CC_Initialize.restype = c_int +NameError: name 'MvCamCtrldll' is not defined +2025-06-07 09:08:10,965 - INFO - root - [main:191] - 应用程序退出,退出码: 0 +2025-06-07 09:10:03,526 - INFO - root - [:98] - ================================================================= +2025-06-07 09:10:03,526 - INFO - root - [:99] - 应用程序启动 +2025-06-07 09:10:03,526 - INFO - root - [:100] - Python version: 3.10.9 (main, Mar 1 2023, 12:20:14) [Clang 14.0.6 ] +2025-06-07 09:10:03,527 - INFO - root - [:101] - Working directory: /Users/meng/work/tengzhi/jiateng_ws +2025-06-07 09:10:03,527 - INFO - root - [:102] - 日志文件: logs/app_2025-06-07.log +2025-06-07 09:10:03,669 - INFO - root - [main:125] - ===================================================== +2025-06-07 09:10:03,669 - INFO - root - [main:126] - 应用程序启动 +2025-06-07 09:10:03,669 - INFO - root - [main:127] - ===================================================== +2025-06-07 09:10:03,670 - INFO - root - [load_config:34] - 已加载配置文件: config/app_config.json +2025-06-07 09:10:03,670 - INFO - root - [main:135] - 配置信息 - 启用串口: False, 启用键盘监听: False +2025-06-07 09:10:03,670 - INFO - root - [install_menu_translator:12] - 已安装菜单翻译器 +2025-06-07 09:10:03,670 - INFO - root - [main:176] - 已设置中文翻译器,翻译路径: /Users/meng/anaconda3/lib/python3.10/site-packages/PySide6/Qt/translations,加载状态: True +2025-06-07 09:10:07,872 - INFO - root - [handle_login:81] - 正在创建主窗口,用户ID: system, 姓名: system, 公司: Default Corp +2025-06-07 09:10:07,924 - INFO - root - [__init__:68] - 主窗口已创建,用户: system +2025-06-07 09:10:07,957 - INFO - root - [handle_login:84] - 主窗口已显示(最大化) diff --git a/main.py b/main.py new file mode 100644 index 0000000..f8d5d81 --- /dev/null +++ b/main.py @@ -0,0 +1,200 @@ +import sys +import logging +import os +import tempfile +import traceback +from logging.handlers import TimedRotatingFileHandler +from datetime import datetime +from PySide6.QtWidgets import QApplication, QMessageBox +from PySide6.QtCore import QTranslator, QLocale, QLibraryInfo +from widgets.login_widget import LoginWidget +from utils.menu_translator import MenuTranslator +from utils.config_loader import ConfigLoader + +# 自定义异常处理器 +def global_exception_handler(exctype, value, tb): + """全局异常处理器,捕获未处理的异常并记录日志""" + error_msg = ''.join(traceback.format_exception(exctype, value, tb)) + logging.critical(f"未捕获的异常: {error_msg}") + + # 如果已经有QApplication实例,显示错误对话框 + if QApplication.instance(): + QMessageBox.critical(None, "系统错误", + f"发生了未处理的错误:\n{value}\n\n请联系管理员并提供日志文件。") + + # 调用原始的异常处理器 + sys.__excepthook__(exctype, value, tb) + +# 安装全局异常处理器 +sys.excepthook = global_exception_handler + +# 设置日志目录 +log_dir = 'logs' +temp_log_dir = None + +# 尝试使用应用程序目录 +try: + if not os.path.exists(log_dir): + os.makedirs(log_dir, exist_ok=True) + + # 测试目录是否可写 + test_file = os.path.join(log_dir, 'test_write.tmp') + with open(test_file, 'w') as f: + f.write('test') + os.remove(test_file) + + logging.basicConfig(level=logging.INFO, format='%(message)s') + logging.info(f"使用应用程序日志目录: {os.path.abspath(log_dir)}") + +except (OSError, PermissionError) as e: + # 如果应用程序目录不可用或不可写,使用临时目录 + temp_log_dir = os.path.join(tempfile.gettempdir(), 'app_logs') + log_dir = temp_log_dir + + try: + if not os.path.exists(log_dir): + os.makedirs(log_dir, exist_ok=True) + + logging.basicConfig(level=logging.INFO, format='%(message)s') + logging.info(f"无法使用应用程序日志目录,原因: {e}") + logging.info(f"使用临时日志目录: {log_dir}") + except Exception as e2: + # 如果临时目录也失败,只使用控制台输出 + print(f"无法创建日志目录,将只使用控制台输出: {e2}") + logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +# 配置全局日志 +# 使用日期命名日志文件 +today = datetime.now().strftime('%Y-%m-%d') +log_file_path = os.path.join(log_dir, f'app_{today}.log') + +try: + # 创建一个TimedRotatingFileHandler,每天轮换一次日志文件 + file_handler = TimedRotatingFileHandler( + log_file_path, + when='midnight', # 每天午夜轮换 + interval=1, # 轮换间隔为1天 + backupCount=30, # 保留30天的日志 + encoding='utf-8' # 使用UTF-8编码 + ) + + # 配置日志格式 + log_format = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - [%(funcName)s:%(lineno)d] - %(message)s') + file_handler.setFormatter(log_format) + + # 控制台输出处理器 + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setFormatter(log_format) + + # 配置根日志记录器 + root_logger = logging.getLogger() + root_logger.setLevel(logging.INFO) # 将默认级别设为INFO,减少DEBUG级别的输出 + # 清除已有的handlers + for handler in root_logger.handlers[:]: + root_logger.removeHandler(handler) + root_logger.addHandler(file_handler) + root_logger.addHandler(console_handler) + + logging.info("=================================================================") + logging.info("应用程序启动") + logging.info(f"Python version: {sys.version}") + logging.info(f"Working directory: {os.getcwd()}") + logging.info(f"日志文件: {log_file_path}") + +except Exception as e: + # 如果文件处理器创建失败,仅使用控制台输出 + logging.error(f"无法设置日志文件,将只使用控制台输出: {e}") + + # 确保根logger至少有一个控制台处理器 + root_logger = logging.getLogger() + if not root_logger.handlers: + console_handler = logging.StreamHandler(sys.stdout) + console_format = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - [%(funcName)s:%(lineno)d] - %(message)s') + console_handler.setFormatter(console_format) + root_logger.addHandler(console_handler) + + logging.info("=================================================================") + logging.info("应用程序启动 (仅控制台日志)") + logging.info(f"Python version: {sys.version}") + logging.info(f"Working directory: {os.getcwd()}") + +def main(): + """主程序入口""" + + app = QApplication(sys.argv) + logging.info("=====================================================") + logging.info(" 应用程序启动 ") + logging.info("=====================================================") + + try: + # 读取配置 + config = ConfigLoader.get_instance() + # 打印关键配置信息 + enable_serial_ports = config.get_value('app.features.enable_serial_ports', False) + enable_keyboard_listener = config.get_value('app.features.enable_keyboard_listener', False) + logging.info(f"配置信息 - 启用串口: {enable_serial_ports}, 启用键盘监听: {enable_keyboard_listener}") + + # 设置中文翻译器 + translator = QTranslator(app) + # 使用兼容新旧版本的方式获取翻译路径 + try: + # 新版本API + translations_path = QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath) + except AttributeError: + # 旧版本API + translations_path = QLibraryInfo.location(QLibraryInfo.TranslationsPath) + + # 尝试加载翻译文件 + translation_loaded = translator.load("qt_zh_CN", translations_path) + + # 如果加载失败,尝试在可执行文件目录下查找翻译文件 + if not translation_loaded and getattr(sys, 'frozen', False): + # 打包后的应用 + app_dir = os.path.dirname(sys.executable) + possible_paths = [ + os.path.join(app_dir, "translations"), + os.path.join(app_dir, "PySide6", "translations"), + os.path.join(app_dir, "Qt", "translations"), + ] + + for path in possible_paths: + if os.path.exists(path): + if translator.load("qt_zh_CN", path): + translation_loaded = True + translations_path = path + break + + app.installTranslator(translator) + + # 设置应用程序的本地化 + locale = QLocale(QLocale.Chinese, QLocale.China) + QLocale.setDefault(locale) + + # 安装菜单翻译器 + MenuTranslator.install_menu_translator(app) + + logging.info(f"已设置中文翻译器,翻译路径: {translations_path},加载状态: {translation_loaded}") + + # 创建db目录(如果不存在) + os.makedirs('db', exist_ok=True) + + # 检查数据库是否存在,如果不存在则初始化 + if not os.path.exists('db/jtDB.db'): + from utils.init_db import init_database + init_database() + logging.info("初始化数据库完成") + + login_widget = LoginWidget() + login_widget.show() + + exit_code = app.exec() + logging.info(f"应用程序退出,退出码: {exit_code}") + sys.exit(exit_code) + + except Exception as e: + logging.critical(f"严重错误: {e}", exc_info=True) + print(f"严重错误: {e}") # 确保即使日志系统故障也能看到错误 + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ui/__pycache__/login_ui.cpython-310.pyc b/ui/__pycache__/login_ui.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9585f7c738389c4563ba39bc5506bd6e7357f76 GIT binary patch literal 2362 zcmZ8j&2Jk;6rcUHz5Z;He$i5bkWhU|+9DOHMTj=)2T~fh) z-xvCs&L2fW{z78>(}DN^Msx)xMwsFeU!jVxQq|X}=Id1V4Qlu%HT@jT`FWaGP*3#= zzC|s8HLvKGXh|U#2-BHyhcLrYHZ)phW|P!&DR?IJe3ENiciED|6SFbjy5V?9p)v1v zopa3PNwIM`jyh*!&Vw%S=K}vma5lIF{0pJW=38q)j7k@QHzKZ$h`N#(jq^d515g{h zjSG%{xJmq?w_$P!RT!ZvGw+c_g{e%tQ=pm*oa*<8PN;!lC%O4x$?abKaG|XVYdIlC ze;SNv1}086NMGqGTZ%$@q_46e($M#oD!BRu#3?t5;m^If)rMk-P3BIU$eTx|-;b<1HrU zN-K1_{E?CrY`g8XqR6%%k$+CiUX7eEn)RLT((Gywelp7et#{nnWw(XUUX5mBch%HH{qB#WD`?4S%zG=tq4ln zP;UbV_=q%tbU->+nX#eth^_U=vews!#|hYAraW4}CeJPBM^u635QA-A*jiv~fvuWp zSp6a^2#wMPT#a1@c^TwdCNK93%*s3zg@+1gRK`41{^y|z^6Hp}YQM%y%X>0^)sepm zRucXu`2;HqGzFHE;H{GBPL1J7u&a*v8RmO8$Zex%^!KrvkQx2`=p(}iG7HI_%D9;> zoX8%r>OrtL2=VGdj@V!mBaEl{8dCfatY!Ah{$VEloBh|BJVjHiYOxxd+R`AEC0z!( zHbz(2-v7v}KnpoP0-kfdT>k)*G310lc>~DZC!)#q-{{F(MxKlTc}6B3o`JMJm~n^J zq(9vgnIIn6e)+(5UOayF{7L%oZo2(-IsrME;>GUXC6=2$V_Vdn{&;I`X`}71*>ERLo z$>yN{8SrBhSn#aV2b%)!+Wa2U^eSZJt55Jz8K0b47=Gg9%C&hO< z#j+iua*7ov#g|ooGej=c&jua~u>jGchn3XkqB7*5QeYKK$^e>t&2yR^$KkXDOu+NA#?$f6a_s8G}IcbFz4M{4!h{MOC3%v=`@D2AzTR=)NbAhvGOGa2THb$Vp@=@ zE2}KY3oam91b^q+o#0Zy9Gbrjg$T+H3vmlc;Rf&8qSQ#(_5$#Ow?eHJV@)19yxpM% zz_MFN_DZYmc9)X!O{ipU03JjGvBWMu!l1((x|o8MF9xBz4yVxan$n6+0QZ^`a<@I= zg?O1_m8_i&8kEkXpJl(TNrc0A9v z$M&}u_a`=qPY*9B!q<_9ZPv^Xc?PNh;$cgjRhvI00T?%@5$}Gk1tJhyQ8E8M?R(g3#_th AR{#J2 literal 0 HcmV?d00001 diff --git a/ui/__pycache__/main_window_ui.cpython-310.pyc b/ui/__pycache__/main_window_ui.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..735750309d64c0a8e543db1d2ca37573ade3ea92 GIT binary patch literal 15939 zcmdU0>vvPvmDknVk}SV%AUu>9ny3M6aCpQtB|soRz~R+&*6l+TzOs>#Y;$xK5?9WU z7z#-sq0KvxR8I43GLW`pl0Zn;nosj#{(`$^&6>4}Z0pPPLs#ZQ)|%D%?S1aOzSmMZ zZNH7Rd~_cBJoY*J{LbF{9E~+LMm+c%{bc*G-X}bsKTyK?=SSjx{1+ZWpm{VU=gBLo zlJ~0KyifJz{i;77Py_j(8q9~(P(G}N^9^c4KB7kQQ8k*6sj+;c+L({4afRx8b4~eX zwK?CSw&YvY)_j}V#`(Tnd%i>MP&^NMG`|)&?a=}mWy+^^YQe*vWT=YXJ;}HcJ-9!e z9sPcGR2w^Kgbsc`s|{y#BY1FM`e-JH(g#IW+n0WPtf(XL$o8?v?8NT*MC{;^^wC_# ztlaEO?a?!N)ZCp(YZ>uKHgghf?-J>J#%MTrcs!TY^^8FIfnwp<_M)zjjUs5`i;QBU1Os<#=31#&w@U9aJxWleD4^`jftdUcn|7>#Gdod zXC?~oBa-o`isn(hXFWrTrfA;NVb!PkH2-OjimB3q_zq|xEsXD=)}Tf39n!kBnAUh& zQNvn1(=ZaznudH@v(|!~sMe~rfhMN4YaRG*q;j;}sdb?=t}W6QBezLgqTPn?W^JXm zR9l9U7Hzq<0y(W(Lc1N`ZQ30&eb(dmsO?y$RYq)ndA_%2P;szCaS|rttgsq^?wRtG zm1&RSDS66XO_^3W=F_~IZ`#XoKb2}8wCo@FYB}o6o%wR+wd<8HuiX0Vja%2>o4x+~ z%K0;MzdAGfyBo7NewqCk9b^;eAsH|Nh2l8YDx6AXN3(h=WyA{^T?)>Tte(plL6IqB zCo)Ee%Zu3$6vJQ0%{|{MWJIASpBWwQIXNbd_vnaC9Lx5M zWYZK)ohgb~y3DugMbM3fjl6CKVeT5AojX0C#$vx6#k zV&-&gJk6_nMzAGHo)lt8`|LDgNc*R}DD!hX!0`ZPHb`@*ho&&gsW8$FCC^Bh=30+X zY)V0X6tQSIrUm6^+E25OoJK9kl(KeQZ$fUIYcwO)j2a>NF>5qiHPBCsqu*Ap*~&HB zP_wP3W}BmCyOas^-$DIpVJQt}x>akSG)qNf;Hwy>2=Xv@^J?|dnd*(7SDTShjZ;8H z)dmUz2m}dWl>;wg$xcC(hJX85PBS7pi9~9Mc4|u@GdMP?r5st&(J_%v=VW=LfT$Ud z4vGw9AO+bd3X*IiKA0H=1mqwI3{B0Dx*al0;*AIqS(K$ECy}a^XwWst3j5PyI6GP} zBFH;Do*vAO4y%z|W=Kzsr$;k6L1JM+NR5i@@G-N75t9k4FO%9y(U8_O zb8t)1yhzx=?G(EW0nHWf+GcMvi*eW&_CcI|tw>Rfza6n=U%N8V?hd-Dos$f%@9HW(pV z^6hDXBM*_I6u~U+M_g?v0xzUUw4fz(t#K+4{L@^^lR%9Y9xvdWU`n+K>#bw43n@t` z>a9c%n%jW?0?Bv88^^rI6$)FGiAAotcF3h`z6ptJWO)=RLJQuP=6qw$Fq6Fhm9k$C zj4%T5T7)#OSrTRxVZ_!Wj4URC=#h~|lO|e@1IJ}c(Q=dKr?^hI5#|0`5Nj#7;{4(d zA&A}v{E^7jj?(sW$FN5Wy=9&ZNOvL~cBH$eJ>^CE;*lk0Kken)YI2t9Z6nL<@(|EN zj;V!tXg5=mqbQ|Jj+SEt%gZqbN6Q@?EeA&trY4S-Ge;{BTLF%u^1~c?v>2BqP?jh| zf=6yQdra``-eIRgnl*DPcw`A~y-ka2L6-V%)a@=ix#=zw|0}g7vyE=%-kDydHQQwi z=c>E>Ev*F~pVn%kx6Em^a`Zd3wkc&&DJkW zDM;;HR8H*Vxmk^|bed;HcX>7VaHd-Al$_sgp5HYry=$=xx_F&>&{9v?tM`%?r1y@j zo3doM2P@ub_TN(uX)JU4damDxT7Bhv?Ah+KT9~qSOka6}cAHtd54D$?@wL3xJ+4%r znOafah<4YSDJh}LDP>CNCX{Y+N$4hrgl@ukExF%>9%aonREIg;jM!#KE6D&prVMN@ z--|f);n7wwT|emhU8~sd!iE0w7L8?<=|Y+%-ak-V-z8|ssYudiw!DTnoZ3Epl7nj>yTyAr4 zxeYv6T;9)IZsT!DS=f%2wmW2DJE&KhTx_qA3t4}=SuWRjE4LEM2+gZl@V`<*;qxyHND(k@Wk z$$5m0ySRr35ql6Lxl4XbX_NJLnH)&&cW_O~{chCS?c#p7#XYa_Zf<)IsP@!wxyQj} zlIiw>Zm)~Wy)G{II=I~H;BpUhx!1wvL;60n^$@qZAF=&4ob5;NcTo-P+mj)EK)ai1 z9|rBit`R(34wXXM>MjqrKA_3F1iCux5lPh%k3Qm-9Z=KL8j}m>3W&&5aIyRcwQd2q%S4Ix51)Fh=|J;O=u4)dyMSnlc7}7ZF^;>6Bdx!9G zw@pK|mxHF))t8fjb>ojE3S+sfmgpYjzgki`iPS zsa`PhuVW7%dSK1^-t`;S^!Bcs_(46Pzjp{9OX#sXYG!=le(0l)?2gxip1RJihKx?E zl0L1(PwVcl%|rNXNlcnn(K9nIzg9Vay{Zu_19irh>7|b~wl!>7)*WH(8cr;#ZSQCf z;<<%8pLzP#*-Nihp8s^hy;tV>0#6bts{e}NNs0OFS&X<|%O{Uz^~{zkxnv|IdypnB zx#Zg6+pDv6>y1XrWd6_aBhZwQ9+E`W)+8%0J8 zscpIJ@F=WsU9?kHl+)yMf%~tK+$j3vxy<2XnT#&Tcoz3k5JjLij*GDoz+`HOUA#oh z&fdev(&HH;$`!Q(>d-@39ymQNnbNNunTGziXO=bJv-}cYZBuRu_tr?7|ufyZXAunVIFeQeyK zj6er8B{&%t%cyyC9f99@6$8wV=Q4UmOHtYg9pl@Yg5krtY6NA<@H1`999DraV4-7k zBU)z1<6ctSyl|z#nHh%@lfLN#r>3u2X~uUemHFb0aj&y90!mp2WuPP1XsZt&CG4g8 z&GX-AC(LcOD{(*7qJAPuC+870IZ)9%kHXoDEU|i$++x8#DZHMGNNYS;>y!#hd9F_w{ zDf_KUqLBc*brm+6LNGL>3zHnaFgb7)!XMMf43{Iao*va>BaLhj;VOfBY1XNBGv`T% z2<|6YVAn_&}sZP+R4- z0F#^WAdfLZK0$tQdB%pVGfIui8U^!iRKi~iPQt+q?$2zHP#4u?S@6>=aNi;{2W{8F z9Fx>&H{IG+Tk^=E)0KPUVH<7M4To%2(!|UrnM4iKS%ka4LR~NWX0Z8PNMfNEkuZdv zHk7>Si1Dol-*s4b9@zK<32_1dZ2gH9^@Lwe65rq)86-Q!`lC4gGYpL)0&lBFS4QMQ zdqpSGK6rU8(O1d=S1M@w9|#g?p2E)p;LLcF*p7G zO!LDF<+<)p%)R@hY!Pia zP2kGa&*y$K?W%Dst7TFqe)lJ4UcFkm_-^&}i*v6$U%m0_+?BV{0)|z2`=y<8WgUf%&YDT2iD(DCsLi^{pDV5i-Qchzo{#D z0CLa|Gg`eqYh3_j#0?F(yC5D+V^x}E-!On=lXwJjB*=ai->2XZ1u6yKqu>V=5dJVM z2|=-a6db02mDcDU(%9+t>(PwbK|53`vHQ{mOV3UESQ{_`ENE)XDLo4gcY`ifi{nx& z1-9h#W1~6R)MO*X!hYJaI0<9Eh_AUNuK2wRHg0Y0fr(HzS;j+~2T9|x{s=cI%{!Q& zL&qM*{Y9V@C@Uqo4+HSMdB^GY+)CqSO%Im*Q=sIX8Ngmtig#mxm2;OWH?B*ehv%Yl zW(u1U-Ya|N?MR*d2Za{fk2lQB%V%dUe`FKWN|I&TpQ!xPE4OaG@W(IC%N=&>v+D!! zKmGBGbGL5(9^0OtK&*A#cmMH=r(KPtEo%!cUH!az^Wx0Qp93dcG)IRqs)9 z+SR$Ie`}Z9kwaJ?F}eUjoI80BwhKDp`LJ=oITOhc8x!J3n02v-0=7&@A>VGxw`iq; zHU!C_lpeoMdcU7$1KPjEjvBT`ElyC4gdNTzJ3FCK7KJ<8x>}E-x1gzogv#`ILtc`$v;NewCm>XH|@h%M6SdZ(+)qcwDSCKY|L7Qwc`%l)%jk=rRA0RzqthQ%uD@$KfvzLU9#wHanh@I&RJ#!jByX2+UZiZ+E`4}q zCpAk(cUCINFT(nnX&d$tH7k_t-Lcg-_VUPmyqZY%Qb2Gm{sDmzV~4{d(y=2BP(CZJ zw2Raxs}IsRVQ;IQ3omU7C!B|>PVYT!fW6@9+4~Z7k&*X9i>zr%U$KW8c$LSMeCl}z7 z&@r4335dRnh|@NOJ%}@|U5UXGgo^5yc4W{;)*JGCq_D=xDuqgmda&RoZm*}hx`yY1 zFLK3@dy7xL(f?=gMeijUZt%veOwh#u0C;M^n*>GgqB9)8(u6k&-buW<8|f%7!kYuY zOnEV#>U7_ABFp(p08bGUo;u1)@cM&O`fUVMCOqLy5?WYN^2@Rl=h0IPJq6HHfP0E^ zPXy^51Y>yHKrr?u(hh(^@5>0pOrW9%h9*$)Gsw9sA6IU^B!P+%NSp$N1793e;z=rc zih`90s;hg(rB7;_0hyK^!_rK zh%?miJch8B)~-rUTDjR%L`Kij#6ME-6AGS2zz*OY3?I@V+{Ihj9GQs(ypu!He-$^2 zEO;5Cmc}V~4uJ|E8$po;8v%xogqBPox0RZpY&Dx@TQw}%%q<=xX1*l%Fr9 z2f@CQQt~dgO1)a}xJR5PI7F?6b`RQ!T=HvC(xfPL31H)h#}W6*{NVr|Z+UcrHZo@L zh-*rYscn+-=6l6ctuFZV&@*CI&nFH6PEixuA4WA#UE(p)qqc>kFX5q}Y)5OxD57!{ zCKQLY76@T$@pjBsW%|R)nKMphN zX>#Z~lxrwiqYZD0kEij(csL~;@Iao0Kyw~#-$_DCTON;leapSe0V$ikiX?VuAi|MCAKZoU|=?X(+`2FWn)85DpSmiknO9hw%H~ zQV<3>3?lSR(p&ftZ-u2exBWOdmBk)Tx8X$f*`mlTmGJ8VQxyGXt7}fIlKpBhpU`K3 zUWm?%9&%y0AQ!JaUAZu&%03ty?%YPEg=5x53(Ft0aP3lVt)Mziff-TmS&Tarcd>6L_2Iah+m+lCE9rG!qK^#*YF@hkm_kDy)4n<=SYY*5lr}c*Y*xz z5G=zlQ?@O`f)7?YQ$ z|39%%yOL16f9~{m`Z|?P-x6hFWv!4p&$|=>Z^3oy5#ZA1W*PktL?9phOBFivH08Ko ztkk{co7GO1FIrut!erL*Ot8cw(AFFnx z*7aoCQt;ujIV@X%4ro^)2h_Zy*Cyf)Kn=ks)B4?~X5PGPx}+-SUXv~<>8M&T7J1=8 zM)Cmf2iY&qZ^qlvbWmIA`XWJEfVLMFq4oc3xn9yD2|-yrp+1_o1E?J+e(KHrq+wIb`(=wML@ zSg0vrw|JYHy+A?24(J3kI?1whz_;1kk4flPgCG*7A6>+~e#L8s-cvzeyDv;$O;~uO z{Lv3H2)!q|U0a}j%Py2Ab(sEX2mEO}kcVYSUaLWRr{(X1_*Ywydy;e$O>H`oeaNDV zk`bL8ON@ea_(N71^|8Cq4iMViHtiR*4fhk*fQm89a%P9wpNBx>w9rarNk zT~ly-fpXO(P#rJI1AKXh-#kI(8At!&Qed%XGB_H7^9fEhxtBmkI|nV|JTMgwSYxu) z6s)@#MiIg&sTYXK-Ss^@gjLEzR9g*`!{J5TzPZ$xsNLs&s9GE zXIo{N7k8<1>_%haG6io?a1nuYA$bMEkil(5bWoz9aBSbi#8XO&LEVnGqmdJjo-;G%Ro+FTD0FMNwN;10@A0D=qXkMqQ}htcar~@SRI!tAzFz ztrh~>hS|L+(Y97ag&Y73D_3qN)+AS)HQ zUs5bdF~X<;7%Jx|=M@Tg8EI8buaX2ETE+#SBM9k!M+g%~MEZx?*^AVvOssaz_5b1b za!q#_jnO}WiMUDu9XH~)6#R~YgdNzj@GlsJxQ6_sawMq?Bs=JLoTGS?gWqvRQmOoy zR>aTsQbsJ5I#EpLWC{P?l7FoxdZD=9Z$a5WOF0Hhx`*HqcOce)|H4WHVGnRO7+w{Qd;T$8imYv26K)M}iT8!$ z;U$q};hylfnwtdG7)W**Ee9Syj2qC6YY*b5sq}lnf&k|pzD4J^Z~VB1pO^9P2H7ns zFFhheN3YoAwLE!Q_{kIB!5NM74L?}S%2!b>L}K5D81Z?M9b+ORJ*_k_2agF#5|2js VJ95(LVqE^9^?uKyKul@({x1s)Pf7p) literal 0 HcmV?d00001 diff --git a/ui/__pycache__/settings_ui.cpython-310.pyc b/ui/__pycache__/settings_ui.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0c7c5f15a9a0b6e4cd689c45d684027d3e8ef88 GIT binary patch literal 8224 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 literal 0 HcmV?d00001 diff --git a/ui/login_ui.py b/ui/login_ui.py new file mode 100644 index 0000000..93ab639 --- /dev/null +++ b/ui/login_ui.py @@ -0,0 +1,85 @@ +from PySide6.QtWidgets import ( + QWidget, QLabel, QLineEdit, QPushButton, QComboBox, QGridLayout, QHBoxLayout, QVBoxLayout +) +from PySide6.QtGui import QFont +from PySide6.QtCore import Qt + +class LoginUI(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + self.setWindowTitle("用户登录") + self.resize(350, 220) + self.init_ui() + + def init_ui(self): + font_title = QFont("微软雅黑", 18, QFont.Bold) + font_label = QFont("微软雅黑", 12) + font_input = QFont("微软雅黑", 12) + font_version = QFont("微软雅黑", 8) + + # 标题 + self.label_title = QLabel("腾龙集团MES管理系统") + self.label_title.setFont(font_title) + self.label_title.setStyleSheet("color: #1a237e;") + self.label_title.setAlignment(Qt.AlignCenter) + self.label_title.setFixedHeight(40) + + # 工号 + self.label_user = QLabel("工号:") + self.label_user.setFont(font_label) + self.label_user.setFixedWidth(50) + self.edit_user = QLineEdit() + self.edit_user.setFont(font_input) + self.edit_user.setFixedHeight(28) + + # 密码 + self.label_pwd = QLabel("密码:") + self.label_pwd.setFont(font_label) + self.label_pwd.setFixedWidth(50) + self.edit_pwd = QLineEdit() + self.edit_pwd.setFont(font_input) + self.edit_pwd.setEchoMode(QLineEdit.Password) + self.edit_pwd.setFixedHeight(28) + + # 按钮 + self.btn_login = QPushButton("登陆") + self.btn_close = QPushButton("关闭") + self.btn_login.setFixedWidth(90) + self.btn_close.setFixedWidth(90) + self.btn_login.setFixedHeight(30) + self.btn_close.setFixedHeight(30) + + btn_layout = QHBoxLayout() + btn_layout.addStretch(1) + btn_layout.addWidget(self.btn_login) + btn_layout.addSpacing(30) + btn_layout.addWidget(self.btn_close) + btn_layout.addStretch(1) + + # 版本标签 + self.version_label = QLabel("版本: 1.0.0") + self.version_label.setFont(font_version) + self.version_label.setStyleSheet("color: #666666;") + self.version_label.setAlignment(Qt.AlignRight) + + # 表单布局 + form_layout = QGridLayout() + form_layout.setHorizontalSpacing(10) + form_layout.setVerticalSpacing(18) + form_layout.addWidget(self.label_user, 1, 0) + form_layout.addWidget(self.edit_user, 1, 1) + form_layout.addWidget(self.label_pwd, 2, 0) + form_layout.addWidget(self.edit_pwd, 2, 1) + + # 主布局 + main_layout = QVBoxLayout() + main_layout.addSpacing(8) + main_layout.addWidget(self.label_title) + main_layout.addSpacing(5) + main_layout.addLayout(form_layout) + main_layout.addSpacing(10) + main_layout.addLayout(btn_layout) + main_layout.addStretch(1) + main_layout.addWidget(self.version_label) + main_layout.addSpacing(5) + self.setLayout(main_layout) \ No newline at end of file diff --git a/ui/main_window_ui.py b/ui/main_window_ui.py new file mode 100644 index 0000000..8794fed --- /dev/null +++ b/ui/main_window_ui.py @@ -0,0 +1,742 @@ +from PySide6.QtWidgets import ( + QMainWindow, QWidget, QLabel, QGridLayout, QVBoxLayout, QHBoxLayout, + QTableWidget, QTableWidgetItem, QHeaderView, QFrame, QSplitter, + QPushButton, QLineEdit, QAbstractItemView +) +from PySide6.QtGui import QFont, QAction, QBrush, QColor +from PySide6.QtCore import Qt + +class MainWindowUI(QMainWindow): + def __init__(self): + super().__init__() + self.setWindowTitle("腾智微丝产线包装系统") + self.resize(1200, 800) + self.init_ui() + + def init_ui(self): + # 设置字体 + self.title_font = QFont("微软雅黑", 16, QFont.Bold) + self.second_title_font = QFont("微软雅黑", 14, QFont.Bold) + self.normal_font = QFont("微软雅黑", 12) + self.small_font = QFont("微软雅黑", 9) + + # 创建菜单栏 + self.create_menu() + + # 创建中央部件 + self.central_widget = QWidget() + self.setCentralWidget(self.central_widget) + + # 创建主布局 - 水平分割 + self.main_layout = QHBoxLayout(self.central_widget) + self.main_layout.setContentsMargins(5, 5, 5, 5) + self.main_layout.setSpacing(5) + + # 创建左侧面板 + self.left_panel = QWidget() + self.left_layout = QVBoxLayout(self.left_panel) + self.left_layout.setContentsMargins(0, 0, 0, 0) + self.left_layout.setSpacing(5) + self.create_left_panel() + + # 创建右侧面板 + self.right_panel = QWidget() + self.right_layout = QVBoxLayout(self.right_panel) + self.right_layout.setContentsMargins(0, 0, 0, 0) + self.right_layout.setSpacing(5) + self.create_right_panel() + + # 添加左右面板到主布局 + self.main_layout.addWidget(self.left_panel, 1) # 左侧面板占比较小 + self.main_layout.addWidget(self.right_panel, 2) # 右侧面板占比较大 + + def create_menu(self): + # 创建菜单栏 + self.menubar = self.menuBar() + + # 用户操作菜单 + self.user_menu = self.menubar.addMenu("用户操作页") + self.main_action = QAction("主页面", self) + self.user_menu.addAction(self.main_action) + + # 系统设置菜单 + self.system_menu = self.menubar.addMenu("系统设置") + self.settings_action = QAction("设置页面", self) + self.system_menu.addAction(self.settings_action) + + def create_left_panel(self): + # 标题 + self.title_label = QLabel("腾智微丝产线包装系统") + self.title_label.setFont(self.title_font) + self.title_label.setAlignment(Qt.AlignCenter) + self.title_label.setStyleSheet("color: #1a237e; padding: 10px; background-color: #f5f5f5; border-radius: 4px;") + self.left_layout.addWidget(self.title_label) + + # 项目信息表格 - 使用QFrame包裹,添加边框 + self.project_frame = QFrame() + self.project_frame.setFrameShape(QFrame.StyledPanel) + self.project_frame.setLineWidth(1) + self.project_frame.setFixedHeight(150) # 调整这个值可以控制整体高度 + self.project_layout = QVBoxLayout(self.project_frame) + self.project_layout.setContentsMargins(5, 5, 5, 5) + + # 项目表格 + self.project_table = QTableWidget(4, 5) + self.project_table.setHorizontalHeaderLabels(["项目", "用电", "数量", "产量", "开机率"]) + self.project_table.setVerticalHeaderLabels(["当日", "当月", "当年", "累计"]) + self.project_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + self.project_table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) + self.project_table.setEditTriggers(QTableWidget.NoEditTriggers) # 设置为不可编辑 + + # 设置表格样式 + self.project_table.setStyleSheet(""" + QTableWidget { + border: none; + gridline-color: #dddddd; + } + QHeaderView::section { + background-color: #f0f0f0; + padding: 4px; + border: 1px solid #cccccc; + font-weight: bold; + } + """) + + self.project_layout.addWidget(self.project_table) + + self.left_layout.addWidget(self.project_frame) + + # 任务信息区域 - 使用QFrame包裹,添加边框 + self.task_frame = QFrame() + self.task_frame.setFrameShape(QFrame.StyledPanel) + self.task_frame.setLineWidth(1) + self.task_frame.setFixedHeight(180) + self.task_layout = QVBoxLayout(self.task_frame) + self.task_layout.setContentsMargins(8, 8, 8, 8) + + # 任务标签 + self.task_label = QLabel("任务") + self.task_label.setFont(self.normal_font) + self.task_label.setAlignment(Qt.AlignLeft) + self.task_label.setStyleSheet("font-weight: bold; color: #333333;") + self.task_layout.addWidget(self.task_label) + + # 任务表格 - 使用合并单元格实现一级二级标题 + self.task_table = QTableWidget(3, 4) # 3行4列:一级标题行、二级标题行、数据行 + self.task_table.setEditTriggers(QTableWidget.NoEditTriggers) # 设置为不可编辑 + self.task_table.horizontalHeader().setVisible(False) + self.task_table.verticalHeader().setVisible(False) + self.task_table.setShowGrid(True) + + # 设置列宽均等 + self.task_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + # 第一行:订单量和完成量 (一级标题) + self.task_table.setSpan(0, 0, 1, 2) # 订单量跨2列 + self.task_table.setSpan(0, 2, 1, 2) # 完成量跨2列 + + order_item = QTableWidgetItem("订单量") + order_item.setTextAlignment(Qt.AlignCenter) + order_item.setFont(self.normal_font) + self.task_table.setItem(0, 0, order_item) + + completed_item = QTableWidgetItem("完成量") + completed_item.setTextAlignment(Qt.AlignCenter) + completed_item.setFont(self.normal_font) + self.task_table.setItem(0, 2, completed_item) + + # 第二行:二级标题 + headers = ["总生产数量", "总生产公斤", "已完成数量", "已完成公斤"] + for col, header in enumerate(headers): + item = QTableWidgetItem(header) + item.setTextAlignment(Qt.AlignCenter) + item.setFont(self.small_font) + self.task_table.setItem(1, col, item) + + + # 设置行高 + self.task_table.setRowHeight(0, 30) # 一级标题行高 + self.task_table.setRowHeight(1, 30) # 二级标题行高 + self.task_table.setRowHeight(2, 30) # 数据行高 + self.task_layout.addWidget(self.task_table) + + # 订单行 + self.order_layout = QHBoxLayout() + self.order_label = QLabel("订单") + self.order_label.setFont(QFont("微软雅黑", 12, QFont.Bold)) + self.order_label.setFixedHeight(30) + self.order_label.setStyleSheet("padding: 0 5px; color: #333333;") + + self.order_edit = QLineEdit() + self.order_edit.setReadOnly(True) + self.order_edit.setFont(QFont("微软雅黑", 12)) + self.order_edit.setText("ORD-2025-001") # 设置默认订单号 + self.order_edit.setStyleSheet("background-color: #f9f9f9; border: 1px solid #cccccc; border-radius: 3px; padding: 2px 5px;") + + self.order_layout.addWidget(self.order_label) + self.order_layout.addWidget(self.order_edit) + self.task_layout.addLayout(self.order_layout) + + self.left_layout.addWidget(self.task_frame) + + # 上料区 - 使用QFrame包裹,添加边框 + self.material_frame = QFrame() + self.material_frame.setFrameShape(QFrame.StyledPanel) + self.material_frame.setLineWidth(1) + self.material_frame.setFixedHeight(300) # 增加高度以匹配图片 + self.material_frame.setStyleSheet("QFrame { background-color: #f8f8f8; }") + self.material_layout = QHBoxLayout(self.material_frame) + self.material_layout.setContentsMargins(0, 0, 0, 0) + self.material_layout.setSpacing(0) + + # 上料区标签 + self.material_label = QLabel("上料区") + self.material_label.setFont(self.normal_font) + self.material_label.setAlignment(Qt.AlignCenter) + self.material_label.setFixedWidth(100) # 设置固定宽度 + self.material_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;") + self.material_layout.addWidget(self.material_label) + + # 上料区内容 - 这里可以添加更多控件 + self.material_content = QWidget() + self.material_content.setStyleSheet("background-color: black;") # 黑色背景适合显示相机画面 + self.material_content_layout = QVBoxLayout(self.material_content) + self.material_content_layout.setContentsMargins(0, 0, 0, 0) # 移除内边距以便相机画面填满 + self.material_layout.addWidget(self.material_content) + + self.left_layout.addWidget(self.material_frame) + + # 托盘号行 - 使用QFrame包裹,添加边框 + self.tray_frame = QFrame() + self.tray_frame.setFrameShape(QFrame.StyledPanel) + self.tray_frame.setLineWidth(1) + self.tray_layout = QHBoxLayout(self.tray_frame) + self.tray_layout.setContentsMargins(0, 0, 0, 0) + self.tray_layout.setSpacing(0) + + self.tray_label = QLabel("托盘号") + self.tray_label.setFont(self.normal_font) + self.tray_label.setAlignment(Qt.AlignCenter) + self.tray_label.setFixedWidth(100) # 设置固定宽度 + self.tray_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;") + self.tray_layout.addWidget(self.tray_label) + + self.tray_edit = QLineEdit() + self.tray_edit.setReadOnly(True) + self.tray_edit.setStyleSheet("border: none; padding: 5px 10px;") + self.tray_edit.setFont(QFont("微软雅黑", 12)) + self.tray_layout.addWidget(self.tray_edit) + + self.left_layout.addWidget(self.tray_frame) + + # 下料区 - 使用QFrame包裹,添加边框 + self.output_frame = QFrame() + self.output_frame.setFrameShape(QFrame.StyledPanel) + self.output_frame.setLineWidth(1) + self.output_frame.setFixedHeight(200) # 增加高度以匹配图片 + self.output_frame.setStyleSheet("QFrame { background-color: #f8f8f8; }") + self.output_layout = QHBoxLayout(self.output_frame) + self.output_layout.setContentsMargins(0, 0, 0, 0) + self.output_layout.setSpacing(0) + + # 下料区标签 + self.output_label = QLabel("下料") + self.output_label.setFont(self.normal_font) + self.output_label.setAlignment(Qt.AlignCenter) + self.output_label.setFixedWidth(100) # 设置固定宽度 + self.output_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;") + self.output_layout.addWidget(self.output_label) + + # 下料区内容 - 这里可以添加更多控件 + self.output_content = QWidget() + self.output_content.setStyleSheet("background-color: white;") + self.output_content_layout = QVBoxLayout(self.output_content) + self.output_content_layout.setContentsMargins(10, 10, 10, 10) + self.output_layout.addWidget(self.output_content) + + self.left_layout.addWidget(self.output_frame) + + # 产线控制区 - 使用QFrame包裹,添加边框 + self.control_frame = QFrame() + self.control_frame.setFrameShape(QFrame.StyledPanel) + self.control_frame.setLineWidth(1) + self.control_layout = QHBoxLayout(self.control_frame) + self.control_layout.setContentsMargins(0, 0, 0, 0) + self.control_layout.setSpacing(0) + + self.control_label = QLabel("产线") + self.control_label.setFont(self.normal_font) + self.control_label.setAlignment(Qt.AlignCenter) + self.control_label.setFixedWidth(100) # 设置固定宽度 + self.control_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;") + self.control_layout.addWidget(self.control_label) + + # 按钮容器 + self.button_container = QWidget() + self.button_layout = QGridLayout(self.button_container) + self.button_layout.setContentsMargins(10, 10, 10, 10) + self.button_layout.setSpacing(10) # 增加按钮间距 + + # 创建按钮并设置样式 + button_style = """ + QPushButton { + padding: 8px 16px; + font-weight: bold; + border-radius: 4px; + } + """ + + self.input_button = QPushButton("上料") + self.input_button.setFont(self.normal_font) + self.input_button.setStyleSheet(button_style + "background-color: #e3f2fd; border: 1px solid #2196f3;") + + self.output_button = QPushButton("下料") + self.output_button.setFont(self.normal_font) + self.output_button.setStyleSheet(button_style + "background-color: #fff8e1; border: 1px solid #ffc107;") + + self.start_button = QPushButton("开始") + self.start_button.setFont(self.normal_font) + self.start_button.setStyleSheet(button_style + "background-color: #e8f5e9; border: 1px solid #4caf50;") + + self.stop_button = QPushButton("暂停") + self.stop_button.setFont(self.normal_font) + self.stop_button.setStyleSheet(button_style + "background-color: #ffebee; border: 1px solid #f44336;") + + # 使用网格布局排列按钮 + self.button_layout.addWidget(self.input_button, 0, 0) + self.button_layout.addWidget(self.output_button, 0, 1) + self.button_layout.addWidget(self.start_button, 0, 2) + self.button_layout.addWidget(self.stop_button, 0, 3) + + self.control_layout.addWidget(self.button_container) + + self.left_layout.addWidget(self.control_frame) + + # 添加弹性空间,确保控件紧凑排列在顶部 + self.left_layout.addStretch() + + def create_right_panel(self): + # 创建右侧整体框架 + self.right_frame = QFrame() + self.right_frame.setFrameShape(QFrame.NoFrame) # 移除框架边框 + self.right_frame.setLineWidth(0) + self.right_layout.addWidget(self.right_frame) + + # 右侧整体使用垂直布局,不设置边距 + self.right_frame_layout = QVBoxLayout(self.right_frame) + self.right_frame_layout.setContentsMargins(0, 0, 0, 0) + self.right_frame_layout.setSpacing(0) + + # 创建一个垂直分割器,用于控制两个表格的高度比例 + self.right_splitter = QSplitter(Qt.Vertical) + + # 创建微丝产线表格的容器 + self.process_container = QWidget() + self.process_container_layout = QVBoxLayout(self.process_container) + self.process_container_layout.setContentsMargins(0, 0, 0, 0) + self.process_container_layout.setSpacing(0) + + # 创建包装记录表格的容器 + self.record_container = QWidget() + self.record_container_layout = QVBoxLayout(self.record_container) + self.record_container_layout.setContentsMargins(0, 0, 0, 0) + self.record_container_layout.setSpacing(0) + + # 创建微丝产线表格 + self.create_process_table() + self.process_container_layout.addWidget(self.process_frame) + + # 创建包装记录表格 + self.create_record_table() + self.record_container_layout.addWidget(self.record_frame) + + # 将两个容器添加到分割器中 + self.right_splitter.addWidget(self.process_container) + self.right_splitter.addWidget(self.record_container) + + # 设置初始大小比例:微丝产线占1/3,包装记录占2/3 + self.right_splitter.setSizes([100, 200]) # 比例为1:2 + + # 将分割器添加到右侧布局 + self.right_frame_layout.addWidget(self.right_splitter) + + # 添加一个通用的表格样式设置方法 + def setup_table_common(self, table, hide_headers=True): + """设置表格的通用样式和属性 + + Args: + table: 要设置的QTableWidget对象 + hide_headers: 是否隐藏默认的表头 + """ + # 设置为不可编辑 + table.setEditTriggers(QAbstractItemView.NoEditTriggers) + + # 隐藏默认表头 + if hide_headers: + table.horizontalHeader().setVisible(False) + table.verticalHeader().setVisible(False) + + # 显示网格线 + table.setShowGrid(True) + + # 移除外边框 + table.setFrameShape(QFrame.NoFrame) + + # 设置表格样式 + table.setStyleSheet(""" + QTableWidget { + gridline-color: #dddddd; + border: none; + background-color: white; + } + QTableWidget::item { + border: none; + padding: 3px; + } + QTableWidget::item:selected { + background-color: #e0e0ff; + color: black; + } + """) + + # 允许用户调整列宽 + table.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive) + table.horizontalHeader().setStretchLastSection(True) + + return table + + # 添加一个通用的表头项创建方法 + def create_header_item(self, text, font=None, alignment=Qt.AlignCenter, bg_color="#f8f8f8"): + """创建表头单元格项 + + Args: + text: 表头文本 + font: 字体,默认为None(使用self.normal_font) + alignment: 对齐方式 + bg_color: 背景色 + + Returns: + QTableWidgetItem: 创建的表头项 + """ + item = QTableWidgetItem(text) + item.setTextAlignment(alignment) + item.setFont(font or self.normal_font) + item.setBackground(QBrush(QColor(bg_color))) + return item + + def create_process_table(self): + """创建微丝产线表格,包含上料、检验、包装部分""" + # 创建微丝产线框架 + self.process_frame = QFrame() + self.process_frame.setFrameShape(QFrame.Box) + self.process_frame.setLineWidth(1) + self.process_frame.setStyleSheet("QFrame { border: 1px solid #dddddd; }") + self.process_layout = QVBoxLayout(self.process_frame) + self.process_layout.setContentsMargins(0, 0, 0, 0) + self.process_layout.setSpacing(0) + + # 微丝产线标题 + self.process_title = QLabel("微丝产线") + self.process_title.setFont(self.second_title_font) + self.process_title.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) + # 调整行高 + self.process_title.setFixedHeight(40) + self.process_title.setStyleSheet("background-color: #f8f8f8; padding: 5px; border-bottom: 1px solid #dddddd;") + self.process_layout.addWidget(self.process_title) + + + # 创建表格内容区域 + self.process_content = QWidget() + self.process_content_layout = QVBoxLayout(self.process_content) + self.process_content_layout.setContentsMargins(0, 0, 0, 0) + self.process_content_layout.setSpacing(0) + + # 创建表格 - 支持动态配置检验列数 + self.inspection_columns = 3 # 默认3列,可动态配置 + # TODO:后续从数据库中读取 + self.inspection_headers = ["外观", "线径", "电阻", "硬度", "强度"] # 默认检验标题 + total_columns = 2 + self.inspection_columns + 2 # 上料2列 + 检验N列 + 包装2列 + + self.process_table = QTableWidget(8, total_columns) # 8行:1行标题区域 + 1行列标题 + 6行数据 + + # 应用通用表格设置 + self.setup_table_common(self.process_table) + + # 设置行高 + self.process_table.setRowHeight(0, 30) # 标题区域行高 + self.process_table.setRowHeight(1, 30) # 列标题行高 + + # 设置数据行的行高 + for row in range(2, 8): # 工序行 + self.process_table.setRowHeight(row, 35) + + # 设置列宽 + self.set_process_table_column_widths() + + # 创建表头 - 合并单元格 + self.create_process_table_headers() + + # 填充表格内容 + self.fill_process_table_cells() + + # 添加表格到布局 + self.process_content_layout.addWidget(self.process_table) + self.process_layout.addWidget(self.process_content) + + def create_record_table(self): + """创建包装记录表格""" + # 创建包装记录框架 + self.record_frame = QFrame() + self.record_frame.setFrameShape(QFrame.Box) + self.record_frame.setLineWidth(1) + self.record_frame.setStyleSheet("QFrame { border: 1px solid #dddddd; }") # 移除 border-top: none; + self.record_layout = QVBoxLayout(self.record_frame) + self.record_layout.setContentsMargins(0, 0, 0, 0) + self.record_layout.setSpacing(0) + + # 包装记录标题 + self.record_title = QLabel("包装记录") + self.record_title.setFont(self.second_title_font) + self.record_title.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) + # 调整行高 + self.record_title.setFixedHeight(40) + self.record_title.setStyleSheet("background-color: #f8f8f8; padding: 5px; border-bottom: 1px solid #dddddd;") + self.record_layout.addWidget(self.record_title) + + # 创建表格 + self.record_table = QTableWidget(14, 7) # 14行7列:序号、订单、材质、规格、托号、轴包装号、重量 + + # 应用通用表格设置 + self.setup_table_common(self.record_table) + + # 设置列标题 + record_headers = ["序号", "订单", "材质", "规格", "托号", "轴包装号", "重量"] + for col, header in enumerate(record_headers): + self.record_table.setItem(0, col, self.create_header_item(header)) + + # 设置行高 + self.record_table.setRowHeight(0, 35) # 列标题行高 + self.record_table.setRowHeight(13, 35) # 合计行高 + + # 设置数据行的行高 + for row in range(1, 13): # 记录行 + self.record_table.setRowHeight(row, 35) + + # 设置列宽 + column_widths = [70, 220, 170, 170, 170, 170, 170] # 各列的默认宽度 + for col, width in enumerate(column_widths): + self.record_table.setColumnWidth(col, width) + + # 添加表格到布局 + self.record_layout.addWidget(self.record_table) + + # 填充表格内容 + self.fill_record_table_cells() + + # 添加一个通用的单元格创建方法 + def create_cell_item(self, text, alignment=Qt.AlignCenter): + """创建表格单元格项 + + Args: + text: 单元格文本 + alignment: 对齐方式 + + Returns: + QTableWidgetItem: 创建的单元格项 + """ + item = QTableWidgetItem(str(text)) + item.setTextAlignment(alignment) + return item + + def fill_process_table_cells(self): + """填充微丝产线表格单元格""" + # 工序工程数据 + process_data = ["拉丝", "退火", "检验", "包装", "入库", "出库"] + + # 填充工序数据 + for row in range(6): + # 设置序号 + self.process_table.setItem(row + 2, 0, self.create_cell_item(row + 1)) + + # 设置工序工程名称 + self.process_table.setItem(row + 2, 1, self.create_cell_item(process_data[row])) + + # 只为前3行设置数据 + if row < 3: + # 检验区域 - 动态列 + inspection_data = ["合格", f"{0.5 + row * 0.1:.1f}", f"{10 + row * 5}", f"{80 + row * 5}", f"{90 + row * 2}"] + for i in range(min(self.inspection_columns, len(inspection_data))): + self.process_table.setItem(row + 2, 2 + i, self.create_cell_item(inspection_data[i])) + + # 包装区域 - 贴标和称重 + packaging_start_col = 2 + self.inspection_columns + + self.process_table.setItem(row + 2, packaging_start_col, self.create_cell_item("已完成")) + self.process_table.setItem(row + 2, packaging_start_col + 1, self.create_cell_item(f"{50 + row * 10}")) + + def fill_record_table_cells(self): + """填充包装记录表格单元格""" + # 填充序号列 + for row in range(12): + self.record_table.setItem(row + 1, 0, self.create_cell_item(row + 1)) + + # 填充示例数据 + record_data = [ + ["ORD-2025-001", "不锈钢", "0.5mm", "T001", "A001", "50kg"], + ["ORD-2025-001", "不锈钢", "0.6mm", "T001", "A002", "55kg"], + ["ORD-2025-001", "不锈钢", "0.7mm", "T001", "A003", "60kg"], + ] + + # 只填充前3行 + for row in range(3): + for col, value in enumerate(record_data[row]): + self.record_table.setItem(row + 1, col + 1, self.create_cell_item(value)) + + # 设置合计行 + self.record_table.setItem(13, 0, self.create_header_item("合计")) + + # 轴数 + self.record_table.setItem(13, 3, self.create_header_item("轴数")) + self.record_table.setItem(13, 4, self.create_cell_item("0")) + + # 重量 + self.record_table.setItem(13, 5, self.create_header_item("重量")) + self.record_table.setItem(13, 6, self.create_cell_item("0.0")) + + def set_inspection_columns(self, columns, headers=None): + """设置检验列数和标题 + + Args: + columns: 检验列数量 + headers: 检验列标题列表,如果为None则使用默认标题 + """ + # 保存旧的列数 + old_column_count = self.process_table.columnCount() + + # 清除表头行的所有项目 + if old_column_count > 0: + for c_idx in range(old_column_count): + # 第0行 - 主标题 + item_r0 = self.process_table.takeItem(0, c_idx) + if item_r0: + del item_r0 + # 第1行 - 子标题 + item_r1 = self.process_table.takeItem(1, c_idx) + if item_r1: + del item_r1 + + # 更新检验列数 + self.inspection_columns = columns + + # 更新检验标题 + if headers is not None and len(headers) >= columns: + self.inspection_headers = headers + elif len(self.inspection_headers) < columns: + # 如果当前标题不足,扩展标题列表 + current_len = len(self.inspection_headers) + for i in range(current_len, columns): + self.inspection_headers.append(f"检验项{i+1}") + + # 计算总列数 + total_columns = 2 + self.inspection_columns + 2 # 上料2列 + 检验N列 + 包装2列 + self.process_table.setColumnCount(total_columns) + + # 重新设置列宽 + self.set_process_table_column_widths() + + # 重新创建表头 + self.create_process_table_headers() + + # 重新填充数据 + self.fill_process_table_cells() + + def create_process_table_headers(self): + """创建微丝产线表格的表头,实现合并单元格""" + # 第一行:上料、检验、包装标题区域 + + # 上料区域(2列) + self.process_table.setSpan(0, 0, 1, 2) + self.process_table.setItem(0, 0, self.create_header_item("上料")) + + # 检验区域(动态列数) + self.process_table.setSpan(0, 2, 1, self.inspection_columns) + self.process_table.setItem(0, 2, self.create_header_item("检验")) + + # 包装区域(2列) + packaging_start_col = 2 + self.inspection_columns + self.process_table.setSpan(0, packaging_start_col, 1, 2) + self.process_table.setItem(0, packaging_start_col, self.create_header_item("包装")) + + # 第二行:列标题 + # 上料区域列标题 + material_headers = ["序号", "工序工程"] + for col, header in enumerate(material_headers): + self.process_table.setItem(1, col, self.create_header_item(header)) + + # 检验区域列标题 - 可动态配置 + for i in range(self.inspection_columns): + header_text = "" + if i < len(self.inspection_headers): + header_text = self.inspection_headers[i] + else: + header_text = f"检验项{i+1}" # 如果没有定义足够的标题,使用默认标题 + + self.process_table.setItem(1, 2 + i, self.create_header_item(header_text)) + + # 包装区域列标题 + packaging_headers = ["贴标", "称重"] + for i, header in enumerate(packaging_headers): + self.process_table.setItem(1, packaging_start_col + i, self.create_header_item(header)) + + def set_process_table_column_widths(self): + """设置微丝产线表格的列宽 - 支持动态配置检验列""" + # 上料区域列宽 + self.process_table.setColumnWidth(0, 70) # 序号 + self.process_table.setColumnWidth(1, 190) # 工序工程 + + # 检验区域列宽 + for i in range(self.inspection_columns): + self.process_table.setColumnWidth(2 + i, 140) # 检验列 + + # 包装区域列宽 + packaging_start_col = 2 + self.inspection_columns + self.process_table.setColumnWidth(packaging_start_col, 140) # 贴标 + self.process_table.setColumnWidth(packaging_start_col + 1, 140) # 称重 + + def create_process_table_headers(self): + """创建微丝产线表格的表头,实现合并单元格""" + # 第一行:上料、检验、包装标题区域 + + # 上料区域(2列) + self.process_table.setSpan(0, 0, 1, 2) + self.process_table.setItem(0, 0, self.create_header_item("上料")) + + # 检验区域(动态列数) + self.process_table.setSpan(0, 2, 1, self.inspection_columns) + self.process_table.setItem(0, 2, self.create_header_item("检验")) + + # 包装区域(2列) + packaging_start_col = 2 + self.inspection_columns + self.process_table.setSpan(0, packaging_start_col, 1, 2) + self.process_table.setItem(0, packaging_start_col, self.create_header_item("包装")) + + # 第二行:列标题 + # 上料区域列标题 + material_headers = ["序号", "工序工程"] + for col, header in enumerate(material_headers): + self.process_table.setItem(1, col, self.create_header_item(header)) + + # 检验区域列标题 - 可动态配置 + for i in range(self.inspection_columns): + header_text = "" + if i < len(self.inspection_headers): + header_text = self.inspection_headers[i] + else: + header_text = f"检验项{i+1}" # 如果没有定义足够的标题,使用默认标题 + + self.process_table.setItem(1, 2 + i, self.create_header_item(header_text)) + + # 包装区域列标题 + packaging_headers = ["贴标", "称重"] + for i, header in enumerate(packaging_headers): + self.process_table.setItem(1, packaging_start_col + i, self.create_header_item(header)) \ No newline at end of file diff --git a/ui/settings_ui.py b/ui/settings_ui.py new file mode 100644 index 0000000..52e8902 --- /dev/null +++ b/ui/settings_ui.py @@ -0,0 +1,369 @@ +from PySide6.QtWidgets import ( + QWidget, QLabel, QLineEdit, QPushButton, QComboBox, QGridLayout, QHBoxLayout, QVBoxLayout, + QTabWidget, QFrame, QFormLayout, QGroupBox, QRadioButton, QSpacerItem, QSizePolicy, + QTableWidget, QTableWidgetItem, QHeaderView, QSlider +) +from PySide6.QtGui import QFont +from PySide6.QtCore import Qt + +class SettingsUI(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + self.init_ui() + + def init_ui(self): + # 设置字体 + self.title_font = QFont("微软雅黑", 14, QFont.Bold) + self.normal_font = QFont("微软雅黑", 10) + self.small_font = QFont("微软雅黑", 9) + + # 创建主布局 + self.main_layout = QVBoxLayout(self) + self.main_layout.setContentsMargins(10, 10, 10, 10) + + # 创建标题 + self.title_label = QLabel("系统设置") + self.title_label.setFont(self.title_font) + self.title_label.setAlignment(Qt.AlignCenter) + self.title_label.setStyleSheet("color: #1a237e; margin-bottom: 10px;") + self.main_layout.addWidget(self.title_label) + + # 创建选项卡部件 + self.tab_widget = QTabWidget() + self.tab_widget.setFont(self.normal_font) + self.main_layout.addWidget(self.tab_widget) + + # 创建各个选项卡 + self.create_camera_tab() + self.create_database_tab() + self.create_plc_tab() + self.create_push_tab() + self.create_auth_tab() + self.create_user_tab() + self.create_param_tab() + + def create_camera_tab(self): + # 相机设置选项卡 + self.camera_tab = QWidget() + self.camera_layout = QVBoxLayout(self.camera_tab) + self.camera_layout.setContentsMargins(20, 20, 20, 20) + + # 相机选择区域 + self.camera_select_group = QGroupBox("相机选择") + self.camera_select_group.setFont(self.normal_font) + self.camera_select_layout = QHBoxLayout() + + self.camera_label = QLabel("相机设备:") + self.camera_label.setFont(self.normal_font) + self.camera_combo = QComboBox() + self.camera_combo.setFont(self.normal_font) + self.camera_combo.setMinimumWidth(300) + + self.refresh_button = QPushButton("刷新设备") + self.refresh_button.setFont(self.normal_font) + + self.camera_select_layout.addWidget(self.camera_label) + self.camera_select_layout.addWidget(self.camera_combo) + self.camera_select_layout.addWidget(self.refresh_button) + self.camera_select_layout.addStretch(1) + self.camera_select_group.setLayout(self.camera_select_layout) + self.camera_layout.addWidget(self.camera_select_group) + + # 相机控制区域 + self.camera_control_group = QGroupBox("相机控制") + self.camera_control_group.setFont(self.normal_font) + self.camera_control_layout = QHBoxLayout() + + self.open_button = QPushButton("打开相机") + self.open_button.setFont(self.normal_font) + self.open_button.setFixedWidth(120) + + self.close_button = QPushButton("关闭相机") + self.close_button.setFont(self.normal_font) + self.close_button.setFixedWidth(120) + + self.test_button = QPushButton("测试预览") + self.test_button.setFont(self.normal_font) + self.test_button.setFixedWidth(120) + + self.camera_control_layout.addWidget(self.open_button) + self.camera_control_layout.addWidget(self.close_button) + self.camera_control_layout.addWidget(self.test_button) + self.camera_control_layout.addStretch(1) + self.camera_control_group.setLayout(self.camera_control_layout) + self.camera_layout.addWidget(self.camera_control_group) + + # 相机参数设置区域 + self.camera_params_group = QGroupBox("相机参数") + self.camera_params_group.setFont(self.normal_font) + self.camera_params_layout = QGridLayout() + self.camera_params_layout.setColumnStretch(1, 1) # 让滑块列占据更多空间 + + # 曝光时间 + self.exposure_label = QLabel("曝光时间:") + self.exposure_label.setFont(self.normal_font) + self.exposure_slider = QSlider(Qt.Horizontal) + self.exposure_slider.setMinimum(1000) + self.exposure_slider.setMaximum(50000) + self.exposure_slider.setValue(20000) + self.exposure_slider.setTickPosition(QSlider.TicksBelow) + self.exposure_slider.setTickInterval(5000) + self.exposure_value = QLabel("20000 μs") + self.exposure_value.setFont(self.normal_font) + self.exposure_value.setMinimumWidth(80) + + # 增益 + self.gain_label = QLabel("增益:") + self.gain_label.setFont(self.normal_font) + self.gain_slider = QSlider(Qt.Horizontal) + self.gain_slider.setMinimum(0) + self.gain_slider.setMaximum(100) + self.gain_slider.setValue(10) + self.gain_slider.setTickPosition(QSlider.TicksBelow) + self.gain_slider.setTickInterval(10) + self.gain_value = QLabel("10") + self.gain_value.setFont(self.normal_font) + self.gain_value.setMinimumWidth(80) + + # 帧率 + self.framerate_label = QLabel("帧率:") + self.framerate_label.setFont(self.normal_font) + self.framerate_slider = QSlider(Qt.Horizontal) + self.framerate_slider.setMinimum(1) + self.framerate_slider.setMaximum(30) + self.framerate_slider.setValue(15) + self.framerate_slider.setTickPosition(QSlider.TicksBelow) + self.framerate_slider.setTickInterval(5) + self.framerate_value = QLabel("15 fps") + self.framerate_value.setFont(self.normal_font) + self.framerate_value.setMinimumWidth(80) + + # 添加到布局 + self.camera_params_layout.addWidget(self.exposure_label, 0, 0) + self.camera_params_layout.addWidget(self.exposure_slider, 0, 1) + self.camera_params_layout.addWidget(self.exposure_value, 0, 2) + + self.camera_params_layout.addWidget(self.gain_label, 1, 0) + self.camera_params_layout.addWidget(self.gain_slider, 1, 1) + self.camera_params_layout.addWidget(self.gain_value, 1, 2) + + self.camera_params_layout.addWidget(self.framerate_label, 2, 0) + self.camera_params_layout.addWidget(self.framerate_slider, 2, 1) + self.camera_params_layout.addWidget(self.framerate_value, 2, 2) + + self.camera_params_group.setLayout(self.camera_params_layout) + self.camera_layout.addWidget(self.camera_params_group) + + # 相机设置按钮 + self.camera_buttons_layout = QHBoxLayout() + + self.get_params_button = QPushButton("获取参数") + self.get_params_button.setFont(self.normal_font) + self.get_params_button.setFixedWidth(120) + + self.set_params_button = QPushButton("设置参数") + self.set_params_button.setFont(self.normal_font) + self.set_params_button.setFixedWidth(120) + + self.save_camera_button = QPushButton("保存设置") + self.save_camera_button.setFont(self.normal_font) + self.save_camera_button.setFixedWidth(120) + + self.camera_buttons_layout.addStretch(1) + self.camera_buttons_layout.addWidget(self.get_params_button) + self.camera_buttons_layout.addWidget(self.set_params_button) + self.camera_buttons_layout.addWidget(self.save_camera_button) + + self.camera_layout.addLayout(self.camera_buttons_layout) + + # 预览区域 + self.preview_group = QGroupBox("相机预览") + self.preview_group.setFont(self.normal_font) + self.preview_layout = QVBoxLayout() + + self.preview_frame = QFrame() + self.preview_frame.setFrameShape(QFrame.Box) + self.preview_frame.setLineWidth(1) + self.preview_frame.setMinimumHeight(200) + self.preview_frame.setStyleSheet("background-color: black;") + + self.preview_layout.addWidget(self.preview_frame) + self.preview_group.setLayout(self.preview_layout) + self.camera_layout.addWidget(self.preview_group) + + # 添加弹性空间 + self.camera_layout.addStretch(1) + + self.tab_widget.addTab(self.camera_tab, "相机设置") + + def create_database_tab(self): + # 数据源设置选项卡 + self.database_tab = QWidget() + self.database_layout = QVBoxLayout(self.database_tab) + self.database_layout.setContentsMargins(20, 20, 20, 20) + + # 数据库类型选择 + self.db_type_group = QGroupBox("数据库类型") + self.db_type_group.setFont(self.normal_font) + self.db_type_layout = QHBoxLayout() + + self.sqlite_radio = QRadioButton("SQLite") + self.sqlite_radio.setFont(self.normal_font) + self.sqlite_radio.setChecked(True) + + self.pgsql_radio = QRadioButton("PostgreSQL") + self.pgsql_radio.setFont(self.normal_font) + + self.mysql_radio = QRadioButton("MySQL") + self.mysql_radio.setFont(self.normal_font) + + self.db_type_layout.addWidget(self.sqlite_radio) + self.db_type_layout.addWidget(self.pgsql_radio) + self.db_type_layout.addWidget(self.mysql_radio) + self.db_type_layout.addStretch(1) + self.db_type_group.setLayout(self.db_type_layout) + self.database_layout.addWidget(self.db_type_group) + + # 数据库连接设置 + self.db_conn_group = QGroupBox("连接设置") + self.db_conn_group.setFont(self.normal_font) + self.db_conn_layout = QFormLayout() + + self.host_label = QLabel("主机:") + self.host_label.setFont(self.normal_font) + self.host_input = QLineEdit() + self.host_input.setFont(self.normal_font) + self.host_input.setPlaceholderText("localhost") + + self.user_label = QLabel("用户:") + self.user_label.setFont(self.normal_font) + self.user_input = QLineEdit() + self.user_input.setFont(self.normal_font) + + self.password_label = QLabel("密码:") + self.password_label.setFont(self.normal_font) + self.password_input = QLineEdit() + self.password_input.setFont(self.normal_font) + self.password_input.setEchoMode(QLineEdit.Password) + + self.database_label = QLabel("数据库:") + self.database_label.setFont(self.normal_font) + self.database_input = QLineEdit() + self.database_input.setFont(self.normal_font) + self.database_input.setPlaceholderText("db/jtDB.db") + + self.port_label = QLabel("端口:") + self.port_label.setFont(self.normal_font) + self.port_input = QLineEdit() + self.port_input.setFont(self.normal_font) + + self.desc_label = QLabel("说明:") + self.desc_label.setFont(self.normal_font) + self.desc_input = QLineEdit() + self.desc_input.setFont(self.normal_font) + + self.db_conn_layout.addRow(self.host_label, self.host_input) + self.db_conn_layout.addRow(self.user_label, self.user_input) + self.db_conn_layout.addRow(self.password_label, self.password_input) + self.db_conn_layout.addRow(self.database_label, self.database_input) + self.db_conn_layout.addRow(self.port_label, self.port_input) + self.db_conn_layout.addRow(self.desc_label, self.desc_input) + + self.db_conn_group.setLayout(self.db_conn_layout) + self.database_layout.addWidget(self.db_conn_group) + + # 按钮区域 + self.db_buttons_layout = QHBoxLayout() + + self.test_conn_button = QPushButton("测试连接") + self.test_conn_button.setFont(self.normal_font) + self.test_conn_button.setFixedWidth(120) + + self.save_db_button = QPushButton("保存设置") + self.save_db_button.setFont(self.normal_font) + self.save_db_button.setFixedWidth(120) + + self.db_buttons_layout.addStretch(1) + self.db_buttons_layout.addWidget(self.test_conn_button) + self.db_buttons_layout.addSpacing(20) + self.db_buttons_layout.addWidget(self.save_db_button) + + self.database_layout.addLayout(self.db_buttons_layout) + self.database_layout.addStretch(1) + + self.tab_widget.addTab(self.database_tab, "数据源设置") + + def create_plc_tab(self): + # PLC设置选项卡 + self.plc_tab = QWidget() + self.plc_layout = QVBoxLayout(self.plc_tab) + self.plc_layout.setContentsMargins(20, 20, 20, 20) + + # 占位标签 + self.plc_placeholder = QLabel("PLC设置(待实现)") + self.plc_placeholder.setFont(self.normal_font) + self.plc_placeholder.setAlignment(Qt.AlignCenter) + self.plc_layout.addWidget(self.plc_placeholder) + self.plc_layout.addStretch(1) + + self.tab_widget.addTab(self.plc_tab, "PLC设置") + + def create_push_tab(self): + # 推送设置选项卡 + self.push_tab = QWidget() + self.push_layout = QVBoxLayout(self.push_tab) + self.push_layout.setContentsMargins(20, 20, 20, 20) + + # 占位标签 + self.push_placeholder = QLabel("推送设置(待实现)") + self.push_placeholder.setFont(self.normal_font) + self.push_placeholder.setAlignment(Qt.AlignCenter) + self.push_layout.addWidget(self.push_placeholder) + self.push_layout.addStretch(1) + + self.tab_widget.addTab(self.push_tab, "推送设置") + + def create_auth_tab(self): + # 授权设置选项卡 + self.auth_tab = QWidget() + self.auth_layout = QVBoxLayout(self.auth_tab) + self.auth_layout.setContentsMargins(20, 20, 20, 20) + + # 占位标签 + self.auth_placeholder = QLabel("授权设置(待实现)") + self.auth_placeholder.setFont(self.normal_font) + self.auth_placeholder.setAlignment(Qt.AlignCenter) + self.auth_layout.addWidget(self.auth_placeholder) + self.auth_layout.addStretch(1) + + self.tab_widget.addTab(self.auth_tab, "授权设置") + + def create_user_tab(self): + # 用户设置选项卡 + self.user_tab = QWidget() + self.user_layout = QVBoxLayout(self.user_tab) + self.user_layout.setContentsMargins(20, 20, 20, 20) + + # 占位标签 + self.user_placeholder = QLabel("用户设置(待实现)") + self.user_placeholder.setFont(self.normal_font) + self.user_placeholder.setAlignment(Qt.AlignCenter) + self.user_layout.addWidget(self.user_placeholder) + self.user_layout.addStretch(1) + + self.tab_widget.addTab(self.user_tab, "用户设置") + + def create_param_tab(self): + # 参数配置选项卡 + self.param_tab = QWidget() + self.param_layout = QVBoxLayout(self.param_tab) + self.param_layout.setContentsMargins(20, 20, 20, 20) + + # 占位标签 + self.param_placeholder = QLabel("参数配置(待实现)") + self.param_placeholder.setFont(self.normal_font) + self.param_placeholder.setAlignment(Qt.AlignCenter) + self.param_layout.addWidget(self.param_placeholder) + self.param_layout.addStretch(1) + + self.tab_widget.addTab(self.param_tab, "参数配置") \ No newline at end of file diff --git a/utils/__pycache__/config_loader.cpython-310.pyc b/utils/__pycache__/config_loader.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6a7b597ba2eacf7696bc535a9654cc9ad9b894c GIT binary patch literal 3340 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 literal 0 HcmV?d00001 diff --git a/utils/__pycache__/sql_utils.cpython-310.pyc b/utils/__pycache__/sql_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1332ee6721597b8551b654da373c3299670a65b GIT binary patch literal 2678 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 TP+G3_N3M&U7af5tc1!;UFNOZh literal 0 HcmV?d00001 diff --git a/utils/config_loader.py b/utils/config_loader.py new file mode 100644 index 0000000..d668bd9 --- /dev/null +++ b/utils/config_loader.py @@ -0,0 +1,130 @@ +import os +import json +import logging + +class ConfigLoader: + """配置加载器,用于加载和管理应用配置""" + + _instance = None + + @classmethod + def get_instance(cls): + """获取单例实例""" + if cls._instance is None: + cls._instance = ConfigLoader() + return cls._instance + + def __init__(self): + """初始化配置加载器""" + self.config = {} + self.config_file = os.path.join('config', 'app_config.json') + + # 创建配置目录(如果不存在) + os.makedirs('config', exist_ok=True) + + # 加载配置 + self.load_config() + + def load_config(self): + """加载配置文件""" + try: + if os.path.exists(self.config_file): + with open(self.config_file, 'r', encoding='utf-8') as f: + self.config = json.load(f) + logging.info(f"已加载配置文件: {self.config_file}") + else: + # 创建默认配置 + self.config = { + "app": { + "name": "腾智微丝产线包装系统", + "version": "1.0.0", + "features": { + "enable_serial_ports": False, + "enable_keyboard_listener": False + } + }, + "database": { + "type": "sqlite", + "path": "db/jtDB.db", + "host": "", + "port": "", + "user": "", + "password": "", + "name": "" + } + } + + # 保存默认配置 + self.save_config() + logging.info(f"已创建默认配置文件: {self.config_file}") + except Exception as e: + logging.error(f"加载配置文件失败: {e}") + # 使用默认配置 + self.config = { + "app": { + "name": "腾智微丝产线包装系统", + "version": "1.0.0", + "features": { + "enable_serial_ports": False, + "enable_keyboard_listener": False + } + } + } + + def save_config(self): + """保存配置到文件""" + try: + with open(self.config_file, 'w', encoding='utf-8') as f: + json.dump(self.config, f, indent=4, ensure_ascii=False) + logging.info(f"已保存配置文件: {self.config_file}") + return True + except Exception as e: + logging.error(f"保存配置文件失败: {e}") + return False + + def get_value(self, key_path, default=None): + """ + 获取配置值 + + Args: + key_path: 配置键路径,例如 "app.features.enable_serial_ports" + default: 默认值,如果配置项不存在则返回此值 + + Returns: + 配置值或默认值 + """ + keys = key_path.split('.') + value = self.config + + try: + for key in keys: + value = value[key] + return value + except (KeyError, TypeError): + return default + + def set_value(self, key_path, value): + """ + 设置配置值 + + Args: + key_path: 配置键路径,例如 "app.features.enable_serial_ports" + value: 要设置的值 + + Returns: + bool: 是否设置成功 + """ + keys = key_path.split('.') + config = self.config + + # 遍历路径中的所有键,除了最后一个 + for key in keys[:-1]: + if key not in config: + config[key] = {} + config = config[key] + + # 设置最后一个键的值 + config[keys[-1]] = value + + # 保存配置 + return self.save_config() \ No newline at end of file diff --git a/utils/init_db.py b/utils/init_db.py new file mode 100644 index 0000000..2cd4425 --- /dev/null +++ b/utils/init_db.py @@ -0,0 +1,46 @@ +from sql_utils import SQLUtils +import datetime + +def init_database(): + db = SQLUtils('sqlite', database='db/jtDB.db') + + # 创建用户表 + create_table_sql = """ + CREATE TABLE IF NOT EXISTS user ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username VARCHAR(50) NOT NULL UNIQUE, + password VARCHAR(100) NOT NULL, + create_time TIMESTAMP NOT NULL, + create_by VARCHAR(50) NOT NULL, + update_time TIMESTAMP, + update_by VARCHAR(50), + is_deleted BOOLEAN DEFAULT FALSE + ); + """ + + # 获取当前时间 + current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + + # 插入系统用户 + insert_system_user_sql = """ + INSERT OR IGNORE INTO user ( + username, password, create_time, create_by, is_deleted + ) VALUES ( + 'system', '123456', ?, 'system', FALSE + ); + """ + + try: + db.begin_transaction() + db.execute_query(create_table_sql) + db.execute_query(insert_system_user_sql, (current_time,)) + db.commit_transaction() + print("Database initialized successfully!") + except Exception as e: + db.rollback_transaction() + print(f"Error initializing database: {str(e)}") + finally: + db.close() + +if __name__ == "__main__": + init_database() \ No newline at end of file diff --git a/utils/menu_translator.py b/utils/menu_translator.py new file mode 100644 index 0000000..3149bd2 --- /dev/null +++ b/utils/menu_translator.py @@ -0,0 +1,19 @@ +from PySide6.QtCore import QObject, QEvent +import logging + +class MenuTranslator(QObject): + """菜单翻译器,用于翻译右键菜单等动态创建的菜单""" + + @staticmethod + def install_menu_translator(app): + """安装菜单翻译器""" + translator = MenuTranslator() + app.installEventFilter(translator) + logging.info("已安装菜单翻译器") + + def eventFilter(self, obj, event): + """事件过滤器,用于捕获菜单显示事件并翻译菜单项""" + if event.type() == QEvent.ContextMenu: + # 这里可以添加右键菜单翻译逻辑 + pass + return False \ No newline at end of file diff --git a/utils/sql_utils.py b/utils/sql_utils.py new file mode 100644 index 0000000..dc145bc --- /dev/null +++ b/utils/sql_utils.py @@ -0,0 +1,78 @@ +import sys + +try: + import psycopg2 +except ImportError: + psycopg2 = None + +try: + import sqlite3 +except ImportError: + sqlite3 = None + + +class SQLUtils: + def __init__(self, db_type, **kwargs): + self.db_type = db_type.lower() + self.conn = None + self.cursor = None + self.kwargs = kwargs + self.connect() + + def connect(self): + if self.db_type == 'pgsql' or self.db_type == 'postgresql': + if not psycopg2: + raise ImportError('psycopg2 is not installed') + self.conn = psycopg2.connect(**self.kwargs) + elif self.db_type == 'sqlite' or self.db_type == 'sqlite3': + if not sqlite3: + raise ImportError('sqlite3 is not installed') + self.conn = sqlite3.connect(self.kwargs.get('database', ':memory:')) + else: + raise ValueError(f'Unsupported db_type: {self.db_type}') + self.cursor = self.conn.cursor() + + def execute_query(self, sql, params=None): + if params is None: + params = () + self.cursor.execute(sql, params) + self.conn.commit() + + def execute_update(self, sql, params=None): + try: + self.cursor.execute(sql,params) + self.conn.commit() + except Exception as e: + self.conn.rollback() + raise e + + def begin_transaction(self) -> None: + """开始事务""" + if self.db_type in ['sqlite', 'sqlite3']: + self.execute_query('BEGIN TRANSACTION') + else: + self.conn.autocommit = False + + def commit_transaction(self) -> None: + """提交事务""" + self.conn.commit() + if self.db_type not in ['sqlite', 'sqlite3']: + self.conn.autocommit = True + + def rollback_transaction(self) -> None: + """回滚事务""" + self.conn.rollback() + if self.db_type not in ['sqlite', 'sqlite3']: + self.conn.autocommit = True + + def fetchone(self): + return self.cursor.fetchone() + + def fetchall(self): + return self.cursor.fetchall() + + def close(self): + if self.cursor: + self.cursor.close() + if self.conn: + self.conn.close() \ No newline at end of file diff --git a/utils/version_manager.py b/utils/version_manager.py new file mode 100644 index 0000000..559d901 --- /dev/null +++ b/utils/version_manager.py @@ -0,0 +1,262 @@ +import os +import json +import logging +import requests +import shutil +import tempfile +import zipfile +from pathlib import Path +import sys +import datetime +from PySide6.QtWidgets import QMessageBox, QProgressDialog +from PySide6.QtCore import Qt + +# 版本检查服务器地址 +VERSION_CHECK_URL = "http://your-server.com/api/version_check" +UPDATE_DOWNLOAD_URL = "http://your-server.com/api/download_update" + +class VersionManager: + """版本管理工具类""" + + VERSION = "1.0.0" + + @staticmethod + def get_current_version(): + """获取当前版本号""" + return VersionManager.VERSION + + @staticmethod + def check_for_updates(parent_widget=None): + """ + 检查是否有更新可用 + + Args: + parent_widget: 父窗口,用于显示消息框 + + Returns: + dict: 包含更新信息的字典,如果没有更新或检查失败则为None + """ + try: + current_version = VersionManager.get_current_version() + logging.info(f"正在检查更新,当前版本: {current_version}") + + # 从服务器获取最新版本信息 + response = requests.get(VERSION_CHECK_URL, params={"current_version": current_version}, timeout=5) + response.raise_for_status() # 如果HTTP请求返回了不成功的状态码,将引发HTTPError异常 + + data = response.json() + if not data.get("success"): + logging.warning(f"版本检查失败: {data.get('message')}") + return None + + if data.get("update_available"): + logging.info(f"发现新版本: {data.get('latest_version')}") + return { + "latest_version": data.get("latest_version"), + "update_url": data.get("update_url"), + "release_notes": data.get("release_notes"), + "is_mandatory": data.get("is_mandatory", False) + } + else: + logging.info("当前已是最新版本") + return None + + except requests.RequestException as e: + logging.error(f"检查更新时网络错误: {e}") + if parent_widget: + QMessageBox.warning(parent_widget, "更新检查失败", f"无法连接到更新服务器: {e}") + return None + except Exception as e: + logging.error(f"检查更新时发生错误: {e}") + if parent_widget: + QMessageBox.warning(parent_widget, "更新检查失败", f"检查更新时发生错误: {e}") + return None + + @staticmethod + def download_and_install_update(update_info, parent_widget=None): + """ + 下载并安装更新 + + Args: + update_info: 包含更新信息的字典 + parent_widget: 父窗口,用于显示进度对话框 + + Returns: + bool: 更新是否成功 + """ + if not update_info or not update_info.get("update_url"): + logging.error("无效的更新信息") + return False + + update_url = update_info.get("update_url") + version = update_info.get("latest_version") + + try: + # 创建进度对话框 + progress = None + if parent_widget: + progress = QProgressDialog("正在下载更新...", "取消", 0, 100, parent_widget) + progress.setWindowTitle(f"下载更新 v{version}") + progress.setWindowModality(Qt.WindowModal) + progress.setAutoClose(True) + progress.setMinimumDuration(0) + progress.setValue(0) + progress.show() + + # 下载更新文件 + logging.info(f"开始下载更新: {update_url}") + + # 使用临时目录 + with tempfile.TemporaryDirectory() as temp_dir: + # 下载文件 + update_file = os.path.join(temp_dir, "update.zip") + + # 使用流式下载以显示进度 + with requests.get(update_url, stream=True) as r: + r.raise_for_status() + total_size = int(r.headers.get('content-length', 0)) + downloaded = 0 + + with open(update_file, 'wb') as f: + for chunk in r.iter_content(chunk_size=8192): + if progress and progress.wasCanceled(): + logging.info("用户取消了下载") + return False + if chunk: + f.write(chunk) + downloaded += len(chunk) + if total_size and progress: + percent = int((downloaded / total_size) * 100) + progress.setValue(percent) + + if progress: + progress.setValue(100) + progress.setLabelText("正在安装更新...") + + # 解压更新文件 + logging.info("正在解压更新文件") + extract_dir = os.path.join(temp_dir, "extracted") + os.makedirs(extract_dir, exist_ok=True) + + with zipfile.ZipFile(update_file, 'r') as zip_ref: + zip_ref.extractall(extract_dir) + + # 获取应用程序根目录 + app_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + # 备份当前版本 + current_version = VersionManager.get_current_version() + backup_dir = os.path.join(app_dir, f"backup_v{current_version}") + logging.info(f"备份当前版本到: {backup_dir}") + if os.path.exists(backup_dir): + shutil.rmtree(backup_dir) + os.makedirs(backup_dir, exist_ok=True) + + # 复制当前文件到备份目录 + for item in os.listdir(app_dir): + if not item.startswith("backup_v"): + s = os.path.join(app_dir, item) + d = os.path.join(backup_dir, item) + if os.path.isdir(s): + shutil.copytree(s, d, dirs_exist_ok=True) + else: + shutil.copy2(s, d) + + # 复制更新文件到应用目录 + logging.info("正在安装更新文件") + for item in os.listdir(extract_dir): + s = os.path.join(extract_dir, item) + d = os.path.join(app_dir, item) + if os.path.isdir(s): + shutil.copytree(s, d, dirs_exist_ok=True) + else: + shutil.copy2(s, d) + + # 更新版本文件 + version_file = os.path.join(app_dir, "version.json") + with open(version_file, 'w') as f: + json.dump({ + "version": version, + "updated_at": str(datetime.datetime.now()), + "release_notes": update_info.get("release_notes", "") + }, f, indent=4) + + logging.info(f"更新完成,新版本: {version}") + + if parent_widget: + QMessageBox.information(parent_widget, "更新完成", + f"已成功更新到版本 {version}。\n应用程序需要重启才能应用更新。") + + # 提示用户重启应用 + if parent_widget and QMessageBox.question( + parent_widget, "重启应用", + "需要重启应用程序以完成更新。是否现在重启?", + QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes: + + logging.info("用户选择重启应用") + # 重启应用 + python = sys.executable + os.execl(python, python, *sys.argv) + + return True + + except Exception as e: + logging.error(f"下载或安装更新时发生错误: {e}", exc_info=True) + if parent_widget: + QMessageBox.critical(parent_widget, "更新失败", f"下载或安装更新时发生错误: {e}") + return False + finally: + if progress: + progress.close() + + @staticmethod + def check_and_prompt_update(parent_widget=None): + """检查更新并提示用户""" + # 这里只是一个示例,实际应该连接到服务器检查更新 + logging.info(f"检查更新,当前版本: {VersionManager.VERSION}") + return False # 返回是否有更新 + + @staticmethod + def check_and_prompt_update(parent_widget): + """ + 检查更新并提示用户 + + Args: + parent_widget: 父窗口 + + Returns: + bool: 是否有可用更新 + """ + update_info = VersionManager.check_for_updates(parent_widget) + if not update_info: + return False + + # 获取更新信息 + latest_version = update_info.get("latest_version", "未知") + release_notes = update_info.get("release_notes", "无更新说明") + is_mandatory = update_info.get("is_mandatory", False) + + message = f"发现新版本: {latest_version}\n\n" + message += "更新内容:\n" + message += release_notes + + if is_mandatory: + message += "\n\n这是一个必须安装的更新。" + result = QMessageBox.information(parent_widget, "发现必要更新", message, + QMessageBox.Ok | QMessageBox.Cancel) + if result == QMessageBox.Ok: + return VersionManager.download_and_install_update(update_info, parent_widget) + else: + # 如果是必要更新但用户取消,则退出应用 + if parent_widget: + QMessageBox.critical(parent_widget, "更新取消", + "这是一个必要更新,应用程序将退出。") + sys.exit(0) + else: + message += "\n\n是否现在更新?" + result = QMessageBox.question(parent_widget, "发现新版本", message, + QMessageBox.Yes | QMessageBox.No) + if result == QMessageBox.Yes: + return VersionManager.download_and_install_update(update_info, parent_widget) + + return False \ No newline at end of file diff --git a/widgets/__pycache__/camera_display_widget.cpython-310.pyc b/widgets/__pycache__/camera_display_widget.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2650ab5acb067271b9cc77318cf6528dbee0f56 GIT binary patch literal 3845 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 literal 0 HcmV?d00001 diff --git a/widgets/__pycache__/login_widget.cpython-310.pyc b/widgets/__pycache__/login_widget.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96561a03c4a3ffa0463213c41201cc2115ce075a GIT binary patch literal 3474 zcmaJ^>vPoB71wj6^*;OvAvEN%Y0_qPhT82HKG3EKuQcgkHw37sn$Bp}x_50Et#)%I z#rBSt!Gj4fg_smdl7S5C0Z)KQ>a@+&6lgO2H}th=*L>nrzhwG4=W5qpmr$*Bbp6a+5aixdjOp#QmToyi&mcVY~ z!mk9PHk4xuepN!vh%-V_4~F2-2e;0yt<1MC-e{d(ZGU_>{_F3el=qHf`}CVWGBGmk z@7ps>CT@y`PD*}hqU6!~&kyZCuz&C2f=vpqzx|8RLf}zW7=L5`+xt1`mMXOHO5xSQ z?y-G^TFLWfs*J2p*q%wKLw$-I}a{?ysPl~O^s==X5{EBwE~}- z?*x?18G4!e)>PG{k!m?rk4EYJvlgxSVE;&Ss*~W9$w;M)RasGuG}O(sNu+lbi6k-+ zr5N=B$B#sMQ(#ZRDc}5f^u907%oj`%>;r|gkwyM&}U>idsiaeimOtw|ZM)kff|QAnNez6Z1gjMg6$+Z}t={St1PG3!{EL78Zc1 zzt9s4VkjoDP!@S4h&&P`m`x%H3~dK%fE8`#TCR@1x}s zSh%pa%4#p~DEtWi{%^4SBMX9BS8lbhF2^T7ix+P*G*9p}43D1Qjgc{yf%T%o07wLe z(afH}0b`20H5t$mQ4Tzpc*u6kRh;rrI64TN0zXAe0fkQ5mN@AkrrtR9kX&UJX-!*wy8=B?V)=^3#&8oUCwfrbMRdR_#JL`Na zPfLdWjM9{V2n-7&$EY7L_btdg4+Q9Zr8Yy1+`9>SnoengI+5m4|1h2P8Ct`50=;Gh zj8WG&I~$8qqPs{Z!J#HB8 ze&?oqM0c#`;~T)#bsya!B#25Rj=Iv^i;!L5AV6Jk4*_>|jmuG2YKX@mEFh;i#dAsy zo&$05l^gN-_v6Jc+IPNg-}ue_+n=|t9dBJ-Ze9Meb?J-XS=iD$(faVu@!|*Vi&p^} z*H%_`6~>BcVxXrI=m95~HCC=0j*$H{SweGDI$zZ%N?51!jck?Q#HPY$%kx?Y`1f z0hGXCO8{6Hoqj45L+OOX{!*XvwNN}E{#t3s4W*$rpul-QAV7ygQ^#^xFGAi4PP(Cm zTCk)k@jX3p@Hjso3TuAuB)C`y z`Ok;ibU#UlI=UDehjUPrLFazZ8JY*2C;3lg)E#shK#4pE;O%3&s}lai5a^M8yCeIh z4c+04{>Plb=O2FtT5RK#jx`6!VAq<(p|KzZj%h8PZ(qL?YzJ~}Wp(YV3-QV2cy&2m zT#bKwHePwJ-JE}TZ=P*~^#p`5a$28X!0|;_H7{`*JxzvnAGqFG#GJBrVvqILMxd~MDXk;qTUPAwY{biK%rm8ce zrCGaT*D2w7AL$meecLKIfRwOWOefjT%j6(RNb_C=YqgQKphTOT1XKsoCPt=K^*}(? z1ttNJZvhU5K=vx!-fJ*m>D1v?pwp26Y8CkDvLx%`GvW};4Z+$LaVy*aCjUywxEuMc z$p3RFRo~VNFTGWzD2^31tVgJ$X-0jfS*el$ijEm&O=t^CPO`!gpM4*c;i^TsPF1j| z<8&(nHhb(P9Iypo*a9HuVG-2fBlN+6G@mUFMuTt79Rl<396snLCEH8D;rJrIW#hcMARKe~KJ04xqvs?221$k8g1^@s6 literal 0 HcmV?d00001 diff --git a/widgets/__pycache__/main_window.cpython-310.pyc b/widgets/__pycache__/main_window.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b404c46812bc3f2acdc85156a820745998e74262 GIT binary patch literal 6351 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 K42n}|zxsa_wLCQd literal 0 HcmV?d00001 diff --git a/widgets/camera_display_widget.py b/widgets/camera_display_widget.py new file mode 100644 index 0000000..afa20d2 --- /dev/null +++ b/widgets/camera_display_widget.py @@ -0,0 +1,137 @@ +import sys +import os +import logging +from ctypes import * + +# 确定使用哪个UI框架 +try: + from PySide6.QtWidgets import QWidget, QVBoxLayout, QFrame + from PySide6.QtCore import Qt, Signal +except ImportError: + from PyQt5.QtWidgets import QWidget, QVBoxLayout, QFrame + from PyQt5.QtCore import Qt, pyqtSignal as Signal + +# 添加相机模块路径 +sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "camera")) + +# 导入相机相关模块 +from camera.MvCameraControl_class import MvCamera +from camera.CamOperation_class import CameraOperation +from camera.MvErrorDefine_const import * +from camera.CameraParams_header import * + +# 导入相机管理器 +from widgets.camera_manager import CameraManager + + +class CameraDisplayWidget(QWidget): + """相机显示组件,用于在主窗口显示相机图像""" + + # 状态信号 + signal_camera_status = Signal(bool, str) # 相机状态信号 (是否连接, 状态消息) + + def __init__(self, parent=None): + super().__init__(parent) + + # 获取相机管理器实例 + self.camera_manager = CameraManager.get_instance() + + # 初始化UI + self.init_ui() + + # 设置显示事件处理 + self.showEvent = self.on_show_event + + # 设置大小变化事件处理 + self.resizeEvent = self.on_resize_event + + def init_ui(self): + """初始化UI - 只包含相机显示框架""" + # 创建布局 + layout = QVBoxLayout() + # 移除所有边距和间距 + layout.setContentsMargins(0, 0, 0, 0) + layout.setSpacing(0) + + # 创建相机画面显示框架 + self.frame = QFrame() + # 去掉边框 + self.frame.setFrameShape(QFrame.NoFrame) + # 设置黑色背景 + self.frame.setStyleSheet("background-color: #000000;") + # 添加到布局 + layout.addWidget(self.frame) + + # 设置布局 + self.setLayout(layout) + + def start_display(self): + """开始显示相机图像""" + if not self.camera_manager.isOpen: + logging.error("相机未打开,无法开始显示") + self.signal_camera_status.emit(False, "相机未打开") + return False + + try: + # 获取窗口句柄 + try: + # PySide6 + window_id = int(self.frame.winId()) + except: + try: + # PyQt5 + window_id = self.frame.winId().__int__() + except: + # 其他情况 + window_id = int(self.frame.winId()) + + # 开始取图 + success = self.camera_manager.start_grabbing(window_id) + + if success: + logging.info("相机画面显示开始") + self.signal_camera_status.emit(True, "") + else: + logging.error("开始显示相机画面失败") + self.signal_camera_status.emit(False, "开始显示失败") + + return success + + except Exception as e: + logging.error(f"开始显示时发生异常: {str(e)}") + self.signal_camera_status.emit(False, str(e)) + return False + + def stop_display(self): + """停止显示相机图像""" + if not self.camera_manager.isGrabbing: + return True + + try: + success = self.camera_manager.stop_grabbing() + if not success: + logging.error("停止显示失败") + return success + except Exception as e: + logging.error(f"停止显示时发生异常: {str(e)}") + return False + + def on_show_event(self, event): + """当组件显示时检查相机状态并自动开始显示""" + if self.camera_manager.isOpen and not self.camera_manager.isGrabbing: + self.start_display() + super().showEvent(event) + + def on_resize_event(self, event): + """处理大小变化事件,确保相机画面适配上料区""" + super().resizeEvent(event) + if self.camera_manager.isGrabbing: + # 停止当前显示 + self.stop_display() + # 使用新尺寸重新开始显示 + self.start_display() + + def closeEvent(self, event): + """窗口关闭事件""" + self.stop_display() + super().closeEvent(event) \ No newline at end of file diff --git a/widgets/camera_manager.py b/widgets/camera_manager.py new file mode 100644 index 0000000..93a867f --- /dev/null +++ b/widgets/camera_manager.py @@ -0,0 +1,354 @@ +import sys +import os +import logging +from ctypes import * + +# 添加相机模块路径 +sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "camera")) + +# 导入相机相关模块 +from camera.MvCameraControl_class import MvCamera +from camera.CamOperation_class import CameraOperation +from camera.MvErrorDefine_const import * +from camera.CameraParams_header import * +from camera.CameraParams_const import * + + +class CameraManager: + """相机管理器单例类,确保整个应用中只有一个相机实例""" + + _instance = None + _initialized = False + + @staticmethod + def get_instance(): + """获取相机管理器实例""" + if CameraManager._instance is None: + CameraManager._instance = CameraManager() + return CameraManager._instance + + def __init__(self): + """初始化相机管理器""" + if CameraManager._instance is not None: + raise Exception("相机管理器是单例类,请使用get_instance()方法获取实例") + else: + CameraManager._instance = self + + # 初始化变量 + self.deviceList = None + self.cam = MvCamera() + self.nSelCamIndex = -1 + self.obj_cam_operation = None + self.isOpen = False + self.isGrabbing = False + + # 初始化SDK (只在第一次时初始化) + if not CameraManager._initialized: + MvCamera.MV_CC_Initialize() + CameraManager._initialized = True + logging.info("相机SDK已初始化") + + def enum_devices(self): + """枚举相机设备""" + try: + # 确保先关闭任何已打开的相机 + if self.isOpen: + self.close_device() + + # 枚举设备 + self.deviceList = MV_CC_DEVICE_INFO_LIST() + n_layer_type = (MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE + | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE) + ret = MvCamera.MV_CC_EnumDevices(n_layer_type, self.deviceList) + if ret != 0: + error_msg = f"枚举设备失败! 错误码: 0x{ret:x}" + logging.error(error_msg) + return None + + if self.deviceList.nDeviceNum == 0: + logging.info("未找到相机设备") + return [] + + logging.info(f"找到 {self.deviceList.nDeviceNum} 个相机设备") + + # 构造设备信息列表 + devices_info = [] + for i in range(0, self.deviceList.nDeviceNum): + mvcc_dev_info = cast(self.deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents + + if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE: + # GigE相机 + user_defined_name = "" + for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chUserDefinedName: + if per == 0: + break + user_defined_name = user_defined_name + chr(per) + + model_name = "" + for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName: + if per == 0: + break + model_name = model_name + chr(per) + + nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24) + nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16) + nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8) + nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff) + ip = f"{nip1}.{nip2}.{nip3}.{nip4}" + + device_info = { + "index": i, + "type": "GigE", + "name": user_defined_name, + "model": model_name, + "ip": ip, + "display": f"[{i}]GigE: {user_defined_name} {model_name} ({ip})" + } + devices_info.append(device_info) + + elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE: + # USB相机 + user_defined_name = "" + for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chUserDefinedName: + if per == 0: + break + user_defined_name = user_defined_name + chr(per) + + model_name = "" + for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName: + if per == 0: + break + model_name = model_name + chr(per) + + device_info = { + "index": i, + "type": "USB", + "name": user_defined_name, + "model": model_name, + "display": f"[{i}]USB: {user_defined_name} {model_name}" + } + devices_info.append(device_info) + + else: + # 其他类型相机 + device_info = { + "index": i, + "type": "Other", + "display": f"[{i}]Other" + } + devices_info.append(device_info) + + return devices_info + + except Exception as e: + error_msg = f"枚举设备时发生异常: {str(e)}" + logging.error(error_msg) + return None + + def open_device(self, device_index): + """打开相机设备 + + Args: + device_index: 设备索引 + + Returns: + bool: 是否成功打开设备 + """ + # 检查是否已经打开 + if self.isOpen: + logging.warning("相机已经打开!") + return False + + # 检查设备索引是否有效 + if device_index < 0 or (self.deviceList and device_index >= self.deviceList.nDeviceNum): + logging.error(f"无效的设备索引: {device_index}") + return False + + try: + logging.debug(f"准备打开相机,设备索引: {device_index}") + + self.nSelCamIndex = device_index + + # 创建相机操作对象 + self.obj_cam_operation = CameraOperation(self.cam, self.deviceList, self.nSelCamIndex) + ret = self.obj_cam_operation.Open_device() + if ret != 0: + error_msg = f"打开相机失败! 错误码: 0x{ret:x}" + logging.error(error_msg) + self.isOpen = False + return False + + # 设置连续模式 + self.obj_cam_operation.Set_trigger_mode(False) + + # 获取参数 + self.obj_cam_operation.Get_parameter() + + self.isOpen = True + logging.info(f"相机已打开,设备索引: {device_index}") + + return True + + except Exception as e: + error_msg = f"打开相机时发生异常: {str(e)}" + logging.error(error_msg) + self.isOpen = False + return False + + def close_device(self): + """关闭相机设备 + + Returns: + bool: 是否成功关闭设备 + """ + if not self.isOpen: + return True + + try: + # 确保停止取图 + if self.isGrabbing: + self.stop_grabbing() + + # 关闭设备 + ret = self.obj_cam_operation.Close_device() + if ret != 0: + error_msg = f"关闭相机失败! 错误码: 0x{ret:x}" + logging.error(error_msg) + return False + + self.isOpen = False + logging.info("相机已关闭") + + return True + + except Exception as e: + error_msg = f"关闭相机时发生异常: {str(e)}" + logging.error(error_msg) + self.isOpen = False # 强制设置为关闭状态 + return False + + def start_grabbing(self, window_id): + """开始取图 + + Args: + window_id: 显示窗口句柄 + + Returns: + bool: 是否成功开始取图 + """ + if not self.isOpen: + logging.error("相机未打开,无法开始取图") + return False + + if self.isGrabbing: + logging.warning("相机已经在取图") + return True + + try: + ret = self.obj_cam_operation.Start_grabbing(window_id) + if ret != 0: + error_msg = f"开始取图失败! 错误码: 0x{ret:x}" + logging.error(error_msg) + return False + + self.isGrabbing = True + logging.info("开始图像采集") + + return True + + except Exception as e: + error_msg = f"开始取图时发生异常: {str(e)}" + logging.error(error_msg) + return False + + def stop_grabbing(self): + """停止取图 + + Returns: + bool: 是否成功停止取图 + """ + if not self.isOpen: + return True + + if not self.isGrabbing: + return True + + try: + ret = self.obj_cam_operation.Stop_grabbing() + if ret != 0: + error_msg = f"停止取图失败! 错误码: 0x{ret:x}" + logging.error(error_msg) + return False + + self.isGrabbing = False + logging.info("停止图像采集") + + return True + + except Exception as e: + error_msg = f"停止取图时发生异常: {str(e)}" + logging.error(error_msg) + self.isGrabbing = False # 强制设置为非取图状态 + return False + + def get_parameters(self): + """获取相机参数 + + Returns: + tuple: (曝光时间, 增益, 帧率) 或 None (如果失败) + """ + if not self.isOpen: + logging.error("相机未打开,无法获取参数") + return None + + try: + ret = self.obj_cam_operation.Get_parameter() + if ret != 0: + error_msg = f"获取相机参数失败! 错误码: 0x{ret:x}" + logging.error(error_msg) + return None + + exposure_time = self.obj_cam_operation.exposure_time + gain = self.obj_cam_operation.gain + frame_rate = self.obj_cam_operation.frame_rate + + logging.info(f"获取相机参数: 曝光={exposure_time}, 增益={gain}, 帧率={frame_rate}") + + return (exposure_time, gain, frame_rate) + + except Exception as e: + error_msg = f"获取相机参数时发生异常: {str(e)}" + logging.error(error_msg) + return None + + def set_parameters(self, frame_rate, exposure_time, gain): + """设置相机参数 + + Args: + frame_rate: 帧率 + exposure_time: 曝光时间 + gain: 增益 + + Returns: + bool: 是否成功设置参数 + """ + if not self.isOpen: + logging.error("相机未打开,无法设置参数") + return False + + try: + # 设置参数 + ret = self.obj_cam_operation.Set_parameter(str(frame_rate), str(exposure_time), str(gain)) + if ret != 0: + error_msg = f"设置相机参数失败! 错误码: 0x{ret:x}" + logging.error(error_msg) + return False + + logging.info(f"设置相机参数: 曝光={exposure_time}, 增益={gain}, 帧率={frame_rate}") + + return True + + except Exception as e: + error_msg = f"设置相机参数时发生异常: {str(e)}" + logging.error(error_msg) + return False \ No newline at end of file diff --git a/widgets/camera_settings_widget.py b/widgets/camera_settings_widget.py new file mode 100644 index 0000000..a96f055 --- /dev/null +++ b/widgets/camera_settings_widget.py @@ -0,0 +1,324 @@ +import sys +import os +import logging +from ctypes import * +from math import log10 +from camera.CameraParams_const import * +# 添加相机模块路径 +sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "camera")) + +try: + from PySide6.QtWidgets import QWidget, QMessageBox + from PySide6.QtCore import Qt, Signal + USE_PYSIDE6 = True +except ImportError: + from PyQt5.QtWidgets import QWidget, QMessageBox + from PyQt5.QtCore import Qt + from PyQt5.QtCore import pyqtSignal as Signal + USE_PYSIDE6 = False + +# 导入相机相关模块 +from camera.MvCameraControl_class import MvCamera +from camera.CamOperation_class import CameraOperation +from camera.MvErrorDefine_const import * +from camera.CameraParams_header import * +from ui.settings_ui import SettingsUI + +# 导入相机管理器 +from widgets.camera_manager import CameraManager + + +class CameraSettingsWidget(SettingsUI): + """相机设置控制器,管理相机设置并提供与主窗口相机显示部分的通信""" + + # 定义信号 + signal_camera_connection = Signal(bool, str) # 相机连接状态信号 (是否连接, 错误消息) + signal_camera_params_changed = Signal(float, float, float) # 相机参数变化信号 (曝光, 增益, 帧率) + signal_camera_error = Signal(str) # 相机错误信号 + + def __init__(self, parent=None): + super().__init__(parent) + + # 获取相机管理器实例 + self.camera_manager = CameraManager.get_instance() + + # 初始化UI控件状态 + self.update_controls() + + # 连接信号和槽 + self.connect_signals() + + # 初始化相机参数范围 + self.frame_rate_min = 1.0 + self.frame_rate_max = 60.0 + self.exposure_min = 20.0 + self.exposure_max = 1000000.0 + self.gain_min = 0.0 + self.gain_max = 15.0 + + # 枚举设备 + self.refresh_devices() + + def connect_signals(self): + """连接信号和槽""" + # 设备选择和刷新 + self.refresh_button.clicked.connect(self.refresh_devices) + + # 相机控制按钮 + self.open_button.clicked.connect(self.open_camera) + self.close_button.clicked.connect(self.close_camera) + self.test_button.clicked.connect(self.test_camera) + + # 参数滑块 + self.exposure_slider.valueChanged.connect(self.update_exposure_value) + self.gain_slider.valueChanged.connect(self.update_gain_value) + self.framerate_slider.valueChanged.connect(self.update_frame_rate_value) + + # 参数操作按钮 + self.get_params_button.clicked.connect(self.get_camera_params) + self.set_params_button.clicked.connect(self.set_camera_params) + self.save_camera_button.clicked.connect(self.save_camera_params) + + def refresh_devices(self): + """刷新设备列表""" + self.camera_combo.clear() + + # 枚举设备 + devices_info = self.camera_manager.enum_devices() + + if not devices_info: + self.camera_combo.addItem("未发现相机设备") + self.camera_combo.setEnabled(False) + self.open_button.setEnabled(False) + return + + # 添加设备到下拉框 + for device in devices_info: + self.camera_combo.addItem(device["display"], device["index"]) + + self.camera_combo.setEnabled(True) + self.open_button.setEnabled(True) + + # 更新控件状态 + self.update_controls() + + def get_selected_device_index(self): + """获取当前选中的设备索引""" + if self.camera_combo.count() == 0: + return -1 + + return self.camera_combo.currentData() + + def update_controls(self): + """更新控件状态""" + is_open = self.camera_manager.isOpen + is_grabbing = self.camera_manager.isGrabbing + + # 设备选择和刷新 + self.camera_combo.setEnabled(not is_open) + self.refresh_button.setEnabled(not is_open) + + # 相机控制按钮 + self.open_button.setEnabled(not is_open and self.camera_combo.count() > 0 and self.camera_combo.currentData() is not None) + self.close_button.setEnabled(is_open) + self.test_button.setEnabled(is_open and not is_grabbing) + + # 参数滑块 + self.exposure_slider.setEnabled(is_open) + self.gain_slider.setEnabled(is_open) + self.framerate_slider.setEnabled(is_open) + + # 参数操作按钮 + self.get_params_button.setEnabled(is_open) + self.set_params_button.setEnabled(is_open) + self.save_camera_button.setEnabled(is_open) + + def open_camera(self): + """打开相机""" + if self.camera_manager.isOpen: + QMessageBox.warning(self, "错误", "相机已经打开!") + return + + device_index = self.get_selected_device_index() + if device_index < 0: + QMessageBox.warning(self, "错误", "请先选择一个相机设备!") + return + + success = self.camera_manager.open_device(device_index) + + if success: + # 获取相机参数并更新UI + self.get_camera_params() + + # 更新控件状态 + self.update_controls() + + # 发送连接信号 + self.signal_camera_connection.emit(True, "") + else: + # 发送连接失败信号 + self.signal_camera_connection.emit(False, "打开相机失败") + + def close_camera(self): + """关闭相机""" + if not self.camera_manager.isOpen: + return + + success = self.camera_manager.close_device() + + # 更新控件状态 + self.update_controls() + + # 发送连接信号 + if success: + self.signal_camera_connection.emit(False, "") + else: + self.signal_camera_connection.emit(False, "关闭相机出错") + + def test_camera(self): + """测试相机(在预览窗口显示图像)""" + if not self.camera_manager.isOpen: + QMessageBox.warning(self, "错误", "请先打开相机!") + return + + if self.camera_manager.isGrabbing: + # 停止预览 + self.camera_manager.stop_grabbing() + self.test_button.setText("开始预览") + self.update_controls() + else: + # 获取预览窗口句柄 + try: + # 尝试使用PySide6方式获取窗口句柄 + window_id = int(self.preview_frame.winId()) + except: + try: + # 尝试使用PyQt5方式获取窗口句柄 + window_id = self.preview_frame.winId().__int__() + except: + # 其他情况 + window_id = int(self.preview_frame.winId()) + + # 开始预览 + success = self.camera_manager.start_grabbing(window_id) + + if success: + self.test_button.setText("停止预览") + else: + QMessageBox.warning(self, "错误", "开始预览失败!") + + # 更新控件状态 + self.update_controls() + + def update_exposure_value(self, value): + """更新曝光值显示""" + # 将滑块值转换为实际曝光值(对数映射) + min_log = log10(self.exposure_min) + max_log = log10(self.exposure_max) + log_range = max_log - min_log + + log_value = min_log + (value / 100.0) * log_range + actual_value = 10 ** log_value + + # 更新显示 + self.exposure_value.setText(f"{actual_value:.1f} μs") + + def update_gain_value(self, value): + """更新增益值显示""" + # 将滑块值转换为实际增益值 + actual_value = self.gain_min + (value / 100.0) * (self.gain_max - self.gain_min) + + # 更新显示 + self.gain_value.setText(f"{actual_value:.1f} dB") + + def update_frame_rate_value(self, value): + """更新帧率值显示""" + # 将滑块值转换为实际帧率值 + actual_value = self.frame_rate_min + (value / 100.0) * (self.frame_rate_max - self.frame_rate_min) + + # 更新显示 + self.framerate_value.setText(f"{actual_value:.1f} fps") + + def get_camera_params(self): + """获取相机参数""" + if not self.camera_manager.isOpen: + QMessageBox.warning(self, "错误", "请先打开相机!") + return + + # 获取参数 + params = self.camera_manager.get_parameters() + if not params: + QMessageBox.warning(self, "错误", "获取相机参数失败!") + return + + exposure_time, gain, frame_rate = params + + # 更新滑块值 + # 曝光时间(对数映射) + min_log = log10(self.exposure_min) + max_log = log10(self.exposure_max) + log_range = max_log - min_log + log_value = log10(exposure_time) + slider_value = int(((log_value - min_log) / log_range) * 100) + self.exposure_slider.setValue(slider_value) + + # 增益 + slider_value = int(((gain - self.gain_min) / (self.gain_max - self.gain_min)) * 100) + self.gain_slider.setValue(slider_value) + + # 帧率 + slider_value = int(((frame_rate - self.frame_rate_min) / (self.frame_rate_max - self.frame_rate_min)) * 100) + self.framerate_slider.setValue(slider_value) + + # 发送参数变化信号 + self.signal_camera_params_changed.emit(exposure_time, gain, frame_rate) + + def set_camera_params(self): + """设置相机参数""" + if not self.camera_manager.isOpen: + QMessageBox.warning(self, "错误", "请先打开相机!") + return + + # 从滑块获取参数值 + # 曝光时间(对数映射) + min_log = log10(self.exposure_min) + max_log = log10(self.exposure_max) + log_range = max_log - min_log + log_value = min_log + (self.exposure_slider.value() / 100.0) * log_range + exposure_time = 10 ** log_value + + # 增益 + gain = self.gain_min + (self.gain_slider.value() / 100.0) * (self.gain_max - self.gain_min) + + # 帧率 + frame_rate = self.frame_rate_min + (self.framerate_slider.value() / 100.0) * (self.frame_rate_max - self.frame_rate_min) + + # 设置参数 + success = self.camera_manager.set_parameters(frame_rate, exposure_time, gain) + + if success: + QMessageBox.information(self, "成功", "相机参数设置成功!") + + # 发送参数变化信号 + self.signal_camera_params_changed.emit(exposure_time, gain, frame_rate) + else: + QMessageBox.warning(self, "错误", "相机参数设置失败!") + + def save_camera_params(self): + """保存相机参数""" + if not self.camera_manager.isOpen: + QMessageBox.warning(self, "错误", "请先打开相机!") + return + + # 实现保存参数到配置文件的功能 + # TODO: 待实现 + QMessageBox.information(self, "提示", "参数保存功能尚未实现") + + def closeEvent(self, event): + """窗口关闭事件""" + # 确保关闭相机 + if self.camera_manager.isOpen: + self.camera_manager.close_device() + + # 处理事件 + super().closeEvent(event) \ No newline at end of file diff --git a/widgets/camera_widget.py b/widgets/camera_widget.py new file mode 100644 index 0000000..22acad1 --- /dev/null +++ b/widgets/camera_widget.py @@ -0,0 +1,298 @@ +import sys +import os +import logging +from ctypes import * +from camera.CameraParams_const import * + +# 添加相机模块路径 +sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), "camera")) + +# 导入相机相关模块 +from camera.MvCameraControl_class import MvCamera +from camera.CamOperation_class import CameraOperation +from camera.MvErrorDefine_const import * +from camera.CameraParams_header import * # 导入MV_CC_DEVICE_INFO_LIST等类型 + +# 尝试从PySide6导入,如果失败则从PyQt5导入 +try: + from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QComboBox, QMessageBox, QFrame + from PySide6.QtCore import Signal + USE_PYSIDE6 = True +except ImportError: + from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QComboBox, QMessageBox, QFrame + from PyQt5.QtCore import pyqtSignal as Signal + USE_PYSIDE6 = False + + +class CameraWidget(QWidget): + """海康威视工业相机控制组件""" + + # 定义信号 + camera_connected = Signal(bool) + camera_error = Signal(str) + + def __init__(self, parent=None): + super().__init__(parent) + + # 初始化相机变量 + self.deviceList = None + self.cam = MvCamera() + self.nSelCamIndex = 0 + self.obj_cam_operation = None + self.isOpen = False + self.isGrabbing = False + + # 初始化UI + self.init_ui() + + # 枚举相机设备 + self.enum_devices() + + def init_ui(self): + # 主布局 + self.main_layout = QVBoxLayout(self) + self.main_layout.setContentsMargins(5, 5, 5, 5) + self.main_layout.setSpacing(5) + + # 相机选择区域 + self.device_layout = QHBoxLayout() + self.device_label = QLabel("相机:") + self.device_combo = QComboBox() + self.device_combo.setMinimumWidth(150) + self.refresh_button = QPushButton("刷新") + self.refresh_button.clicked.connect(self.enum_devices) + + self.device_layout.addWidget(self.device_label) + self.device_layout.addWidget(self.device_combo) + self.device_layout.addWidget(self.refresh_button) + self.device_layout.addStretch() + + # 相机控制区域 + self.control_layout = QHBoxLayout() + self.open_button = QPushButton("打开相机") + self.open_button.clicked.connect(self.open_device) + self.close_button = QPushButton("关闭相机") + self.close_button.clicked.connect(self.close_device) + self.start_button = QPushButton("开始采集") + self.start_button.clicked.connect(self.start_grabbing) + self.stop_button = QPushButton("停止采集") + self.stop_button.clicked.connect(self.stop_grabbing) + + self.control_layout.addWidget(self.open_button) + self.control_layout.addWidget(self.close_button) + self.control_layout.addWidget(self.start_button) + self.control_layout.addWidget(self.stop_button) + + # 视频显示区域 + self.display_frame = QFrame() + self.display_frame.setFrameShape(QFrame.Box) + self.display_frame.setLineWidth(1) + self.display_frame.setMinimumHeight(200) + self.display_frame.setStyleSheet("background-color: black;") + + # 将所有组件添加到主布局 + self.main_layout.addLayout(self.device_layout) + self.main_layout.addLayout(self.control_layout) + self.main_layout.addWidget(self.display_frame, 1) # 显示区域占据剩余空间 + + # 初始化按钮状态 + self.update_controls() + + def update_controls(self): + """更新控件状态""" + has_devices = self.device_combo.count() > 0 + + self.open_button.setEnabled(has_devices and not self.isOpen) + self.close_button.setEnabled(self.isOpen) + self.start_button.setEnabled(self.isOpen and not self.isGrabbing) + self.stop_button.setEnabled(self.isOpen and self.isGrabbing) + self.device_combo.setEnabled(not self.isOpen) + self.refresh_button.setEnabled(not self.isOpen) + + def enum_devices(self): + """枚举相机设备""" + try: + # 初始化SDK + MvCamera.MV_CC_Initialize() + + # 清空设备列表 + self.device_combo.clear() + + # 枚举设备 + self.deviceList = MV_CC_DEVICE_INFO_LIST() + n_layer_type = (MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE + | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE) + ret = MvCamera.MV_CC_EnumDevices(n_layer_type, self.deviceList) + if ret != 0: + error_msg = f"枚举设备失败! 错误码: 0x{ret:x}" + self.camera_error.emit(error_msg) + logging.error(error_msg) + return + + if self.deviceList.nDeviceNum == 0: + logging.info("未找到相机设备") + return + + logging.info(f"找到 {self.deviceList.nDeviceNum} 个相机设备") + + # 将设备添加到下拉列表 + for i in range(0, self.deviceList.nDeviceNum): + mvcc_dev_info = cast(self.deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents + + if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE: + # GigE相机 + nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24) + nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16) + nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8) + nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff) + ip = f"{nip1}.{nip2}.{nip3}.{nip4}" + + device_info = f"[{i}]GigE: {ip}" + self.device_combo.addItem(device_info) + elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE: + # USB相机 + device_info = f"[{i}]USB" + self.device_combo.addItem(device_info) + else: + # 其他类型相机 + device_info = f"[{i}]Other" + self.device_combo.addItem(device_info) + + # 更新控件状态 + self.update_controls() + except Exception as e: + error_msg = f"枚举设备时发生异常: {str(e)}" + self.camera_error.emit(error_msg) + logging.error(error_msg) + + def get_selected_device_index(self): + """获取选中的设备索引""" + if self.device_combo.count() == 0: + return -1 + + device_text = self.device_combo.currentText() + start_idx = device_text.find('[') + 1 + end_idx = device_text.find(']') + if start_idx >= 0 and end_idx > start_idx: + return int(device_text[start_idx:end_idx]) + return 0 + + def open_device(self): + """打开相机设备""" + if self.isOpen: + QMessageBox.warning(self, "错误", "相机已经打开!") + return + + try: + self.nSelCamIndex = self.get_selected_device_index() + if self.nSelCamIndex < 0: + QMessageBox.warning(self, "错误", "请选择一个相机!") + return + + self.obj_cam_operation = CameraOperation(self.cam, self.deviceList, self.nSelCamIndex) + ret = self.obj_cam_operation.Open_device() + if ret != 0: + error_msg = f"打开相机失败! 错误码: 0x{ret:x}" + QMessageBox.warning(self, "错误", error_msg) + self.isOpen = False + logging.error(error_msg) + else: + # 设置连续模式 + self.obj_cam_operation.Set_trigger_mode(False) + # 获取参数 + self.obj_cam_operation.Get_parameter() + + self.isOpen = True + self.camera_connected.emit(True) + logging.info("相机已打开") + + self.update_controls() + except Exception as e: + error_msg = f"打开相机时发生异常: {str(e)}" + QMessageBox.warning(self, "错误", error_msg) + logging.error(error_msg) + self.isOpen = False + self.update_controls() + + def close_device(self): + """关闭相机设备""" + if not self.isOpen: + return + + try: + if self.isGrabbing: + self.stop_grabbing() + + ret = self.obj_cam_operation.Close_device() + if ret != 0: + error_msg = f"关闭相机失败! 错误码: 0x{ret:x}" + QMessageBox.warning(self, "错误", error_msg) + logging.error(error_msg) + else: + self.isOpen = False + self.camera_connected.emit(False) + logging.info("相机已关闭") + + self.update_controls() + except Exception as e: + error_msg = f"关闭相机时发生异常: {str(e)}" + logging.error(error_msg) + self.isOpen = False + self.update_controls() + + def start_grabbing(self): + """开始取图""" + if not self.isOpen or self.isGrabbing: + return + + try: + # 根据使用的框架不同,获取窗口句柄的方式不同 + if USE_PYSIDE6: + window_id = int(self.display_frame.winId()) + else: + window_id = self.display_frame.winId() + + ret = self.obj_cam_operation.Start_grabbing(window_id) + if ret != 0: + error_msg = f"开始取图失败! 错误码: 0x{ret:x}" + QMessageBox.warning(self, "错误", error_msg) + logging.error(error_msg) + else: + self.isGrabbing = True + logging.info("开始图像采集") + + self.update_controls() + except Exception as e: + error_msg = f"开始取图时发生异常: {str(e)}" + QMessageBox.warning(self, "错误", error_msg) + logging.error(error_msg) + self.isGrabbing = False + self.update_controls() + + def stop_grabbing(self): + """停止取图""" + if not self.isOpen or not self.isGrabbing: + return + + try: + ret = self.obj_cam_operation.Stop_grabbing() + if ret != 0: + error_msg = f"停止取图失败! 错误码: 0x{ret:x}" + QMessageBox.warning(self, "错误", error_msg) + logging.error(error_msg) + else: + self.isGrabbing = False + logging.info("停止图像采集") + + self.update_controls() + except Exception as e: + error_msg = f"停止取图时发生异常: {str(e)}" + logging.error(error_msg) + self.isGrabbing = False + self.update_controls() + + def closeEvent(self, event): + """窗口关闭事件""" + if self.isOpen: + self.close_device() + event.accept() \ No newline at end of file diff --git a/widgets/login_widget.py b/widgets/login_widget.py new file mode 100644 index 0000000..7007981 --- /dev/null +++ b/widgets/login_widget.py @@ -0,0 +1,98 @@ +from PySide6.QtWidgets import QMessageBox +from PySide6.QtCore import Qt +from ui.login_ui import LoginUI +from utils.version_manager import VersionManager +from widgets.main_window import MainWindow +from utils.sql_utils import SQLUtils +import logging +import threading + +def check_user_login(user_id, password): + """验证用户登录""" + try: + db = SQLUtils('sqlite', database='db/jtDB.db') + db.execute_query("SELECT id FROM user WHERE username = ? AND password = ? AND is_deleted = 0", (user_id, password)) + result = db.fetchone() + db.close() + return result is not None + except Exception as e: + logging.error(f"登录验证出错: {e}") + return False + +def get_user_info(user_id): + """获取用户信息""" + try: + db = SQLUtils('sqlite', database='db/jtDB.db') + db.execute_query("SELECT username, 'Default Corp', 1, 1 FROM user WHERE username = ?", (user_id,)) + result = db.fetchone() + db.close() + if result: + return result + return user_id, "未知公司", 0, 0 + except Exception as e: + logging.error(f"获取用户信息出错: {e}") + return user_id, "未知公司", 0, 0 + +class LoginWidget(LoginUI): + def __init__(self, parent=None): + super().__init__(parent) + self.btn_login.clicked.connect(self.handle_login) + self.btn_close.clicked.connect(self.close) + + # 添加回车键支持 + self.edit_user.returnPressed.connect(self.handle_login) + self.edit_pwd.returnPressed.connect(self.handle_login) + + # 显示版本号 + self.version_label.setText(f"版本: {VersionManager.get_current_version()}") + + # 在单独的线程中检查更新,避免阻塞UI + # self.check_update_thread = threading.Thread(target=self.check_for_updates) + # self.check_update_thread.daemon = True + # self.check_update_thread.start() + + def check_for_updates(self): + """在后台线程中检查更新""" + try: + # 检查更新并提示用户 + VersionManager.check_and_prompt_update(self) + except Exception as e: + logging.error(f"检查更新时发生错误: {e}") + + # 登录按钮点击事件 + def handle_login(self): + user_id = self.edit_user.text().strip() + password = self.edit_pwd.text().strip() + if not user_id or not password: + QMessageBox.warning(self, "提示", "请输入工号和密码!") + return + if check_user_login(user_id, password): + try: + user_name, corp_name, corp_id, position_id = get_user_info(user_id) + if not corp_name: + corp_name = "未知公司" + # 移除登录成功的弹框 + # QMessageBox.information(self, "登录成功", f"欢迎 {user_name}!") + self.hide() + + # 使用异常处理确保主窗口创建失败不会导致整个应用程序崩溃 + try: + import logging + logging.info(f"正在创建主窗口,用户ID: {user_id}, 姓名: {user_name}, 公司: {corp_name}") + self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id) + self.main_window.showMaximized() # 窗口最大化显示 + logging.info("主窗口已显示(最大化)") + except Exception as e: + logging.critical(f"创建或显示主窗口时发生错误: {e}", exc_info=True) + QMessageBox.critical(self, "系统错误", f"打开主窗口时发生错误: {e}\n请联系管理员") + self.show() # 如果主窗口创建失败,重新显示登录窗口 + except Exception as e: + import logging + logging.critical(f"处理登录信息时发生错误: {e}", exc_info=True) + QMessageBox.critical(self, "系统错误", f"处理登录信息时发生错误: {e}\n请联系管理员") + self.show() # 确保用户可以重新尝试登录 + else: + QMessageBox.warning(self, "登录失败", "工号或密码错误!") + + + \ No newline at end of file diff --git a/widgets/main_window.py b/widgets/main_window.py new file mode 100644 index 0000000..bc27b86 --- /dev/null +++ b/widgets/main_window.py @@ -0,0 +1,213 @@ +import os +import sys +import logging +from datetime import datetime + +# 导入PySide6 +from PySide6.QtWidgets import QWidget, QMessageBox, QTableWidgetItem, QStackedWidget, QLabel +from PySide6.QtCore import Qt, QTimer +from PySide6.QtGui import QBrush, QColor + +# 导入UI +from ui.main_window_ui import MainWindowUI + +# 导入相机显示组件和设置组件 +from widgets.camera_display_widget import CameraDisplayWidget +from widgets.camera_settings_widget import CameraSettingsWidget + + +class MainWindow(MainWindowUI): + """主窗口""" + + def __init__(self, user_id=None, user_name=None, corp_name=None, corp_id=None, position_id=None): + super().__init__() + self.user_id = user_id + self.user_name = user_name + self.corp_name = corp_name + self.corp_id = corp_id + self.position_id = position_id + + # 设置窗口标题 + if user_name and corp_name: + self.setWindowTitle(f"腾智微丝产线包装系统 - {user_name} ({corp_name})") + + + # # 创建相机显示组件并添加到上料区 + # self.camera_display = CameraDisplayWidget() + # self.material_content_layout.addWidget(self.camera_display) + + # 为下料区添加占位标签,确保它保持为空 + self.output_placeholder = QLabel("下料区 - 暂无内容") + self.output_placeholder.setAlignment(Qt.AlignCenter) + self.output_placeholder.setStyleSheet("color: #888888; background-color: #f0f0f0;") + self.output_content_layout.addWidget(self.output_placeholder) + + # 创建堆叠部件 + self.stacked_widget = QStackedWidget() + self.stacked_widget.addWidget(self.central_widget) # 主页面 + + # 不在这里直接初始化相机设置组件 + # 延迟创建,保证创建的时候SettingsUI的所有控件都已经准备好 + self.camera_settings = None + + # 设置中央部件为堆叠部件 + self.setCentralWidget(self.stacked_widget) + + # 连接信号和槽 + # self.connect_signals() + + # 默认显示主页面 + self.stacked_widget.setCurrentIndex(0) + + # 初始化数据 + self.initialize_data() + + # 配置检验列为5列 + self.set_inspection_columns(5) + + logging.info(f"主窗口已创建,用户: {user_name}") + + def connect_signals(self): + # 连接菜单动作 + self.main_action.triggered.connect(self.show_main_page) + self.settings_action.triggered.connect(self.show_settings_page) + + # 连接按钮事件 + self.input_button.clicked.connect(self.handle_input) + self.output_button.clicked.connect(self.handle_output) + self.start_button.clicked.connect(self.handle_start) + self.stop_button.clicked.connect(self.handle_stop) + + # 连接相机显示组件信号 + self.camera_display.signal_camera_status.connect(self.handle_camera_status) + + def initialize_data(self): + """初始化界面数据""" + # 设置订单和批号 + self.order_edit.setText("ORD-2025-001") + self.tray_edit.setText("BAT-2025-001") + + # 初始化项目表格数据示例 + project_data = [ + ["100", "50", "200", "95%"], + ["3000", "1500", "6000", "92%"], + ["36000", "18000", "72000", "90%"], + ["120000", "60000", "240000", "91%"] + ] + + for row in range(4): + for col in range(1, 5): # 从第2列开始(跳过项目列) + item = QTableWidgetItem(project_data[row][col-1]) + # item.setTextAlignment(Qt.AlignCenter) # 设置文本居中对齐 + self.project_table.setItem(row, col, item) + + # 初始化任务表格数据示例 - 注意:现在表格有3行,第0行是一级标题,第1行是二级标题,第2行是数据行 + # 数据应该填充在第2行(索引为2) + data = ["200", "95", "0", "0"] # 分别对应:总生产数量、总生产公斤、已完成数量、已完成公斤 + for col, value in enumerate(data): + item = QTableWidgetItem(value) + item.setTextAlignment(Qt.AlignCenter) # 设置文本居中对齐 + self.task_table.setItem(2, col, item) + + def show_main_page(self): + self.stacked_widget.setCurrentWidget(self.central_widget) + + # 如果相机已连接,直接开始显示相机画面 + if self.camera_display.camera_manager.isOpen: + if not self.camera_display.camera_manager.isGrabbing: + self.camera_display.start_display() + + logging.info("显示主页面") + + def show_settings_page(self): + # 延迟创建相机设置组件 + if self.camera_settings is None: + self.camera_settings = CameraSettingsWidget() + # 连接相机设置信号 + self.camera_settings.signal_camera_connection.connect(self.handle_camera_connection) + self.camera_settings.signal_camera_params_changed.connect(self.handle_camera_params_changed) + self.camera_settings.signal_camera_error.connect(self.handle_camera_error) + # 添加到堆叠部件 + self.stacked_widget.addWidget(self.camera_settings) + + # 切换到设置页面 + self.stacked_widget.setCurrentWidget(self.camera_settings) + logging.info("显示设置页面") + + def handle_input(self): + """处理上料按钮点击事件""" + logging.info("上料按钮被点击") + + # 如果相机已经配置,则开始显示 + if self.camera_display.camera_manager.isOpen and not self.camera_display.camera_manager.isGrabbing: + self.camera_display.start_display() + + QMessageBox.information(self, "操作提示", "开始上料操作") + # 这里添加上料相关的业务逻辑 + + def handle_output(self): + """处理下料按钮点击事件""" + logging.info("下料按钮被点击") + QMessageBox.information(self, "操作提示", "开始下料操作") + # 这里添加下料相关的业务逻辑 + + def handle_start(self): + """处理开始按钮点击事件""" + logging.info("开始按钮被点击") + + # 开始显示相机画面 + if self.camera_display.camera_manager.isOpen: + self.camera_display.start_display() + + QMessageBox.information(self, "操作提示", "生产线已启动") + # 这里添加启动生产线的业务逻辑 + + def handle_stop(self): + """处理暂停按钮点击事件""" + logging.info("暂停按钮被点击") + + # 停止显示相机画面 + self.camera_display.stop_display() + + QMessageBox.information(self, "操作提示", "生产线已暂停") + # 这里添加暂停生产线的业务逻辑 + + def handle_camera_status(self, is_connected, message): + """处理相机状态变化""" + if is_connected: + logging.info("相机已连接并显示") + else: + logging.warning(f"相机显示问题: {message}") + + def handle_camera_connection(self, is_connected, message): + """处理相机连接状态变化""" + if is_connected: + logging.info("相机已连接") + # 如果当前在主页面,直接开始显示相机画面 + if self.stacked_widget.currentWidget() == self.central_widget: + self.camera_display.start_display() + else: + if message: + logging.warning(f"相机连接失败: {message}") + else: + logging.info("相机已断开") + # 如果相机断开,确保停止显示 + self.camera_display.stop_display() + + def handle_camera_params_changed(self, exposure_time, gain, frame_rate): + """处理相机参数变化""" + logging.info(f"相机参数已更新: 曝光={exposure_time:.1f}μs, 增益={gain:.1f}dB, 帧率={frame_rate:.1f}fps") + # 这里可以添加对相机参数变化的处理逻辑 + + def handle_camera_error(self, error_msg): + """处理相机错误""" + logging.error(f"相机错误: {error_msg}") + QMessageBox.warning(self, "相机错误", error_msg) + + def closeEvent(self, event): + """窗口关闭事件""" + # 停止相机显示 + self.camera_display.stop_display() + + # 接受关闭事件 + event.accept() \ No newline at end of file diff --git a/widgets/settings_dialog.py b/widgets/settings_dialog.py new file mode 100644 index 0000000..047e936 --- /dev/null +++ b/widgets/settings_dialog.py @@ -0,0 +1,57 @@ +import logging + +try: + from PySide6.QtWidgets import QDialog, QVBoxLayout, QTabWidget, QDialogButtonBox + from PySide6.QtCore import Qt +except ImportError: + from PyQt5.QtWidgets import QDialog, QVBoxLayout, QTabWidget, QDialogButtonBox + from PyQt5.QtCore import Qt + + +class SettingsDialog(QDialog): + """设置对话框,用于显示和管理各种设置页面""" + + def __init__(self, parent=None): + super().__init__(parent) + + # 设置对话框标题和大小 + self.setWindowTitle("系统设置") + self.resize(800, 600) + + # 创建布局 + self.layout = QVBoxLayout(self) + + # 创建选项卡控件 + self.tab_widget = QTabWidget() + self.layout.addWidget(self.tab_widget) + + # 创建按钮盒 + self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + self.button_box.accepted.connect(self.accept) + self.button_box.rejected.connect(self.reject) + self.layout.addWidget(self.button_box) + + # 设置窗口模态 + self.setModal(True) + + logging.info("设置对话框已创建") + + def add_settings_page(self, widget, title): + """添加设置页面 + + Args: + widget: 设置页面部件 + title: 页面标题 + """ + self.tab_widget.addTab(widget, title) + logging.info(f"已添加设置页面: {title}") + + def accept(self): + """确认按钮处理""" + logging.info("设置已保存") + super().accept() + + def reject(self): + """取消按钮处理""" + logging.info("设置已取消") + super().reject() \ No newline at end of file diff --git a/widgets/settings_widget.py b/widgets/settings_widget.py new file mode 100644 index 0000000..b575443 --- /dev/null +++ b/widgets/settings_widget.py @@ -0,0 +1,140 @@ +from PySide6.QtWidgets import QMessageBox +import logging +from ui.settings_ui import SettingsUI +from utils.sql_utils import SQLUtils + +class SettingsWidget(SettingsUI): + def __init__(self, parent=None): + super().__init__(parent) + self.parent = parent + + # 连接信号和槽 + self.connect_signals() + + # 初始化数据库类型UI状态 + self.update_db_ui_state() + + def connect_signals(self): + # 数据库类型选择 + self.sqlite_radio.toggled.connect(self.update_db_ui_state) + self.pgsql_radio.toggled.connect(self.update_db_ui_state) + self.mysql_radio.toggled.connect(self.update_db_ui_state) + + # 按钮动作 + self.test_conn_button.clicked.connect(self.test_connection) + self.save_db_button.clicked.connect(self.save_db_settings) + + def update_db_ui_state(self): + """根据选择的数据库类型更新UI状态""" + if self.sqlite_radio.isChecked(): + # SQLite模式下,只需要数据库文件路径 + self.host_input.setEnabled(False) + self.host_input.setText("") + self.user_input.setEnabled(False) + self.user_input.setText("") + self.password_input.setEnabled(False) + self.password_input.setText("") + self.port_input.setEnabled(False) + self.port_input.setText("") + self.database_input.setEnabled(True) + self.database_input.setText("db/jtDB.db") + elif self.pgsql_radio.isChecked(): + # PostgreSQL模式下,需要完整的连接信息 + self.host_input.setEnabled(True) + self.host_input.setText("localhost") + self.user_input.setEnabled(True) + self.user_input.setText("postgres") + self.password_input.setEnabled(True) + self.password_input.setText("") + self.port_input.setEnabled(True) + self.port_input.setText("5432") + self.database_input.setEnabled(True) + self.database_input.setText("jtDB") + elif self.mysql_radio.isChecked(): + # MySQL模式下,需要完整的连接信息 + self.host_input.setEnabled(True) + self.host_input.setText("localhost") + self.user_input.setEnabled(True) + self.user_input.setText("root") + self.password_input.setEnabled(True) + self.password_input.setText("") + self.port_input.setEnabled(True) + self.port_input.setText("3306") + self.database_input.setEnabled(True) + self.database_input.setText("jtDB") + + def get_db_type(self): + """获取当前选择的数据库类型""" + if self.sqlite_radio.isChecked(): + return "sqlite" + elif self.pgsql_radio.isChecked(): + return "pgsql" + elif self.mysql_radio.isChecked(): + return "mysql" + return "sqlite" # 默认返回sqlite + + def get_connection_params(self): + """获取数据库连接参数""" + db_type = self.get_db_type() + params = { + "database": self.database_input.text().strip() + } + + if db_type != "sqlite": + params.update({ + "host": self.host_input.text().strip(), + "user": self.user_input.text().strip(), + "password": self.password_input.text().strip(), + "port": self.port_input.text().strip() + }) + + return db_type, params + + def test_connection(self): + """测试数据库连接""" + db_type, params = self.get_connection_params() + + try: + # 创建数据库连接 + db = SQLUtils(db_type, **params) + + # 尝试执行简单查询 + if db_type == "sqlite": + db.execute_query("SELECT sqlite_version();") + elif db_type == "pgsql": + db.execute_query("SELECT version();") + elif db_type == "mysql": + db.execute_query("SELECT version();") + + result = db.fetchone() + db.close() + + # 显示成功消息 + QMessageBox.information(self, "连接成功", f"数据库连接测试成功!\n数据库版本: {result[0]}") + + logging.info(f"数据库连接测试成功,类型: {db_type}, 版本: {result[0]}") + + except Exception as e: + # 显示错误消息 + QMessageBox.critical(self, "连接失败", f"数据库连接测试失败!\n错误: {str(e)}") + logging.error(f"数据库连接测试失败,类型: {db_type}, 错误: {str(e)}") + + def save_db_settings(self): + """保存数据库设置""" + db_type = self.get_db_type() + params = self.get_connection_params()[1] + desc = self.desc_input.text().strip() + + # 这里应该将设置保存到配置文件中 + # 为了简单起见,这里只显示一个消息框 + settings_info = f"数据库类型: {db_type}\n" + for key, value in params.items(): + if key != "password": + settings_info += f"{key}: {value}\n" + else: + settings_info += f"{key}: {'*' * len(value)}\n" + + settings_info += f"说明: {desc}" + + QMessageBox.information(self, "设置已保存", f"数据库设置已保存!\n\n{settings_info}") + logging.info(f"数据库设置已保存,类型: {db_type}") \ No newline at end of file