From ecc18d0754ce02425eb22153438d4902c58337f6 Mon Sep 17 00:00:00 2001 From: zhaoyafan Date: Fri, 11 Apr 2025 19:23:11 +0800 Subject: [PATCH] First commit --- .gitignore | 5 + MesInterface.json | 1 + MesInterface.py | 687 ++++++++++++++++++++++++++++++++++++++++++++++ build.bat | 3 + favicon.ico | Bin 0 -> 206418 bytes requirements.txt | Bin 0 -> 112 bytes 6 files changed, 696 insertions(+) create mode 100644 .gitignore create mode 100644 MesInterface.json create mode 100644 MesInterface.py create mode 100644 build.bat create mode 100644 favicon.ico create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1393316 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea/ +PyQt5/ +MesInterface.build/ +MesInterface.dist/ +MesInterface.output/ diff --git a/MesInterface.json b/MesInterface.json new file mode 100644 index 0000000..e15cfd6 --- /dev/null +++ b/MesInterface.json @@ -0,0 +1 @@ +{"window_title": "MES - XXXXXX", "server_host": "10.130.97.94", "server_port": 60899, "station_id": "XXXXXX", "scan_regexp": "^.{1,128}$"} \ No newline at end of file diff --git a/MesInterface.py b/MesInterface.py new file mode 100644 index 0000000..c887abf --- /dev/null +++ b/MesInterface.py @@ -0,0 +1,687 @@ +import os +import re +import sys +import time +import json +import socket +import base64 +import shutil +import signal +import hashlib +import inspect +import tempfile +import platform +import subprocess +from pathlib import Path +from PyQt5.QtWidgets import QApplication, QMessageBox, QMenu, QAction, QWidget, QVBoxLayout, QTableWidget, QTableWidgetItem, QLabel, QFrame, QLineEdit, QMainWindow, QDesktopWidget, QHBoxLayout, QPushButton, QDialog +from PyQt5.QtCore import Qt, QCoreApplication, QDateTime, QTimer +from PyQt5.QtGui import QFont, QPalette, QColor, QBrush, QIcon + +__file__ = os.path.abspath(sys.argv[0]) + + +def _fd(f): + return f.fileno() if hasattr(f, 'fileno') else f + + +if os.name == 'nt': + import msvcrt + from ctypes import (sizeof, c_ulong, c_void_p, c_int64, Structure, Union, POINTER, windll, byref) + from ctypes.wintypes import BOOL, DWORD, HANDLE + + LOCK_SH = 0x0 + LOCK_NB = 0x1 + LOCK_EX = 0x2 + LOCK_UN = 0x9 + + if sizeof(c_ulong) != sizeof(c_void_p): + ULONG_PTR = c_int64 + else: + ULONG_PTR = c_ulong + + PVOID = c_void_p + + + class _OFFSET(Structure): + _fields_ = [ + ('Offset', DWORD), + ('OffsetHigh', DWORD) + ] + + + class _OFFSET_UNION(Union): + _fields_ = [ + ('_offset', _OFFSET), + ('Pointer', PVOID) + ] + _anonymous_ = ['_offset'] + + + class OVERLAPPED(Structure): + _fields_ = [ + ('Internal', ULONG_PTR), + ('InternalHigh', ULONG_PTR), + ('_offset_union', _OFFSET_UNION), + ('hEvent', HANDLE) + ] + _anonymous_ = ['_offset_union'] + + + LPOVERLAPPED = POINTER(OVERLAPPED) + LockFileEx = windll.kernel32.LockFileEx + LockFileEx.restype = BOOL + LockFileEx.argtypes = [HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED] + UnlockFileEx = windll.kernel32.UnlockFileEx + UnlockFileEx.restype = BOOL + UnlockFileEx.argtypes = [HANDLE, DWORD, DWORD, DWORD, LPOVERLAPPED] + + + def flock(f, flags): + hfile = msvcrt.get_osfhandle(_fd(f)) + overlapped = OVERLAPPED() + if flags == LOCK_UN: + ret = UnlockFileEx( + hfile, + 0, + 0, + 0xFFFF0000, + byref(overlapped) + ) + else: + ret = LockFileEx( + hfile, + flags, + 0, + 0, + 0xFFFF0000, + byref(overlapped) + ) + return bool(ret) +else: + try: + import fcntl + + LOCK_SH = fcntl.LOCK_SH + LOCK_NB = fcntl.LOCK_NB + LOCK_EX = fcntl.LOCK_EX + LOCK_UN = fcntl.LOCK_UN + except (ImportError, AttributeError): + LOCK_EX = LOCK_SH = LOCK_NB = 0 + + + def flock(f, flags): + return flags == LOCK_UN + else: + def flock(f, flags): + return fcntl.flock(_fd(f), flags) == 0 + + +class SafeJSONConfigReader: + def __init__(self, file: str): + try: + self.data = json.loads(open(file=os.path.abspath(file), mode='r', encoding='utf-8').read()) + except (json.JSONDecodeError, FileNotFoundError, PermissionError): + self.data = None + except (Exception,): + self.data = None + + def is_loaded_success(self): + return self.data is not None + + def get(self, key, default=None): + if (self.data is None) == 1: + return default + keys = key.split('.') + value = self.data + try: + for k in keys: + if isinstance(value, dict): + value = value.get(k) + else: + return default + if (value is None) == 1: + return default + return value + except (AttributeError, TypeError): + return default + + +class CustomLineEdit(QLineEdit): + def __init__(self, parent=None): + super().__init__(parent) + self.setContextMenuPolicy(Qt.CustomContextMenu) + self.customContextMenuRequested.connect(self.show_context_menu) + + def show_context_menu(self, pos): + menu = QMenu(self) + action_c = menu.addAction('复制') + action_c.triggered.connect(self.copy_text_content) + action_c.setEnabled(self.hasSelectedText()) + action_p = menu.addAction('粘贴') + action_p.triggered.connect(self.paste) + action_p.setEnabled(self.isEnabled()) + menu.exec_(self.mapToGlobal(pos)) + + def copy_text_content(self): + self.hasSelectedText() and self.copy() + + +class MessageBox(QDialog): + def __init__(self, title, text, parent=None): + super().__init__(parent) + self.setWindowTitle(title) + dark_palette = QPalette() + dark_palette.setColor(QPalette.Window, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.WindowText, Qt.white) + dark_palette.setColor(QPalette.Base, QColor(35, 35, 35)) + dark_palette.setColor(QPalette.Text, Qt.white) + dark_palette.setColor(QPalette.Button, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.ButtonText, Qt.white) + self.setPalette(dark_palette) + self.setStyleSheet(""" + QPushButton { + background: #444; + padding: 8px 16px; + border-radius: 4px; + color: white; + min-width: 80px; + } + QPushButton:hover { + background: #555; + } + QLabel { + color: white; + } + """) + main_layout = QVBoxLayout(self) + main_layout.setContentsMargins(20, 20, 20, 20) + main_layout.setSpacing(20) + self.labels_content = QLabel(text) + self.labels_content.setFont(QFont('Consolas', 12)) + self.labels_content.setWordWrap(True) + self.labels_content.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) + main_layout.addWidget(self.labels_content, 1) + + self.button_confirm = QPushButton('确定') + self.button_confirm.setFont(QFont('Microsoft YaHei', 12)) + self.button_confirm.clicked.connect(self.accept) + main_layout.addWidget(self.button_confirm, 0, Qt.AlignCenter) + + self.button_confirm.setFocus() + + self.adjustSize() + self.setFixedSize(self.size()) + + @classmethod + def show_message(cls, title, text, parent=None): + return cls(title, text, parent).exec_() + + +class TextInputDialog(QDialog): + def __init__(self, title, default_text, regexp, placeholder, parent=None): + super().__init__(parent) + self.setWindowTitle('%s' % (title,)) + self.setFixedSize(450, 155) + self.regexp = regexp + dark_palette = QPalette() + dark_palette.setColor(QPalette.Window, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.WindowText, Qt.white) + dark_palette.setColor(QPalette.Base, QColor(35, 35, 35)) + dark_palette.setColor(QPalette.Text, Qt.white) + self.setPalette(dark_palette) + self.setStyleSheet(""" + QLineEdit { + background: #2a2a2a; + border: 1px solid #444; + border-radius: 3px; + padding: 5px; + color: white; + } + """) + main_layout = QVBoxLayout(self) + main_layout.setContentsMargins(15, 15, 15, 15) + self.inputs_text = CustomLineEdit(default_text) + self.inputs_text.setFont(QFont('Consolas', 14)) + self.inputs_text.setPlaceholderText(placeholder) + self.inputs_text.returnPressed.connect(self.validate_and_accept) + self.inputs_text.selectAll() + main_layout.addWidget(self.inputs_text) + + def validate_and_accept(self): + text = self.inputs_text.text().strip() + if (self.regexp == '' or bool(re.match(self.regexp, text))) == 1: + self.accept() + else: + self.inputs_text.setStyleSheet('border: 1px solid red;') + self.inputs_text.setFocus() + + def text(self): + return self.inputs_text.text().strip() + + +class MainWindow(QMainWindow): + def __init__(self, app_name, app_version): + super().__init__() + self.app_name = app_name + self.app_version = app_version + self.operators = 'Unknown' + self.equipment = 'Unknown' + self.host = None + self.port = None + self.station = None + self.scan_regexp = None + self.scanning_record = [] + self.scanning_latest = [] + self.setWindowTitle('%s %s' % (self.app_name, self.app_version)) + self.setWindowIcon(QIcon(os.path.join(os.path.dirname(__file__), 'favicon.ico'))) + self.setMinimumSize(925, 728) + + frame = self.frameGeometry() + center_point = QDesktopWidget().availableGeometry().center() + frame.moveCenter(center_point) + self.move(frame.topLeft()) + + dark_palette = QPalette() + dark_palette.setColor(QPalette.Window, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.WindowText, Qt.white) + dark_palette.setColor(QPalette.Base, QColor(35, 35, 35)) + dark_palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.ToolTipBase, Qt.white) + dark_palette.setColor(QPalette.ToolTipText, Qt.white) + dark_palette.setColor(QPalette.Text, Qt.white) + dark_palette.setColor(QPalette.Button, QColor(53, 53, 53)) + dark_palette.setColor(QPalette.ButtonText, Qt.white) + dark_palette.setColor(QPalette.BrightText, Qt.red) + dark_palette.setColor(QPalette.Highlight, QColor(142, 45, 197).lighter()) + dark_palette.setColor(QPalette.HighlightedText, Qt.black) + self.setPalette(dark_palette) + self.setStyleSheet(""" + QLineEdit, QTableWidget { + background: #2a2a2a; + border: 2px solid #444; + border-radius: 5px; + padding: 5px; + color: white; + } + QHeaderView::section { + background-color: #444; + color: white; + padding: 4px; + border: 1px solid #555; + } + QTableWidget::item { + padding: 5px; + } + QPushButton { + background: #444; + padding: 5px 10px; + border-radius: 4px; + color: white; + } + QPushButton:hover { + background: #555; + } + """) + + central_widget = QWidget() + self.setCentralWidget(central_widget) + main_layout = QVBoxLayout(central_widget) + main_layout.setContentsMargins(20, 20, 20, 20) + main_layout.setSpacing(20) + + scan_layout = QVBoxLayout() + scan_layout.setSpacing(15) + + self.inputs_scan = CustomLineEdit() + self.inputs_scan.setFont(QFont('Consolas', 24)) + self.inputs_scan.setAlignment(Qt.AlignCenter) + self.inputs_scan.setPlaceholderText('') + self.inputs_scan.setMaxLength(256) + self.inputs_scan.returnPressed.connect(self.on_scan) + + self.labels_status = QLabel('') + self.labels_status.setFont(QFont('Microsoft YaHei', 24)) + self.labels_status.setAlignment(Qt.AlignCenter) + self.labels_status.setAutoFillBackground(True) + self.set_status('wait', '') + + scan_layout.addWidget(self.inputs_scan) + scan_layout.addWidget(self.labels_status) + + self.labels_history = QLabel('扫描历史') + self.labels_history.setFont(QFont('Microsoft YaHei', 14)) + self.labels_history.setStyleSheet('color: white;') + + self.tables_history = QTableWidget() + self.tables_history.setColumnCount(4) + self.tables_history.setHorizontalHeaderLabels(['时间', '条码', '结果', '详情']) + self.tables_history.horizontalHeader().setStretchLastSection(True) + self.tables_history.verticalHeader().setVisible(False) + self.tables_history.setEditTriggers(QTableWidget.NoEditTriggers) + self.tables_history.setSelectionBehavior(QTableWidget.SelectRows) + self.tables_history.setFont(QFont('Consolas', 12)) + self.tables_history.setColumnWidth(0, 200) + self.tables_history.setColumnWidth(1, 435) + self.tables_history.setColumnWidth(2, 80) + + foot_layout = QHBoxLayout() + self.labels_operator = QLabel('') + self.labels_operator.setFont(QFont('Microsoft YaHei', 14)) + self.labels_operator.setStyleSheet('color: white;') + + self.button_change_operator = QPushButton('变更作业人员') + self.button_change_operator.setFont(QFont('Microsoft YaHei', 12)) + self.button_change_operator.setStyleSheet('color: white;') + self.button_change_operator.clicked.connect(self.on_show_dialog_change_operator) + + self.button_defect = QPushButton('不良发现扫描') + self.button_defect.setFont(QFont('Microsoft YaHei', 12)) + self.button_defect.setStyleSheet('color: white;') + self.button_defect.clicked.connect(self.on_show_dialog_defect) + + foot_layout.addWidget(self.labels_operator) + foot_layout.addStretch() + foot_layout.addWidget(self.button_defect) + foot_layout.addWidget(self.button_change_operator) + + main_layout.addLayout(scan_layout) + main_layout.addWidget(self.labels_history) + main_layout.addWidget(self.tables_history) + main_layout.addLayout(foot_layout) + + self.init() + self.show() + QTimer.singleShot(35, self.init_delay) + + def init(self): + self.set_operators('Operator') + self.set_equipment('%s' % (platform.node(),)) + + def init_delay(self): + config = os.path.join(os.path.dirname(__file__), '%s.json' % (os.path.splitext(os.path.basename(__file__))[0],)) + reader = SafeJSONConfigReader(config) + if (not reader.is_loaded_success()) == 1: + MessageBox.show_message('配置文件错误', '%s' % (config,), self) + self.exit() + return None + data = reader.get('window_title'), reader.get('server_host'), reader.get('server_port'), reader.get('station_id'), reader.get('scan_regexp') + + if (not data[1] or not data[2] or not data[3]) == 1: + MessageBox.show_message('配置文件错误', '%s' % ('主机信息或工站配置错误',), self) + self.exit() + return None + try: + self.setWindowTitle('%s' % (data[0],)) + self.host, self.port, self.station, self.scan_regexp = str(data[1]).strip(), int(data[2]), str(data[3]).strip(), data[4] + except (Exception,) as e: + MessageBox.show_message('错误', '%s' % (e,), self) + self.exit() + return None + + @staticmethod + def exit(): + QApplication.quit() + + @staticmethod + def mes_upload(host: str, port: int, station_id: str, barcode: str, operators: str, equipment: str, result: int): + try: + client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + client_socket.settimeout(3.0) + client_socket.connect((host, port)) + client_socket.sendall(('100,%s,%s,%s,%s,%s,%s' % (station_id, barcode, result, operators, equipment, equipment)).encode('utf-8')) + received_data = str(client_socket.recv(1024).decode('GBK')) + client_socket.close() + if received_data.find(base64.b64decode(bytes('5p2h56CB5LiN5a2Y5Zyo', encoding='utf-8')).decode()) != -1: + return 2, '不存在的条码' + if received_data.find(base64.b64decode(bytes('5Lqn5ZOB5Z6L5Y+36ZSZ6K+v', encoding='utf-8')).decode()) != -1: + return 2, '产品型号错误' + if received_data.find(base64.b64decode(bytes('5bel5bqP5LqS5qOA5aSx6LSl', encoding='utf-8')).decode()) != -1: + return 2, '工序互检失败' + if received_data.find(base64.b64decode(bytes('6L+U5L+u5aSE55CG', encoding='utf-8')).decode()) != -1: + return 2, '条码已被锁定' + if received_data.find(base64.b64decode(bytes('5LiK5bel5bqPTkc=', encoding='utf-8')).decode()) != -1: + return 2, '上道工序不良' + if received_data.find(base64.b64decode(bytes('5rKh5pyJ5byC5bi4', encoding='utf-8')).decode()) != -1: + return 0, '' + print(received_data) + return 9, '未知错误信息' + except socket.timeout: + return 1, '网络连接超时' + + def set_status(self, status=None, message=None): + palette = self.labels_status.palette() + if status == 'wait': + palette.setColor(QPalette.WindowText, Qt.white) + palette.setColor(QPalette.Window, QColor(100, 100, 100)) + if status == 'pass': + palette.setColor(QPalette.WindowText, Qt.black) + palette.setColor(QPalette.Window, QColor(0, 255, 0)) + self.inputs_scan.setStyleSheet(""" + QLineEdit { + background: #2a2a2a; + border: 2px solid #444; + border-radius: 5px; + padding: 5px; + color: white; + } + """) + if status == 'fail': + palette.setColor(QPalette.WindowText, Qt.white) + palette.setColor(QPalette.Window, QColor(255, 0, 0)) + self.inputs_scan.setStyleSheet('border: 2px solid red;') + self.labels_status.setPalette(palette) + self.labels_status.setText(message if message else '') + + def set_operators(self, data): + self.operators = str(data).strip() + self.labels_operator.setText('作业人员: %s' % (self.operators,)) + print('人员变更 => %s' % (self.operators,)) + + def set_equipment(self, data): + self.equipment = str(data).strip() + print('设备变更 => %s' % (self.equipment,)) + + def add_scan_record(self, timestr, timestamp, barcode, results, details): + max_records = 128 + self.scanning_record.insert(0, [timestr, timestamp, barcode, results, details]) + if (len(self.scanning_record) > max_records) == 1: + self.scanning_record = self.scanning_record[:max_records] + self.tables_history.setRowCount(len(self.scanning_record)) + + for row, (_timestr, _timestamp, _barcode, _results, _details) in enumerate(self.scanning_record): + timestr_item = QTableWidgetItem(_timestr) + timestr_item.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) + self.tables_history.setItem(row, 0, timestr_item) + + barcode_item = QTableWidgetItem(_barcode) + barcode_item.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter) + self.tables_history.setItem(row, 1, barcode_item) + + results_item = QTableWidgetItem(_results) + results_item.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) + results_item.setForeground(QBrush(QColor(0, 255, 0))) if _results == 'PASS' else results_item.setForeground(QBrush(QColor(255, 0, 0))) + self.tables_history.setItem(row, 2, results_item) + + details_item = QTableWidgetItem(_details) + details_item.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter) + self.tables_history.setItem(row, 3, details_item) + + def on_scan(self, barcode: str = '', result: int = 1): + edit = self.inputs_scan + text = str(barcode).strip() if barcode else edit.text().strip() + edit.clear() if barcode else None + if (result not in [1, 2]) == 1: + return None + if (text == '') == 1: + return None + if (len(text) > 128) == 1: + self.set_status('fail', '扫描内容过长') + edit.clear() + return None + if (self.scan_regexp and isinstance(self.scan_regexp, str) and not re.match(self.scan_regexp, text)) == 1: + self.set_status('fail', '规则验证失败') + edit.selectAll() + return None + if (self.scanning_latest and self.scanning_latest[1] == text and (time.time() < self.scanning_latest[0])) == 1: + self.scanning_latest[2] and self.set_status('fail', self.scanning_latest[2]) + edit.selectAll() + return None + mes_upload_response = self.mes_upload(self.host, self.port, self.station, text, self.operators, self.equipment, result) + if (mes_upload_response[0] != 0) == 1: + self.scanning_latest = [time.time() + 1, text, ''] + self.set_status('fail', mes_upload_response[1]) + edit.selectAll() + return None + else: + self.scanning_latest = [time.time() + 5, text, '重复扫描'] + self.set_status('pass', '上传成功') + self.add_scan_record(QDateTime.currentDateTime().toString('yyyy-MM-dd hh:mm:ss'), int(time.time()), text, {1: 'PASS', 2: 'FAIL'}[result], '') + edit.clear() + return None + + def on_show_dialog_change_operator(self): + dialog = TextInputDialog(title='变更作业人员', default_text=self.operators, regexp='^[0-9A-Za-z\\-]{6,12}$', placeholder='', parent=self) + if (dialog.exec_() == QDialog.Accepted) == 1: + operator = dialog.text() + operator and self.set_operators(operator) + self.inputs_scan.setFocus() + + def on_show_dialog_defect(self): + dialog = TextInputDialog(title='不良发现扫描', default_text='', regexp='^.{1,128}$', placeholder='', parent=self) + if (dialog.exec_() == QDialog.Accepted) == 1: + products = dialog.text() + products and self.on_scan(products, 2) + self.inputs_scan.setFocus() + + +class MainRunner: + def __init__(self): + signal.signal(signal.SIGINT, self._handle_interrupt) + self.app_name = 'MesInterface' + self.app_version = '1.0.0.0' + self.app_publisher = 'zhaoyafan' + self.app_publisher_url = 'https://www.fanscloud.net/' + self.application = None + self.window = None + + def _copy_files_and_directories(self, src, dst): + function_name = inspect.currentframe().f_code.co_name + if (os.path.exists(src)) != 1: + return None + if (os.path.isdir(src)) == 1: + if not os.path.exists(dst): + os.makedirs(dst) + for item in os.listdir(src): + s = os.path.join(src, item) + d = os.path.join(dst, item) + if os.path.isdir(s): + self.__getattribute__(function_name)(s, d) + else: + shutil.copy(s, d) + else: + shutil.copy(src, dst) + + def run(self): + QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) + QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) + self.application = QApplication(sys.argv) + self.window = MainWindow(app_name=self.app_name, app_version=self.app_version) + sys.exit(self.application.exec_()) + + def build(self): + if (str(__file__).endswith('.py')) == 0: + print('Build is not currently supported.', file=sys.stderr) + exit(1) + from_home = os.path.dirname(os.path.abspath(__file__)) + dist_home = os.path.join(os.path.dirname(__file__), '%s.dist' % (os.path.splitext(os.path.basename(__file__))[0],)) + ask = input('%s %s: ' % ('Build?', '[Y/n]')) + if ask.lower().strip() == 'y': + subprocess.run(['pip', 'install', 'nuitka', '-q'], shell=True, env=os.environ) + subprocess.run([ + 'python', + '-m', + 'nuitka', + '--standalone', + '--enable-plugin=pyqt5', + '--include-module=PyQt5', + '--windows-console-mode=disable', + '--windows-icon-from-ico=favicon.ico', + '--product-name=%s' % (self.app_name,), + '--file-description=%s' % (self.app_name,), + '--product-version=%s' % (self.app_version,), + '--copyright=Copyright (C) 2025', + '--output-dir=%s' % (os.path.join(os.path.dirname(__file__)),), + '%s' % (__file__,) + ], shell=True, env=os.environ) + for i in ['PyQt5', 'favicon.ico', 'MesInterface.json']: + self._copy_files_and_directories('%s/%s' % (from_home, i), '%s/%s' % (dist_home, i)) + else: + if (not os.path.exists(dist_home)) == 1: + return None + ask = input('%s %s: ' % ('Compile setup program?', '[Y/n]')) + if ask.lower().strip() == 'y': + compile_file = os.path.join(os.path.dirname(__file__), '%s.iss' % (os.path.splitext(os.path.basename(__file__))[0],)) + compile_template = os.path.join(os.path.dirname(__file__), '%s.iss.template' % (os.path.splitext(os.path.basename(__file__))[0],)) + compiler = 'C:\\Program Files (x86)\\Inno Setup 6\\ISCC.exe' + if (os.path.exists(compile_template)) != 1: + print('The template file \"%s\" does not exist.' % (compile_template,), file=sys.stderr) + return None + if (os.path.exists(compiler)) != 1: + print('The compiler \"%s\" does not exist. Please check if Inno Setup is installed. You can download it at https://www.innosetup.com/' % (compiler,), + file=sys.stderr) + return None + Path(compile_file).write_text( + Path(compile_template).read_text().replace( + '%APPNAME%', + self.app_name + ).replace( + '%APPEXEC%', + os.path.splitext(os.path.basename(__file__))[0] + ).replace( + '%APPVERSION%', + self.app_version + ).replace( + '%APPBUILDDATE%', + time.strftime('%Y%m%d', time.localtime()) + ).replace( + '%APPPUBLISHER%', + self.app_publisher + ).replace( + '%APPPUBLISHERURL%', + self.app_publisher_url + ).replace( + '%DISABLEX64%', + '' if platform.architecture()[0] == '64bit' else '; ' + ) + ) + subprocess.run([compiler, compile_file]) + + def _handle_interrupt(self, _signal, _frame): + print('Exit.', file=sys.stderr) + self.handle_interrupt() + + def handle_interrupt(self): + try: + self.window.exit() + except Exception as e: + print(e, file=sys.stderr) + + +if __name__ == '__main__': + if (os.path.basename(__file__).lower().endswith('.int')) == 1: + QCoreApplication.addLibraryPath(os.path.join(os.path.dirname(__file__), 'site-packages/PyQt5/Qt5/plugins')) + else: + QCoreApplication.addLibraryPath(os.path.join(os.path.dirname(__file__), 'PyQt5/Qt5/plugins')) + f_lock = open(file=os.path.join(tempfile.gettempdir(), '%s.lock' % hashlib.md5(bytes(__file__, encoding='utf-8')).hexdigest()[:16]), mode='w', encoding='utf-8') + if (not flock(f_lock, LOCK_EX | LOCK_NB)) == 1: + app = QApplication(sys.argv) + msg = QMessageBox() + msg.setIcon(QMessageBox.Warning) + msg.setText('The application is already running.') + msg.setWindowTitle('Warning') + msg.setStandardButtons(QMessageBox.Cancel) + msg.exec_() + app.exit(1) + sys.exit(1) + else: + MainRunner().run() if (len(sys.argv) > 1 and sys.argv[1] == '--build') == 0 else MainRunner().build() diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..26eed86 --- /dev/null +++ b/build.bat @@ -0,0 +1,3 @@ +@echo off +@chcp 65001 +@python MesInterface.py --build diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..caf21dcc1233f41922bba2eb2c5e13290ba3aefc GIT binary patch literal 206418 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 literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..4b47cce503c6bc375b4756d8820f96fd2a675c47 GIT binary patch literal 112 zcmezWFMy$vA&{Yj!IZ%k2u&IE7!0ALAp