Python实现调用BarTender SDK对BTW模板进行预览及打印

条码老陈08-2850阅读0评论

接续上期文章《Python调用BarTender SDK实现数据源修改与打印操作详解》,许多读者反馈希望了解如何实现对BTW模板的预览功能。本文将深入讲解通过Python调用BarTender SDK生成标签预览图及打印的技术方案。

一、功能执行流程

3a8d82970f325e7029ba6f1eb199cf84.png

二、功能架构设计

class BTWPreviewApp:
    def __init__(self, root):
        # 核心组件
        self.engine = None  # BarTender引擎实例
        self.format_doc = None  # 当前打开的标签文档
        self.ui_queue = queue.Queue()  # 线程安全队列
        self.bartender_available = False  # BarTender可用标志
        
        # GUI组件
        self.file_tree = None  # 文件列表树
        self.preview_label = None  # 预览区域
        self.printer_combo = None  # 打印机选择

三、核心功能实现

1. BarTender引擎初始化与检查

def check_bartender_availability(self):
    """检查BarTender可用性"""
    try:
        import clr
        dll_path = os.path.join(os.path.dirname(__file__), 'Seagull.BarTender.Print.dll')
        if os.path.exists(dll_path):
            clr.AddReference(dll_path)
            from Seagull.BarTender.Print import Engine
            
            # 测试引擎实例
            test_engine = Engine(True)
            test_engine.Stop()
            self.bartender_available = True
        else:
            self.bartender_available = False
    except Exception as e:
        self.bartender_available = False

2. BTW文件加载与预览生成

def load_format_with_bartender(self, file_path):
    """使用BarTender加载格式并生成预览"""
    try:
        from Seagull.BarTender.Print import LabelFormatThumbnail
        from System.Drawing import Color
        
        # 关闭之前的格式
        if self.format_doc:
            self.format_doc.Close()
            
        # 打开新格式
        self.format_doc = self.engine.Documents.Open(file_path)
        
        # 生成预览图片
        thumbnail = LabelFormatThumbnail.Create(file_path, Color.White, 1200, 1200)
        
        # 两种预览处理方式
        try:
            # 方法1: 内存流直接转换
            from System.IO import MemoryStream
            from System.Drawing.Imaging import ImageFormat
            memory_stream = MemoryStream()
            thumbnail.Save(memory_stream, ImageFormat.Png)
            pil_image = Image.open(io.BytesIO(memory_stream.ToArray()))
        except:
            # 方法2: 临时文件回退方案
            pil_image = self._fallback_preview_with_temp_file(thumbnail)
        
        return pil_image
    except Exception as e:
        return None

3. 预览图像处理与显示

def update_preview_ui(self, pil_image):
    """更新预览图片UI"""
    try:
        # 调整图片尺寸
        max_display_size = 600
        img_width, img_height = pil_image.size
        if img_width > max_display_size or img_height > max_display_size:
            scale = min(max_display_size/img_width, max_display_size/img_height)
            new_size = (int(img_width*scale), int(img_height*scale))
            pil_image = pil_image.resize(new_size, Image.Resampling.LANCZOS)
        
        # 显示图片
        photo = ImageTk.PhotoImage(pil_image)
        self.preview_label.configure(image=photo)
        self.preview_label.image = photo
    except:
        # 显示错误占位符
        self.preview_label.configure(image="", text="预览加载失败")

4. 打印机管理

def load_printers_async(self):
    """异步加载打印机列表"""
    def load_printers():
        from Seagull.BarTender.Print import Printers
        printers = Printers()
        printer_names = []
        for i in range(printers.Count):
            printer = printers[i]
            printer_names.append(printer.PrinterName)
        self.ui_queue.put(("update_printers", [printer_names]))
    
    threading.Thread(target=load_printers, daemon=True).start()

5. 打印控制

def print_format(self):
    """打印当前文档"""
    def print_async():
        try:
            # 设置选择的打印机
            if self.printer_var.get():
                self.format_doc.PrintSetup.PrinterName = self.printer_var.get()
            
            # 执行打印
            result = self.format_doc.Print()
            if result:
                self.ui_queue.put(("update_status", ["打印完成"]))
            else:
                self.ui_queue.put(("update_status", ["打印失败"]))
        except Exception as e:
            self.ui_queue.put(("show_error", [str(e)]))
    
    threading.Thread(target=print_async, daemon=True).start()

四、关键技术点

1. 多线程处理与UI更新机制

def setup_ui_updater(self):
    """设置UI更新器"""
    def update_ui():
        try:
            while not self.ui_queue.empty():
                action, args = self.ui_queue.get_nowait()
                if action == "update_preview":
                    self.update_preview_ui(args[0])
                elif action == "update_printers":
                    self.update_printers_ui(args[0])
                # 其他UI更新...
        self.root.after(100, update_ui)
    
    self.root.after(100, update_ui)

2. 预览生成失败处理

def _fallback_preview_with_temp_file(self, thumbnail):
    """预览生成的回退方案"""
    try:
        import tempfile
        with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as temp_file:
            temp_path = temp_file.name
        
        # 保存到临时文件
        from System.Drawing.Imaging import ImageFormat
        thumbnail.Save(temp_path, ImageFormat.Png)
        
        # 从文件加载
        pil_image = Image.open(temp_path)
        
        # 延迟删除临时文件
        def delayed_delete():
            try:
                time.sleep(1)
                os.unlink(temp_path)
            except: pass
        
        threading.Thread(target=delayed_delete, daemon=True).start()
        
        return pil_image
    except:
        return None

3. 资源生命周期管理


def on_closing(self):
    """程序关闭时的资源清理"""
    # 关闭当前文档
    if self.format_doc:
        try:
            self.format_doc.Close()
        except: pass
    
    # 停止BarTender引擎
    if self.engine:
        try:
            self.engine.Stop()
        except: pass
    
    # 清理临时文件
    if hasattr(self, '_temp_files_to_cleanup'):
        for temp_file in self._temp_files_to_cleanup:
            try:
                os.unlink(temp_file)
            except: pass
    
    self.root.destroy()

五、关键技术点

1. .NET互操作

使用Pythonnet库实现Python与.NET的互操作:

import clr
clr.AddReference('Seagull.BarTender.Print')
from Seagull.BarTender.Print import Engine, Printers, LabelFormatDocument

2. 异步处理架构

  • 使用多线程处理耗时操作

  • 通过队列机制实现线程间通信

  • Tkinter的after方法实现UI定时更新

image.png

本文示例下载:


微信二维码
验证码:

请关注本站微信公众号,回复“0828”,获取验证码。

在微信里搜索“barcodex_cn”或微信扫描右侧二维码都可以关注本站微信公众号。

文章版权声明:除非注明,否则均为BarcodeX贝恪原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
AddoilApplauseBadlaughBombCoffeeFabulousFacepalmFecesFrownHeyhaInsidiousKeepFightingNoProbPigHeadShockedSinistersmileSlapSocialSweatTolaughWatermelonWittyWowYeahYellowdog
评论列表 (暂无评论,50人围观)

还没有评论,来说两句吧...

取消
微信二维码
微信二维码
支付宝二维码