From ec31dd43ad8277e1d64bdb97c007b5d78195cb67 Mon Sep 17 00:00:00 2001 From: zhaoyafan Date: Mon, 1 Apr 2024 16:51:26 +0800 Subject: [PATCH] First commit --- BarTender.dll | Bin 0 -> 171600 bytes main.py | 971 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | Bin 0 -> 276 bytes rules.json | 70 ++++ settings.json | 7 + 5 files changed, 1048 insertions(+) create mode 100644 BarTender.dll create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 rules.json create mode 100644 settings.json diff --git a/BarTender.dll b/BarTender.dll new file mode 100644 index 0000000000000000000000000000000000000000..95653d21a2484e8f8c89c232fa49dc585679fd94 GIT binary patch literal 171600 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%0A7i2tlYt#3EjOT7$ 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 i_YdzoZQ{GXeRWX9v7di@W8= 0: raise Exception('Range error.') + if limit_rows is not None and not limit_rows >= 0: raise Exception('Range error.') + self.class_name = class_name + self.limit_rows = limit_rows + self.limit_time = limit_time + try: + self.database = SQLite3(db_file) + self.init_database() + except sqlite3.DatabaseError: + self.database.close() and os.remove(db_file) + raise Exception('The database was damaged and has been reset.') + + def init_database(self): + with self.rLock: + self.database.execute(''' + CREATE TABLE IF NOT EXISTS "ditto" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "class" TEXT(64) COLLATE NOCASE, + "value" TEXT(256) COLLATE NOCASE, + "time" integer(12) + ); + ''') + + def fresh(self): + with self.rLock: + if self.limit_time is not None: self.database.execute(''' + DELETE FROM ditto WHERE class='%s' AND time < %s; + ''' % (self.class_name, (int(time.time()) - self.limit_time))) + if self.limit_rows is not None: self.database.execute(''' + DELETE FROM ditto WHERE id IN (SELECT id FROM (SELECT id FROM ditto WHERE class='%s' ORDER BY time DESC LIMIT %s,100)); + ''' % (self.class_name, self.limit_rows)) + + def count(self): + with self.rLock: + self.fresh() + self.database.execute(''' + SELECT COUNT(1) AS rows FROM ditto WHERE class='%s'; + ''' % (self.class_name,)) + return self.database.fetchone()['rows'] + + def clear(self): + with self.rLock: + self.fresh() + self.database.execute(''' + DELETE FROM ditto WHERE class='%s'; + ''' % (self.class_name,)) + return self.database.rownums() + + def query(self, value): + with self.rLock: + self.fresh() + self.database.execute(''' + SELECT COUNT(1) AS rows FROM ditto WHERE class='%s' AND value='%s'; + ''' % (self.class_name, value)) + return self.database.fetchone()['rows'] + + def addit(self, value): + with self.rLock: + if self.query(value) != 0: return False + self.database.execute(''' + INSERT INTO ditto (\"class\", \"value\", \"time\") VALUES ('%s', '%s', '%s'); + ''' % (self.class_name, value, int(time.time()))) + self.fresh() + return True + + +class LoggerFileHandler: + def __init__(self, log_file: str, mode: str = 'a', level: str = None, fmt: str = None): + self.log, self.mod = log_file, mode + self.lev, self.fmt = level, fmt + self.sty = '%' + + +class LoggerConsHandler: + def __init__(self, level: str = None, fmt: str = None): + self.lev, self.fmt = level, fmt + self.sty = '%' + + +class Logger: + logger = None + levels = { + 'CRITICAL': logging.CRITICAL, + 'FATAL': logging.FATAL, + 'ERROR': logging.ERROR, + 'WARNING': logging.WARNING, + 'WARN': logging.WARN, + 'INFO': logging.INFO, + 'DEBUG': logging.DEBUG, + 'NOTSET': logging.NOTSET, + 'D': logging.DEBUG, + 'I': logging.INFO, + 'W': logging.WARNING, + 'E': logging.ERROR, + 'F': logging.FATAL + } + default_format = '{asctime} - {name} - {levelname[0]}: {message}' + default_format_style = '{' + handler_list = [] + + def __init__( + self, + name: str = 'default', + default_level='DEBUG', + fh: LoggerFileHandler = None, + ch: LoggerConsHandler = None, + add_default_handler=False + ): + ch = LoggerConsHandler() if add_default_handler and not ch else ch + if fh and not isinstance(fh, LoggerFileHandler): + raise TypeError('The parameter fh must be type.') + if ch and not isinstance(ch, LoggerConsHandler): + raise TypeError('The parameter ch must be type.') + + self.logger = logging.getLogger(name) + self.logger.setLevel(self.levels[default_level]) + + if fh: + fhandler = logging.FileHandler(filename=fh.log, mode=fh.mod, encoding='utf-8') + self.handler_list.append(fhandler) + fhandler.setLevel(self.levels[fh.lev or default_level]) + fh.fmt = fh.fmt or self.default_format + fh.sty = '{' if '%' not in fh.fmt else '%' + fhandler.setFormatter(logging.Formatter(fmt=fh.fmt, style=fh.sty)) + self.logger.addHandler(fhandler) + if ch: + chandler = logging.StreamHandler() + self.handler_list.append(chandler) + chandler.setLevel(self.levels[ch.lev or default_level]) + ch.fmt = ch.fmt or self.default_format + ch.sty = '{' if '%' not in ch.fmt else '%' + chandler.setFormatter(logging.Formatter(fmt=ch.fmt, style=ch.sty)) + self.logger.addHandler(chandler) + + self.d = self.logger.debug + self.i = self.logger.info + self.w = self.logger.warning + self.e = self.logger.error + self.f = self.logger.fatal + self.c = self.logger.critical + + +class Setting(dict): + def __init__(self, setting_file: str, setting_default: dict): + self.data_file = os.path.abspath(setting_file) + super().__init__(getJson(self.data_file, setting_default)) + + def __getitem__(self, item): + if item in self: + return super().__getitem__(item) + else: + return None + + def __setitem__(self, key, value): + super().__setitem__(key, value) + putJson(self.data_file, self) + + +class BarTenderPrint: + def __init__(self, logger: Logger): + self.logger = logger + self.label = None + self.print = None + self.sheet = None + self.bt_app = BarTender.Application() + self.bt_app.Visible = False + self.bt_format = None + self.printer_list = [printer[2] for printer in win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL)][::-1] + self.printer_current_index = 0 + self.template_source_primary = {} + self.logger.i('%s%s' % ('Init', '')) + + def set_label(self, data: str): + self.label = os.path.abspath(data) + self.logger.i('%s%s' % ('Open the label template ', self.label)) + for _ in range(2): + if (self.bt_format is not None) == 1: + self.bt_format.Close(BarTender.BtSaveOptions.btDoNotSaveChanges) + self.bt_format = self.bt_app.Formats.Open(self.label, False, '') + self.template_source_primary = {} + self.set_print(self.printer_current_index or 0) + self.set_sheet(self.sheet or 1) + + def set_print(self, data: int): + self.printer_current_index = data + self.print = self.printer_list[self.printer_current_index] + self.logger.i('%s%s' % ('Printer set to ', self.print)) + if (self.bt_format is not None) == 1: + self.bt_format.PrintSetup.Printer = self.print + + def set_sheet(self, data: int): + self.sheet = int(data) + self.logger.i('%s%s' % ('Number of copies ', self.sheet)) + if (self.bt_format is not None) == 1: + self.bt_format.PrintSetup.IdenticalCopiesOfLabel = self.sheet + + def set_data_source(self, name, value): + if name not in self.template_source_primary.keys(): + self.template_source_primary[name] = self.bt_format.GetNamedSubStringValue(name) + self.logger.i('%s%s' % ('Set data source ', '%s=%s' % (name, value))) + self.bt_format.SetNamedSubStringValue(name, value) + + def start_printing(self, content: str): + for k, v in {'A': content}.items(): + self.set_data_source(k, v) + if (self.bt_format is not None) == 1: + self.logger.i('%s%s' % ('Printing ', 'normal')) + self.bt_format.PrintOut(False, False) + + def start_printing_template(self): + for k, v in self.template_source_primary.items(): + self.set_data_source(k, v) + if (self.bt_format is not None) == 1: + self.logger.i('%s%s' % ('Printing ', 'template')) + self.bt_format.PrintOut(False, False) + + def generate_preview(self): + path = os.path.abspath(os.path.join(tempfile.gettempdir(), '%s%s.png' % ('preview_', int(round(time.time() * 1000))))) + if (self.bt_format is not None) == 1: + self.logger.i('%s%s' % ('Generate preview to ', path)) + self.bt_format.ExportToFile(path, 'PNG', BarTender.BtColors.btColors24Bit, BarTender.BtResolution.btResolutionPrinter, BarTender.BtSaveOptions.btDoNotSaveChanges) + return path + + def quit(self): + if (self.bt_format is not None) == 1: + self.logger.i('%s%s' % ('Quit', '')) + try: + self.bt_format.Close(BarTender.BtSaveOptions.btDoNotSaveChanges) + self.bt_app.Quit(BarTender.BtSaveOptions.btDoNotSaveChanges) + except Exception: + pass + self.bt_format = None + self.bt_app = None + + +class ScanVerify: + def __init__(self, logger, rule_file): + self.logger = logger + self.checker_list = [['无', '.*']] + self.checker_list.extend(getJson(os.path.abspath(rule_file), [])) + self.checker_current_index = 0 + + def set_check(self, data: int): + self.checker_current_index = data + self.logger.i('%s%s' % ('Checker set to ', self.checker_list[self.checker_current_index][0])) + + def verify(self, content: str): + return bool(re.match(self.checker_list[self.checker_current_index][1], content)) + + +class CustomLineEdit(QLineEdit): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setStyleSheet('font-size: 12px; font-family: \'Microsoft YaHei\'; color: #000000;') + + def contextMenuEvent(self, event): + menu = QMenu(self) + action_c = menu.addAction('复制') + action_p = menu.addAction('粘贴') + action_c.triggered.connect(self.copy) + action_p.triggered.connect(self.paste) + menu.popup(self.mapToGlobal(event.pos())) + + +class CustomLineEditNoPopup(QLineEdit): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setStyleSheet('font-size: 12px; font-family: \'Microsoft YaHei\'; color: #656565;') + + def contextMenuEvent(self, event): + pass + + +class CustomPushButton(QPushButton): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setStyleSheet('font-size: 12px; font-family: \'Microsoft YaHei\'; color: #0C0C0C;') + + +class CustomLabel(QLabel): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setStyleSheet('font-size: 12px; font-family: \'Microsoft YaHei\'; color: #0C0C0C; border: 1px solid #0C0C0C;') + + +class CustomComboBox(QComboBox): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setStyleSheet('font-size: 12px; font-family: \'Microsoft YaHei\'; color: #0C0C0C;') + + +class CustomCheckBox(QCheckBox): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setStyleSheet('font-size: 12px; font-family: \'Microsoft YaHei\'; color: #0C0C0C;') + + +class CustomHBoxLayout(QHBoxLayout): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setAlignment(Qt.AlignTop | Qt.AlignLeft) + + +class CustomVBoxLayout(QVBoxLayout): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.setAlignment(Qt.AlignTop | Qt.AlignLeft) + + +class MainWindow(QMainWindow): + def __init__(self, logger: Logger): + super().__init__() + self.app_name = '标签打印' + self.app_version = ('1.0.1', '20240401', 'zhaoyafan', 'zhaoyafan@foxmail.com', 'https://www.fanscloud.net/') + self.logger = logger + self.setting = Setting(os.path.abspath(os.path.join(os.path.dirname(__file__), 'settings.json')), {}) + self.bt = BarTenderPrint(logger=self.logger) + self.sv = ScanVerify(logger=self.logger, rule_file=os.path.abspath(os.path.join(os.path.dirname(__file__), 'rules.json'))) + self.ditto = Ditto(db_file='%s.db' % (os.path.splitext(__file__)[0],), class_name='LabelPrint', limit_time=7776000, limit_rows=100000) + self.last_opened_template = ['', ''] + self.input_convert_letter = 0 + self.setWindowTitle(self.app_name) + self.setGeometry(0, 0, 600, 400) + self.statusBar() + self.menubar = self.menuBar() + filemenu = self.menubar.addMenu('文件') + self.blockRepeatAction = QAction('禁止重复打印', self, checkable=True) + self.clearRecordAction = QAction('清空打印记录', self) + filemenu.addActions( + [ + self.blockRepeatAction, + self.clearRecordAction + ] + ) + moremenu = self.menubar.addMenu('更多') + self.designStateAction = QAction('编辑模式', self, checkable=True) + self.createShortAction = QAction('发送快捷方式到桌面', self) + self.aboutWindowAction = QAction('关于', self) + self.blockRepeatAction.triggered.connect(self.blockRepeatActionFunction) + self.clearRecordAction.triggered.connect(self.clearRecordActionFunction) + self.designStateAction.triggered.connect(self.designStateActionFunction) + self.createShortAction.triggered.connect(self.createShortActionFunction) + self.aboutWindowAction.triggered.connect(self.aboutWindowActionFunction) + moremenu.addActions( + [ + self.designStateAction, + self.createShortAction, + self.aboutWindowAction + ] + ) + # 定义布局 + m_layout_0 = CustomVBoxLayout() + l_layout_0 = CustomVBoxLayout() + l_layout_1 = CustomHBoxLayout() + l_layout_2 = CustomVBoxLayout() + r_layout_0 = CustomVBoxLayout() + r_layout_1 = CustomHBoxLayout() + r_layout_2 = CustomHBoxLayout() + r_layout_3 = CustomVBoxLayout() + l_layout_0.addLayout(l_layout_1) + l_layout_0.addLayout(l_layout_2) + r_layout_0.addLayout(r_layout_1) + r_layout_0.addLayout(r_layout_2) + r_layout_0.addLayout(r_layout_3) + m_layout_0.addLayout(l_layout_0) + m_layout_0.addLayout(r_layout_0) + + # Select file + self.butSTP = CustomPushButton('选择文件') + self.butSTP.setFixedSize(82, 27) + self.butSTP.clicked.connect(self.on_open_template_file) + l_layout_1.addWidget(self.butSTP) + # Template name + self.edtNTP = CustomLineEditNoPopup('') + self.edtNTP.setReadOnly(True) + self.edtNTP.setFixedSize(280, 27) + l_layout_1.addWidget(self.edtNTP) + # Test printing + self.butTPT = CustomPushButton('测试打印') + self.butTPT.setFixedSize(82, 27) + self.butTPT.clicked.connect(self.on_test_print) + l_layout_1.addWidget(self.butTPT) + # Print preview + self.labPRV = CustomLabel() + self.labPRV.setAlignment(Qt.AlignCenter) + self.labPRV.setFixedSize(455, 256) + l_layout_2.addWidget(self.labPRV) + # Printer + self.labNPT = CustomLabel('打印机选择') + self.labNPT.setFixedSize(82, 27) + r_layout_1.addWidget(self.labNPT) + # Select printer + self.slcSPT = CustomComboBox() + self.slcSPT.addItems(self.bt.printer_list) + self.slcSPT.setFixedSize(233, 27) + self.slcSPT.currentIndexChanged.connect(self.on_printer_changed) + r_layout_1.addWidget(self.slcSPT) + # Number of copies + self.labPQT = CustomLabel('打印份数') + self.labPQT.setFixedSize(82, 27) + r_layout_1.addWidget(self.labPQT) + self.edtNQT = CustomLineEditNoPopup('1') + self.edtNQT.setFixedSize(40, 27) + self.edtNQT.textChanged.connect(self.on_copies_editing_changed) + validator = QIntValidator(1, 999) + self.edtNQT.setValidator(validator) + r_layout_1.addWidget(self.edtNQT) + # Input verification + self.labNVR = CustomLabel('扫描验证') + self.labNVR.setFixedSize(82, 27) + r_layout_2.addWidget(self.labNVR) + # Select input verification + self.slcSVR = CustomComboBox() + self.slcSVR.addItems([data[0] for data in self.sv.checker_list]) + self.slcSVR.setFixedSize(233, 27) + self.slcSVR.currentIndexChanged.connect(self.on_checker_changed) + r_layout_2.addWidget(self.slcSVR) + # Convert letter + self.chkCVL = CustomCheckBox('强制转换大写') + self.chkCVL.setFixedSize(128, 27) + self.chkCVL.stateChanged.connect(self.on_convert_letter_changed) + r_layout_2.addWidget(self.chkCVL) + # Scan + self.edtSCN = CustomLineEdit('') + self.edtSCN.setStyleSheet('QLineEdit {font-size: 28px; font-family: \'Microsoft YaHei\'; color: #000000; background-color: #FFFFCC;}') + self.edtSCN.setFixedSize(455, 45) + r_layout_3.addWidget(self.edtSCN) + # Print button + self.butSPT = CustomPushButton('打印') + self.butSPT.setFixedSize(455, 45) + self.butSPT.clicked.connect(self.on_start_printing) + self.edtSCN.returnPressed.connect(self.butSPT.click) + r_layout_3.addWidget(self.butSPT) + + # 显示界面 + central_widget = QWidget() + central_widget.setLayout(m_layout_0) + self.setCentralWidget(central_widget) + self.setFixedSize(self.minimumSizeHint()) + screen_rect = QApplication.desktop().availableGeometry() + window_rect = self.geometry() + self.move(int((screen_rect.width() - window_rect.width()) * 0.5), int((screen_rect.height() - window_rect.height()) * 0.5)) + self.edtSCN.setFocus() + self.show() + self.load_setting() + + def closeEvent(self, event): + self.bt.quit() + event.accept() + + def load_setting(self): + # load blockRepeat + self.blockRepeatAction.setChecked(bool(self.setting['blockRepeat'])) + # load printer + self.slcSPT.setCurrentIndex(next((index for index, item in enumerate(self.bt.printer_list) if item == self.setting['printer']), 0)) + # load checker + self.slcSVR.setCurrentIndex(self.setting['checker'] or 0) + # load printCopies + self.edtNQT.setText(str(self.setting['printCopies'] or 1)) + # load template + tempfile_last = self.setting['template'] + if (tempfile_last and os.path.exists(tempfile_last)) == 1: + self.load_template(tempfile_last) + else: + self.setting['template'] = '' + + def blockRepeatActionFunction(self, checked): + self.setting['blockRepeat'] = bool(checked) + + def clearRecordActionFunction(self): + count = self.ditto.clear() + if (count > 0) == 1: + QMessageBox.information(self, '提示', '打印记录已经清空:%s' % (count,)) + + def designStateActionFunction(self, checked): + if (not self.bt.bt_app) == 1: + return None + if (checked is True) == 1: + t1 = '1.在编辑模式中您可以动态对模板进行修改;' + t2 = '2.保存模板将会覆盖原文件永久生效;' + t3 = '3.修改完成后手动关闭编辑模式;' + QMessageBox.information(self, '提示', '%s\n%s\n%s' % (t1, t2, t3)) + self.bt.bt_app.Visible = bool(1) + else: + self.bt.bt_app.Visible = bool(0) + filename = self.last_opened_template[0] + if (filename == '' or not os.path.exists(filename)) == 1: + return None + last_md5 = self.last_opened_template[1] + temp_md5 = self.md5(open(self.last_opened_template[0], 'rb')) + QMessageBox.information(self, '提示', '模板文件已被修改:\n\n%s' % filename) if (last_md5 != temp_md5) == 1 else None + self.last_opened_template[1] = temp_md5 + + def createShortActionFunction(self): + target = '%s.exe' % (os.path.splitext(__file__)[0],) + shortcut_path = self.path_expandvars('%%USERPROFILE%%\\Desktop\\%s.lnk' % (self.app_name,)) + if (os.path.exists(target)) == 1: + self.create_shortcut(target, shortcut_path, 1) + QMessageBox.information(self, '提示', '%s' % ('已成功发送快捷方式到桌面',)) + + def aboutWindowActionFunction(self): + _c = self.app_version + if (not _c) == 0: + QMessageBox.information(self, '关于', "" 'version: %s, build: %s, author: %s, email: %s, site: %s' % (_c[0], _c[1], _c[2], _c[3], '%s' % (_c[4], _c[4]))) + + @staticmethod + def md5(input_data): + if isinstance(input_data, bytes): + return hashlib.md5(input_data).hexdigest() + if isinstance(input_data, str): + return hashlib.md5(bytes(input_data, encoding='utf-8')).hexdigest() + md5_object = hashlib.md5() + while True: + data = input_data.read(io.DEFAULT_BUFFER_SIZE) + if data: + md5_object.update(data) + else: + return md5_object.hexdigest() + + @staticmethod + def path_expandvars(path): + resolve = os.path.expandvars(path) + if (re.search('%[A-Za-z0-9_]+%', resolve)) is not None: + raise Exception('Variable analysis failed') + return resolve + + @staticmethod + def create_shortcut(target, shortcut_path, run_as_admin): + shell = win32com.client.Dispatch('WScript.Shell') + try: + os.remove(shortcut_path) + except FileNotFoundError: + pass + shortcut = shell.CreateShortCut(shortcut_path) + shortcut.TargetPath = target + if shortcut_path.endswith('.lnk'): + shortcut.Arguments = '' + shortcut.WorkingDirectory = os.path.dirname(target) + if target.startswith('\\\\'): + shortcut.WorkingDirectory = '' + shortcut.save() + if shortcut_path.endswith('.lnk') and run_as_admin: + with open(shortcut_path, 'r+b') as f: + if os.path.isfile(shortcut_path): + f.seek(21, 0) + f.write(b'\x22\x00') + + def set_preview(self, preview_image: str): + if (preview_image and os.path.exists(preview_image)) == 1: + pixmap = QPixmap(preview_image) + pixmap = pixmap.scaled(self.labPRV.size(), aspectRatioMode=Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation) + self.labPRV.setPixmap(pixmap) + if (tempfile.gettempdir() in preview_image) == 1: + rm(preview_image) + + def set_template_name(self, name): + if (isinstance(name, str)) == 1: + self.edtNTP.setText(name) + + def load_template(self, file): + try: + if (file != '' and os.path.exists(file)) == 1: + self.bt.set_label(file) + self.set_template_name(os.path.splitext(os.path.basename(file))[0]) + self.set_preview(self.bt.generate_preview()) + self.last_opened_template[0] = file + self.last_opened_template[1] = self.md5(open(file, 'rb')) + except pywintypes.com_error as e: + t = str(e.args[1]) + m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2]) + if (len(t) > 5) == 1: + m = '%s\n\n%s' % (t, m) + t = '错误' + QMessageBox.critical(self, t, m) + except AttributeError: + QMessageBox.critical(self, '错误', '调用服务失败') + except Exception as e: + QMessageBox.critical(self, '错误', '%s' % e) + + def on_open_template_file(self): + filename, _ = QFileDialog.getOpenFileName(self, '打开文件', os.path.dirname(self.last_opened_template[0]), 'BarTender 文档 (*.btw)') + if (filename and os.path.exists(filename)) == 1: + self.load_template(filename) + self.setting['template'] = filename + + def on_test_print(self): + try: + if (self.bt.bt_format is not None) == 1: + self.bt.start_printing_template() + self.set_preview(self.bt.generate_preview()) + return None + QMessageBox.critical(self, '错误', '请先加载模板文件') + except pywintypes.com_error as e: + t = str(e.args[1]) + m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2]) + if (len(t) > 5) == 1: + m = '%s\n\n%s' % (t, m) + t = '错误' + QMessageBox.critical(self, t, m) + except AttributeError: + QMessageBox.critical(self, '错误', '调用服务失败') + except Exception as e: + QMessageBox.critical(self, '错误', '%s' % e) + + def on_printer_changed(self, index): + try: + self.bt.set_print(index) + self.set_preview(self.bt.generate_preview()) + self.setting['printer'] = str(self.bt.print) + except pywintypes.com_error as e: + t = str(e.args[1]) + m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2]) + if (len(t) > 5) == 1: + m = '%s\n\n%s' % (t, m) + t = '错误' + QMessageBox.critical(self, t, m) + except AttributeError: + QMessageBox.critical(self, '错误', '调用服务失败') + except Exception as e: + QMessageBox.critical(self, '错误', '%s' % e) + + def on_checker_changed(self, index): + try: + self.sv.set_check(index) + self.setting['checker'] = index + except pywintypes.com_error as e: + t = str(e.args[1]) + m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2]) + if (len(t) > 5) == 1: + m = '%s\n\n%s' % (t, m) + t = '错误' + QMessageBox.critical(self, t, m) + except AttributeError: + QMessageBox.critical(self, '错误', '调用服务失败') + except Exception as e: + QMessageBox.critical(self, '错误', '%s' % e) + + def on_copies_editing_changed(self, text): + try: + if (text == '' or int(text) == 0) == 1: + text = '1' + self.edtNQT.setText(text) + else: + copies = int(text) + self.bt.set_sheet(copies) + self.setting['printCopies'] = copies + except pywintypes.com_error as e: + t = str(e.args[1]) + m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2]) + if (len(t) > 5) == 1: + m = '%s\n\n%s' % (t, m) + t = '错误' + QMessageBox.critical(self, t, m) + except AttributeError: + QMessageBox.critical(self, '错误', '调用服务失败') + except Exception as e: + QMessageBox.critical(self, '错误', '%s' % e) + + def on_convert_letter_changed(self, checked): + if (checked == 2) == 1: + self.input_convert_letter = 1 + else: + self.input_convert_letter = 0 + + def on_start_printing(self): + edit = self.edtSCN + if (self.input_convert_letter == 1) == 1: + text = edit.text().strip().upper() + else: + text = edit.text().strip() + edit.setText(text) + if (self.bt.bt_format is None) == 1: + edit.selectAll() + return None + if (text == '') == 1: + edit.selectAll() + return None + if (not self.sv.verify(text)) == 1: + QMessageBox.critical(self, '错误', '打印的内容不符合验证规则:\n\n%s' % (text,)) + edit.selectAll() + return None + if (not self.ditto.addit(text) and self.setting['blockRepeat']) == 1: + QMessageBox.critical(self, '错误', '重复打印:\n\n%s' % (text,)) + edit.selectAll() + return None + try: + self.bt.start_printing(text) + self.set_preview(self.bt.generate_preview()) + edit.clear() + except pywintypes.com_error as e: + t = str(e.args[1]) + m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2]) + if (len(t) > 5) == 1: + m = '%s\n\n%s' % (t, m) + t = '错误' + QMessageBox.critical(self, t, m) + except AttributeError: + QMessageBox.critical(self, '错误', '调用服务失败') + except Exception as e: + QMessageBox.critical(self, '错误', '%s' % e) + + +if __name__ == '__main__': + if (os.path.basename(__file__).lower().endswith('.int')) == 1: + QCoreApplication.addLibraryPath(os.path.abspath(os.path.join(os.path.dirname(__file__), 'site-packages/PyQt5/Qt5/plugins'))) + f_lock = open(file='%s.lock' % (os.path.splitext(__file__)[0],), 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('程序已经在运行中') + msg.setWindowTitle('提示') + msg.setStandardButtons(QMessageBox.Ok) + msg.exec_() + app.exit(1) + sys.exit(1) + try: + win32com.client.Dispatch('BarTender.Application') + except pywintypes.com_error: + app = QApplication(sys.argv) + msg = QMessageBox() + msg.setIcon(QMessageBox.Critical) + msg.setText('初始化失败,请检查BarTender是否已安装。') + msg.setWindowTitle('错误') + msg.setStandardButtons(QMessageBox.Ok) + msg.exec_() + app.exit(1) + sys.exit(1) + app = QApplication(sys.argv) + window_main = MainWindow(logger=Logger(name='main', fh=LoggerFileHandler(log_file='%s.log' % (os.path.splitext(__file__)[0],), mode='w'), ch=LoggerConsHandler())) + sys.exit(app.exec_()) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..af5698ff1aba915e5d324b8e365f8a795e212a3e GIT binary patch literal 276 zcmZvXQ3``F5Jcx&=usj`ME`n+dW2$?3Sz|y(#yAfYovuzmYr;vm)*_l*{CCW9f_cv ztWd9mGBp}B%b_=&by3UBI1drYYNIASASZ}f_YY%!B&^Q~qSm5vdtKrLYST35>$|_) rZx_d$o{4E^n-o-_shjPy=*rF`(NY_i{G8J^GG?X6$UW}9-~aOlKMp2^ literal 0 HcmV?d00001 diff --git a/rules.json b/rules.json new file mode 100644 index 0000000..4bb2060 --- /dev/null +++ b/rules.json @@ -0,0 +1,70 @@ +[ + [ + "MAC地址", + "^[0-9A-F]{12}$" + ], + [ + "大写字母或数字", + "^[0-9A-Z]+$" + ], + [ + "10位长度", + "^.{10}$" + ], + [ + "11位长度", + "^.{11}$" + ], + [ + "12位长度", + "^.{12}$" + ], + [ + "13位长度", + "^.{13}$" + ], + [ + "14位长度", + "^.{14}$" + ], + [ + "15位长度", + "^.{15}$" + ], + [ + "16位长度", + "^.{16}$" + ], + [ + "17位长度", + "^.{17}$" + ], + [ + "18位长度", + "^.{18}$" + ], + [ + "19位长度", + "^.{19}$" + ], + [ + "20位长度", + "^.{20}$" + ], + [ + "21位长度", + "^.{21}$" + ], + [ + "22位长度", + "^.{22}$" + ], + [ + "23位长度", + "^.{23}$" + ], + [ + "24位长度", + "^.{24}$" + ] +] diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..1fc0f73 --- /dev/null +++ b/settings.json @@ -0,0 +1,7 @@ +{ + "template": "", + "printer": "", + "checker": 0, + "printCopies": 1, + "blockRepeat": false +} \ No newline at end of file