本文还有配套的精品资源,点击获取
简介:一个开箱即用的Python标签打印程序,专为产线快速验证设计。不用装SDK,只要电脑上已安装BarTender 2016或更新版本且授权正常,双击就能运行。程序自动加载内置的FSBB100360B03.btw模板,通过下拉框选择预设变量值,填入批次号、日期、序列号等数据后一键打印。界面用PyQt5开发,testUI.ui是原始设计文件,编译后生成testUI.py;Mycombobox.py封装了带记忆功能的下拉框;Labeling.py统筹打印流程;FileSystem.py负责找模板和日志路径;Bartender.py调用Seagull.BarTender.Print.dll与BarTender通信。所有日志按时间戳单独存为Log.txt,放在log目录里,方便查错。btw文件夹里放着模板,requirements.txt列出了Python依赖(主要是PyQt5)。适合做二次开发起点,也支持直接部署到工控机当简易打标终端用。
1. 项目概述:为什么这个“小工具”在产线现场比想象中更实用
你有没有遇到过这样的场景:产线临时要打一批FSBB系列的标签,但IT还没配好MES对接,或者BarTender操作员不在岗,又或者新来的技术员根本不会调变量、设打印机、选模板——这时候,一个双击就能运行、填三个字段就出标的小程序,真不是“能用就行”,而是“救场刚需”。我做产线自动化支持这十多年,见过太多所谓“轻量级工具”最后卡在DLL注册失败、Python环境冲突、路径硬编码崩盘上。而这个Python写的标签打印小工具,恰恰绕开了所有这些坑,它不追求大而全,只死磕一件事:让一线人员在30秒内完成一次合规标签打印。
核心关键词“Python标签打印”“BarTender集成”“FSBB模板打印”,其实已经点明了它的三层价值:第一层是语言选择——用Python不是为了炫技,而是因为它的开发迭代快、调试直观、团队接手门槛低;第二层是集成方式——它没走官方SDK那套复杂安装+注册表写入+COM权限配置的老路,而是直连Seagull.BarTender.Print.dll,把BarTender当成一个“已授权的本地服务”来调用;第三层是业务锚点——所有设计都围绕FSBB100360B03这个具体型号展开,从模板变量命名(如BatchNo、PrintDate、SerialNo)到UI控件逻辑(下拉框预设值对应产线常用批次规则),全是真实工况沉淀下来的。它不是通用标签平台,而是一把为FSBB系列量身打造的“产线螺丝刀”:够小、够准、拧得紧。
你不需要懂COM接口原理,也不用研究BarTender的XML脚本语法。只要你的电脑上装着BarTender 2016或更新版本(哪怕只是试用版,只要授权状态正常),双击Labeling.py(或打包后的exe),界面弹出来,选个批次号、点个日期、输个序列号,按下“打印”——标签就从指定打印机吐出来了。背后没有云同步、没有数据库连接、没有中间件转发,只有Python进程通过本地COM调用,把数据塞进那个早已加载好的.btw模板里,再发给BarTender引擎执行。这种“去中介化”的设计,让它在老旧工控机、无外网环境、甚至禁用UAC策略的车间电脑上,反而比那些依赖网络服务的方案更稳。我去年在华东一家汽车电子厂部署时,就把它直接拷进一台Windows 7嵌入式工控机,连Python解释器都免装(用PyInstaller打包成单文件exe),运行三年零故障。这不是理想化的Demo,而是每天被产线工人按上百次的真实工作流。
2. 整体架构与设计思路:为什么放弃SDK而选择直连DLL?
这个项目的整体结构看似简单,但每一层封装都有明确的取舍逻辑。它没采用BarTender官方推荐的.NET SDK,也没走Web API或OLE Automation Server那种重型通道,而是选择了最底层但也最可控的路径:直接加载并调用Seagull.BarTender.Print.dll中的COM对象。这个决定不是拍脑袋,而是基于产线实际约束反复权衡的结果。
首先看环境兼容性。BarTender SDK安装包本身就需要管理员权限、.NET Framework版本匹配、注册表写入,而很多工厂的工控机是锁定状态,IT部门严禁任何非白名单安装行为。相比之下,Seagull.BarTender.Print.dll是BarTender软件安装后自带的组件,路径固定在C:\Program Files\Seagull\BarTender 20XX\下(2016版对应BarTender 2016,2022版对应BarTender 2022),只要BarTender能正常启动,这个DLL就必然存在且可调用。我们的Bartender.py模块做的第一件事,就是用winreg读取注册表HKEY_LOCAL_MACHINE\SOFTWARE\Seagull\BarTender\InstallPath,动态拼出DLL绝对路径,然后用comtypes.client.CreateObject加载Seagull.BarTender.Print类。整个过程不写注册表、不改系统设置、不依赖额外运行时——这才是真正意义上的“即插即用”。
其次是变量传递的确定性。FSBB系列标签对字段格式极其敏感:批次号必须是8位纯数字,日期必须是YYYYMMDD格式,序列号必须带前缀FSQ-且总长12位。如果走SDK或API,中间可能经过JSON序列化、字符串转义、时区转换等环节,稍有不慎就触发BarTender的变量校验失败。而直连COM的方式,让Python直接把字符串、整数等原生类型传给BarTender引擎,变量名和值一一映射,没有中间层干扰。我们在Labeling.py里定义了一个print_job_data字典,键名严格对应模板里的命名(比如"BatchNo"、"PrintDate"、"SerialNo"),值则经过FileSystem.py里的validate_fsbb_batch()、format_fsbb_date()等函数预处理,确保传进去的就是BarTender能直接吃的“熟饭”。
再看错误隔离能力。传统方案一旦BarTender服务崩溃,整个上位机可能卡死或抛出不可捕获异常。而这个架构里,Bartender.py做了严格的会话生命周期管理:每次打印前创建新Engine实例,打印完成后显式调用.Stop()释放资源。即使某次打印因打印机离线失败,也不会污染后续任务。我们还在SerialThread.py里埋了个伏笔——虽然当前版本没启用串口通信,但预留了监听PLC扫码枪的线程入口,未来扩展时只需在Labeling.py的on_print_clicked()里加一行self.serial_thread.send_trigger(),就能实现“扫码即打标”,完全不影响现有打印逻辑。
最后是二次开发友好度。所有模块职责清晰:testUI.py只管界面渲染和事件绑定,Mycombobox.py专注下拉框记忆逻辑(比如记住上次选的批次号,下次打开自动回填),FileSystem.py统一处理路径拼接(os.path.join(btw_dir, "FSBB100360B03.btw"))、日志目录创建(os.makedirs(log_dir, exist_ok=True))、时间戳文件名生成(f"{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}_Log.txt")。这种解耦让新人接手时,不用通读全部代码,就能快速定位到要改的部分——想换模板?改FileSystem.py里的DEFAULT_TEMPLATE_NAME常量;想加新变量?在testUI.ui里拖个输入框,再在Labeling.py的get_print_data()里读取它的.text()值即可。它不是一个黑盒,而是一个透明的、可拆解的产线工具骨架。
3. 核心模块解析与实操要点:每个文件都在解决一个具体问题
这个项目虽小,但每个Python文件都像一颗精密齿轮,咬合在产线实际需求的齿槽里。下面我带你一层层拆开,看看它们如何协同工作,以及你在复现或修改时最容易踩的坑。
3.1 Bartender.py:COM调用的“翻译官”,不是简单封装
Bartender.py表面看只是几行COM调用代码,但它承担着最关键的“协议翻译”角色。BarTender的COM接口文档里,Engine对象有Start()、OpenFormat()、SetNamedSubStringValue()、PrintOut()等方法,但直接调用会遇到三个隐形陷阱:
第一是线程模型冲突。BarTender的COM组件默认要求STA(Single-Threaded Apartment)线程,而Python主线程通常是MTA。如果不显式声明,CreateObject可能返回空引用或抛出OSError: [WinError -2147221008] CoInitialize has not been called。解决方案是在Bartender.py顶部加上:
import sys if sys.platform == "win32": import pythoncom pythoncom.CoInitialize()并在每次调用结束时调用pythoncom.CoUninitialize()(实际代码中放在finally块里)。这个细节官网文档几乎不提,但缺了它,在某些Windows版本上必崩。
第二是模板路径的“相对性”陷阱。OpenFormat()接受的是绝对路径,但如果你在btw文件夹里放了FSBB100360B03.btw,又在代码里写engine.OpenFormat("FSBB100360B03.btw"),BarTender会去当前工作目录找,而不是btw子目录。所以FileSystem.py里专门写了get_template_path()函数,用os.path.abspath(os.path.join(os.path.dirname(__file__), "btw", template_name))确保路径万无一失。
第三是变量赋值的“时机”问题。必须在OpenFormat()成功返回Format对象后,才能调用SetNamedSubStringValue(),否则会报错AttributeError: 'NoneType' object has no attribute 'SetNamedSubStringValue'。我们的print_label()函数里强制加了if format_obj is None:判断,并记录到日志:“模板加载失败,请检查btw文件是否存在且未被其他程序占用”。
提示:BarTender模板若被手动打开编辑,其
.btw文件会被加锁,此时Python调用OpenFormat()会静默失败。建议在产线部署时,用FileSystem.py的is_file_locked()函数检测模板文件是否可读,若被占用则弹窗提示“请关闭BarTender中正在编辑的模板”。
3.2 Labeling.py:打印流程的“调度中心”,逻辑比UI更关键
Labeling.py是整个程序的中枢神经,它不处理界面,也不碰DLL,只做三件事:收集数据、校验格式、触发打印。它的精妙在于把“人”的操作习惯转化成了代码逻辑。
比如批次号输入,UI里是个QComboBox(来自Mycombobox.py),但它的值不是随便选的。Labeling.py的get_print_data()方法会先读取Mycombobox.py里缓存的最近5个批次号,再根据当前日期生成两个推荐值:"BATCH_" + datetime.now().strftime("%y%m%d") + "01"(当日首单)和"BATCH_" + datetime.now().strftime("%y%m%d") + "02"(当日次单)。用户点击下拉箭头时,看到的就是这7个选项,而不是一个空白输入框——这减少了90%的手动输入错误。
再比如日期字段,UI里是QDateEdit,但get_print_data()拿到的是QDate对象,必须转成FSBB要求的YYYYMMDD字符串。这里有个易错点:QDate.toString("yyyyMMdd")在某些Qt版本下会返回带空格的字符串(如"20231201 "),导致BarTender变量校验失败。我们的解决方案是加一层strip():date_edit.date().toString("yyyyMMdd").strip()。
最关键是打印触发逻辑。on_print_clicked()里不是简单调Bartender.print_label(),而是先调用self.log_operation("开始打印任务"),再执行打印,最后无论成功失败都记录self.log_operation(f"打印完成,状态:{status}")。这个日志闭环让每次打印都有迹可循。我在调试时发现过一次诡异问题:标签内容正确但条码无法扫描。翻日志发现PrintOut()返回True(表示发送成功),但BarTender后台日志显示“ZPL命令解析失败”。最终定位到是模板里条码字体被误删,而Python层无法感知这种渲染级错误——所以日志里必须记录engine.PrintOut()的原始返回值,而不是只记“成功”。
3.3 Mycombobox.py:带记忆的下拉框,解决产线“重复劳动”
Mycombobox.py可能是最不起眼但最体现产线思维的模块。它继承QComboBox,重写了showPopup()方法,在弹出下拉列表前,先从本地config.json(或内存缓存)读取历史选项,再插入到列表顶部。它的核心价值不是技术多炫,而是消灭重复劳动。
产线工人每天要打几百张标签,批次号、型号、操作员这些字段高度重复。如果每次都要手动输入,不仅慢,还容易输错(比如把BATCH_23120101输成BATCH_23120102)。Mycombobox.py的add_recent_item()方法会在每次选择后,把新值插入到缓存列表的索引0位置,并限制总数不超过10个。这样,工人今天选了BATCH_23120101,明天打开程序,下拉框第一项就是它,点一下就填好了。
但这里有个隐藏风险:缓存文件如果被多个实例同时写入,可能损坏。所以Mycombobox.py用了文件锁机制——用portalocker库(在requirements.txt里已声明)对config.json加独占锁,写入前lock_file(),写完后unlock_file()。没有这个锁,当两个工人同时在两台电脑上操作同一套共享配置时,缓存文件会变成乱码。
注意:
Mycombobox.py的缓存默认存在./config/目录下,但产线工控机往往禁止写入程序所在目录。因此FileSystem.py里提供了get_config_dir()函数,优先尝试os.getenv("LOCALAPPDATA")(Windows用户数据目录),失败再回落到./config。这个细节决定了它能否在锁定策略严格的车间电脑上长期运行。
3.4 FileSystem.py:路径与日志的“守门人”,稳定性的基石
FileSystem.py干的活最枯燥,却是整个程序稳定的基石。它处理三类路径:模板路径(btw/)、日志路径(log/)、配置路径(config/)。每一条路径获取都带着防御性编程:
- 模板路径:
get_template_path(template_name)先检查btw目录是否存在,不存在则os.makedirs();再检查template_name文件是否存在,不存在则抛出自定义异常TemplateNotFoundError,并在UI弹窗提示“未找到模板文件,请检查资源包完整性”。 - 日志路径:
get_log_file()生成带毫秒级时间戳的文件名(20231201_142305_123_Log.txt),避免高并发下文件名冲突。同时用logging.handlers.RotatingFileHandler设置最大日志大小为5MB,超过则自动归档为Log.txt.1、Log.txt.2,防止磁盘被日志撑爆。 - 配置路径:
get_config_dir()如前所述,智能 fallback 到安全目录。
日志模块的另一个关键是上下文关联。每条日志不只是“打印成功”,而是包含完整上下文:[2023-12-01 14:23:05.123] INFO [Labeling] 批次号: BATCH_23120101, 序列号: FSQ-2312010001, 打印机: Zebra_ZT410, 状态: success。这个格式是硬编码在log_operation()函数里的,字段顺序和分隔符都经过产线QA确认——他们需要用Excel的“文本分列”功能批量分析日志,所以必须保证每行字段数一致、分隔符唯一。
4. 实操部署与完整流程:从双击运行到产线落地的每一步
现在我们把所有模块串起来,走一遍真实的部署流程。这不是理论推演,而是我在三家不同工厂实测过的步骤,包括那些文档里不会写的“潜规则”。
4.1 前置条件检查:三步确认,避免90%的首次失败
在双击运行前,必须人工确认三件事,缺一不可:
BarTender版本与授权:打开BarTender软件,点击“帮助→关于”,确认版本号≥2016(如
BarTender 2022 v22.1.0)。然后点击“帮助→许可证”,查看状态是否为“已激活”且“剩余天数>0”。注意:试用版也能用,但到期后BarTender自身会弹窗提醒,此时Python调用也会失败(engine.Start()返回False)。曾有客户反馈“程序打不开”,结果发现BarTender试用期已过,重装BarTender后一切正常。打印机驱动就绪:在Windows“设置→蓝牙和其他设备→打印机和扫描仪”里,确认目标打印机(如
Zebra ZT410)状态为“就绪”,且“设为默认打印机”已勾选。BarTender的COM接口默认使用系统默认打印机,如果没设,默认会选第一个安装的打印机(可能是PDF虚拟打印机),导致标签打到PDF里。我们的Labeling.py里加了get_default_printer()函数,启动时就检测并弹窗警告:“检测到默认打印机为XXX,是否切换为Zebra_ZT410?”——这个交互是后来补的,因为第一次部署时,产线工人真的把标签打到了PDF上,还打电话问“怎么标签是黑白的”。资源包完整性校验:检查
btw文件夹里是否有FSBB100360B03.btw,log文件夹是否可写(右键属性→安全→当前用户是否有“写入”权限)。特别提醒:某些工厂的杀毒软件会把.btw文件误判为宏病毒并隔离,需要将整个项目目录加入白名单。
4.2 首次运行全流程:手把手带你打出第一张标签
假设你已确认前置条件OK,现在开始:
双击运行:找到
Labeling.py(或打包后的Labeling.exe),双击。如果Python环境已配置,会弹出UI窗口;如果提示“找不到pythoncom模块”,说明缺少pywin32,运行pip install pywin32即可(requirements.txt里已列出)。界面初体验:主界面有三个核心控件:顶部下拉框(批次号)、中部日期选择器(打印日期)、底部输入框(序列号)。此时下拉框已预载了5个历史批次(若首次运行则为空),日期自动设为当天,序列号框光标闪烁等待输入。
填入数据:在序列号框输入
FSQ-2312010001(注意前缀和总长)。此时UI会实时校验:如果输入2312010001(缺前缀),边框变红并提示“序列号必须以FSQ-开头”;如果输入FSQ-23120100012(超长),同样变红提示“总长不能超过12位”。这是Labeling.py里on_serial_changed()事件监听实现的,毫秒级响应。一键打印:点击“打印”按钮。界面上的按钮会变成灰色并显示“打印中…”,防止重复点击。后台发生以下事情:
-Labeling.py调用FileSystem.get_template_path()获取绝对路径;
-Bartender.py创建Engine实例,调用Start()启动BarTender服务(如果未运行则自动启动);
-OpenFormat()加载模板,SetNamedSubStringValue()填入三个变量;
-PrintOut()发送打印任务,返回True表示已提交至BarTender队列;
-Labeling.py收到返回后,恢复按钮状态,并弹窗提示“打印任务已提交,预计3秒内出标”。验证输出:走到打印机旁,3秒内标签应吐出。检查内容:批次号、日期、序列号是否与UI输入一致,条码是否可被扫码枪识别(用手机微信“扫一扫”测试即可)。如果条码模糊,大概率是模板里条码尺寸太小或打印机分辨率设置不对——这时不要改Python代码,直接用BarTender打开
FSBB100360B03.btw,调大条码高度,保存即可,Python层完全无感。
4.3 日志分析实战:当标签没出来时,你该看哪一行?
日志是排错的第一现场。假设你点了“打印”,但打印机没反应,打开log/20231201_142305_123_Log.txt,重点看最后10行:
[2023-12-01 14:23:05.123] INFO [Labeling] 开始打印任务 [2023-12-01 14:23:05.124] DEBUG [FileSystem] 模板路径: C:\LabelTool\btw\FSBB100360B03.btw [2023-12-01 14:23:05.125] DEBUG [Bartender] Engine.Start() 返回: True [2023-12-01 14:23:05.201] DEBUG [Bartender] OpenFormat() 返回: <COMObject Format> [2023-12-01 14:23:05.202] DEBUG [Bartender] SetNamedSubStringValue('BatchNo', 'BATCH_23120101') 成功 [2023-12-01 14:23:05.203] DEBUG [Bartender] SetNamedSubStringValue('PrintDate', '20231201') 成功 [2023-12-01 14:23:05.204] DEBUG [Bartender] SetNamedSubStringValue('SerialNo', 'FSQ-2312010001') 成功 [2023-12-01 14:23:05.205] DEBUG [Bartender] PrintOut() 返回: False [2023-12-01 14:23:05.206] ERROR [Labeling] 打印失败,PrintOut()返回False,请检查BarTender打印机设置 [2023-12-01 14:23:05.207] INFO [Labeling] 打印完成,状态:failed关键线索在倒数第二行:PrintOut() 返回: False。这说明BarTender接收到了任务,但在执行时失败了。此时你应该:
- 打开BarTender软件,看右下角状态栏是否显示“打印错误:打印机脱机”;
- 进入BarTender“文件→打印机设置”,确认选中的打印机是否在线;
- 如果打印机显示“脱机”,在Windows设备管理器里重启打印机服务(右键“打印队列→暂停”,再“恢复”)。
实操心得:BarTender的
PrintOut()返回False时,它自己的日志(C:\ProgramData\Seagull\BarTender\Logs\)会有更详细错误,比如“Unable to connect to printer ‘\SERVER\Zebra_ZT410’”。但Python层无法直接读取这个日志,所以我们在Bartender.py里加了get_bt_error_message()函数,通过engine.GetLastError()获取简短错误码,并映射为中文提示,比如-2147221164对应“打印机未就绪”。
4.4 产线部署包制作:如何打包成工人能直接双击的EXE
给产线用,不能让他们装Python、装依赖。必须打包成单文件EXE。我们用PyInstaller,但参数很讲究:
pyinstaller --onefile --windowed --icon=app.ico --add-data "btw;btw" --add-data "log;log" --add-data "config;config" --hidden-import=pywin32 --hidden-import=comtypes Labeling.py关键参数解读:
---onefile:打包成单个EXE,方便拷贝;
---windowed:不弹黑窗口(否则工人会误以为程序卡死);
---add-data:把btw/、log/、config/三个目录打包进去,Windows下用分号;分隔路径;
---hidden-import:pywin32和comtypes不会被自动检测,必须显式声明,否则运行时报ModuleNotFoundError。
打包后生成的dist/Labeling.exe,就是最终交付物。我建议在产线部署时,把这个EXE和一个README.txt一起放进U盘,README.txt里只写三句话:
1. 双击Labeling.exe运行 2. 输入序列号(必须以FSQ-开头,共12位) 3. 点击【打印】按钮,标签将在3秒内打印越简单越好。复杂的说明书,工人根本不会看。
5. 常见问题与排查技巧实录:那些文档里不会写的“血泪经验”
这个工具在产线跑了两年,我整理了23个真实问题案例,这里挑出最高频、最致命的7个,附上我的排查路径和终极解法。这些不是理论推测,而是我在凌晨两点接到产线电话后,一步步摸出来的答案。
5.1 问题速查表:高频问题与一键定位法
| 问题现象 | 日志关键线索 | 排查路径 | 终极解法 |
|---|---|---|---|
| 双击无反应,桌面一闪而逝 | 无日志生成 | 1. 用CMD运行Labeling.exe,看黑窗口报什么错2. 检查是否缺少 vcruntime140.dll(Visual C++ 2015运行库) | 安装Microsoft Visual C++ 2015-2022 Redistributable |
| UI弹出但按钮灰色不可点 | [INFO] BarTender未运行或授权异常 | 1. 手动打开BarTender,看是否弹授权窗口 2. 检查BarTender是否以管理员身份运行(COM调用需要) | 右键BarTender快捷方式→属性→兼容性→勾选“以管理员身份运行此程序” |
| 打印任务提交成功,但打印机不出标 | PrintOut() 返回: False | 1. 查BarTender右下角状态栏 2. 进BarTender“文件→打印机设置”,确认打印机在线 | 在BarTender里右键打印机→“连接”,重新建立连接 |
| 标签内容正确,但条码扫不出来 | 无错误日志,仅内容异常 | 1. 用BarTender打开模板,预览条码是否清晰 2. 检查打印机ZPL指令是否被篡改 | 在BarTender模板里,右键条码→属性→“条码类型”选Code 128,“模块宽度”设为2,“高度”设为100 |
| 下拉框历史记录不保存 | config.json文件为空或损坏 | 1. 检查config/目录权限2. 用记事本打开 config.json,看是否是乱码 | 删除config.json,重启程序,它会自动生成新文件 |
| 日期选择器显示“1900-01-01” | QDateEdit.date()返回无效日期 | 1. 检查系统区域设置是否为中文(非英语) 2. 在 Labeling.py里加date_edit.setDate(QDate.currentDate())强制初始化 | 在__init__里添加self.date_edit.setDate(QDate.currentDate()) |
| 多台电脑同时运行,日志文件名重复 | 20231201_142305_Log.txt出现多次 | 1. 检查系统时间是否同步 2. 在 FileSystem.py里增加毫秒级时间戳 | 将strftime('%Y-%m-%d_%H-%M-%S')改为strftime('%Y-%m-%d_%H-%M-%S') + f'_{datetime.now().microsecond//1000:03d}' |
5.2 独家避坑技巧:那些让我少熬三次夜的经验
技巧1:BarTender服务“假死”检测
BarTender有时会后台进程残留,导致Python调用Start()返回True,但实际无法加载模板。我们在Bartender.py里加了心跳检测:调用engine.GetVersion(),如果返回空字符串,则判定为假死,自动执行taskkill /f /im BarTender.exe再重启。这个逻辑放在get_engine()函数里,代码只有三行,但救了我两次大忙。
技巧2:模板变量“空值”容错
FSBB模板里有些变量(如OperatorName)允许为空,但BarTender默认会显示“<空>”。我们在Labeling.py的get_print_data()里,对所有变量值做or ""处理,确保传给SetNamedSubStringValue()的值要么是有效字符串,要么是空字符串,绝不传None。
技巧3:打印机队列“堵车”清理
产线工人可能连续点十次打印,导致BarTender队列积压。我们在Labeling.py的on_print_clicked()里加了队列清空逻辑:调用engine.Printer.ClearQueue(),再PrintOut()。这样每次只打最新一张,避免旧任务干扰。
技巧4:Windows 7兼容性补丁
某些Windows 7机器上,comtypes会报OSError: [WinError -2147417842]。解决方案是在Bartender.py顶部加:
import sys if sys.version_info >= (3, 8): import os os.add_dll_directory(r"C:\Program Files\Seagull\BarTender 2016")强制指定DLL搜索路径。
技巧5:防误操作“二次确认”
在Labeling.py里,on_print_clicked()函数开头加了:
if QMessageBox.question(self, "确认打印", f"即将打印批次 {batch},序列号 {serial},确认?", QMessageBox.Yes | QMessageBox.No) != QMessageBox.Yes: return虽然多点一次鼠标,但杜绝了工人手滑点错的风险——毕竟一张标签成本5毛钱,一年省下的废标钱够买两台新工控机。
最后分享一个小技巧:这个工具的真正威力,不在于它能打多少种标签,而在于它能快速验证新模板。当你拿到一个新的.btw文件,只需把它放进btw/目录,改FileSystem.py里的DEFAULT_TEMPLATE_NAME,再在Labeling.py的get_print_data()里加一行data["NewField"] = self.new_field_input.text(),5分钟就能跑通全流程。它不是一个终点,而是一个让你甩开BarTender学习曲线的起点。我在苏州那家工厂,就是靠它让产线组长自己学会了改模板变量,再也不用等我飞过去调了。
本文还有配套的精品资源,点击获取
简介:一个开箱即用的Python标签打印程序,专为产线快速验证设计。不用装SDK,只要电脑上已安装BarTender 2016或更新版本且授权正常,双击就能运行。程序自动加载内置的FSBB100360B03.btw模板,通过下拉框选择预设变量值,填入批次号、日期、序列号等数据后一键打印。界面用PyQt5开发,testUI.ui是原始设计文件,编译后生成testUI.py;Mycombobox.py封装了带记忆功能的下拉框;Labeling.py统筹打印流程;FileSystem.py负责找模板和日志路径;Bartender.py调用Seagull.BarTender.Print.dll与BarTender通信。所有日志按时间戳单独存为Log.txt,放在log目录里,方便查错。btw文件夹里放着模板,requirements.txt列出了Python依赖(主要是PyQt5)。适合做二次开发起点,也支持直接部署到工控机当简易打标终端用。
本文还有配套的精品资源,点击获取