import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import barcode
from barcode.writer import ImageWriter
import os
import threading
import time
class BarcodeGeneratorApp:
def __init__(self, root):
self.root = root
self.root.title("Code128 条形码生成器")
self.root.geometry("500x550")
# 变量初始化
self.file_path = ""
self.is_running = False
self.current_line = 0
self.lines = []
# 创建界面组件
self.create_widgets()
def create_widgets(self):
# 文件选择区域
file_frame = tk.Frame(self.root)
file_frame.pack(pady=10, fill=tk.X, padx=20)
tk.Label(file_frame, text="选择文本文件:").pack(anchor=tk.W)
self.path_label = tk.Label(file_frame, text="未选择文件", relief=tk.SUNKEN,
anchor=tk.W, padx=5, pady=2, bg="white")
self.path_label.pack(fill=tk.X, pady=5)
browse_btn = tk.Button(file_frame, text="浏览文件", command=self.select_file)
browse_btn.pack(pady=5)
# 尺寸设置区域
size_frame = tk.Frame(self.root)
size_frame.pack(pady=10, fill=tk.X, padx=20)
tk.Label(size_frame, text="条形码尺寸:").pack(anchor=tk.W)
size_subframe = tk.Frame(size_frame)
size_subframe.pack(fill=tk.X)
tk.Label(size_subframe, text="宽度:").grid(row=0, column=0, padx=(0, 5))
self.width_var = tk.StringVar(value="200")
width_entry = tk.Entry(size_subframe, textvariable=self.width_var, width=8)
width_entry.grid(row=0, column=1, padx=(0, 10))
tk.Label(size_subframe, text="高度:").grid(row=0, column=2, padx=(0, 5))
self.height_var = tk.StringVar(value="40")
height_entry = tk.Entry(size_subframe, textvariable=self.height_var, width=8)
height_entry.grid(row=0, column=3)
# 控制按钮区域
btn_frame = tk.Frame(self.root)
btn_frame.pack(pady=10)
self.start_btn = tk.Button(btn_frame, text="开始生成",
command=self.start_generation, width=15)
self.start_btn.pack(side=tk.LEFT, padx=5)
self.stop_btn = tk.Button(btn_frame, text="停止",
command=self.stop_generation, width=15, state=tk.DISABLED)
self.stop_btn.pack(side=tk.LEFT, padx=5)
# 条形码显示区域
img_frame = tk.Frame(self.root, relief=tk.SUNKEN, borderwidth=1)
img_frame.pack(pady=15, padx=20, fill=tk.BOTH, expand=True)
self.barcode_label = tk.Label(img_frame, text="条形码将显示在这里",
bg="white", height=10)
self.barcode_label.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
# 状态显示区域
self.status_var = tk.StringVar(value="就绪")
status_label = tk.Label(self.root, textvariable=self.status_var,
relief=tk.SUNKEN, anchor=tk.W, padx=10)
status_label.pack(side=tk.BOTTOM, fill=tk.X)
def select_file(self):
self.file_path = filedialog.askopenfilename(
title="选择文本文件",
filetypes=(("文本文件", "*.txt"), ("所有文件", "*.*"))
)
if self.file_path:
self.path_label.config(text=f"已选择: {os.path.basename(self.file_path)}")
self.start_btn.config(state=tk.NORMAL)
def start_generation(self):
if not self.file_path:
messagebox.showerror("错误", "请先选择文本文件")
return
# 读取文件内容
try:
with open(self.file_path, 'r', encoding='utf-8') as file:
self.lines = [line.strip() for line in file.readlines() if line.strip()]
if not self.lines:
messagebox.showerror("错误", "文件内容为空")
return
except Exception as e:
messagebox.showerror("错误", f"读取文件失败: {str(e)}")
return
# 获取尺寸设置
try:
width = int(self.width_var.get())
height = int(self.height_var.get())
if width <= 0 or height <= 0:
raise ValueError("尺寸必须大于0")
except ValueError:
messagebox.showerror("错误", "请输入有效的尺寸(正整数)")
return
self.is_running = True
self.current_line = 0
self.start_btn.config(state=tk.DISABLED)
self.stop_btn.config(state=tk.NORMAL)
self.status_var.set("开始生成...")
# 在新线程中运行条形码生成
threading.Thread(target=self.generate_barcode_loop, args=(width, height), daemon=True).start()
def stop_generation(self):
self.is_running = False
self.start_btn.config(state=tk.NORMAL)
self.stop_btn.config(state=tk.DISABLED)
self.status_var.set("已停止")
def generate_barcode_loop(self, width, height):
total_lines = len(self.lines)
while self.is_running and self.current_line < total_lines:
content = self.lines[self.current_line]
self.status_var.set(f"生成条形码: {content} ({self.current_line+1}/{total_lines})")
try:
self.generate_barcode(content, width, height)
except Exception as e:
self.status_var.set(f"生成错误: {str(e)}")
self.current_line += 1
time.sleep(3) # 3秒间隔
if self.current_line >= total_lines:
self.status_var.set("已完成所有内容")
self.stop_generation()
def generate_barcode(self, content, width, height):
# 创建Code128条形码
code128 = barcode.get_barcode_class('code128')
barcode_img = code128(content, writer=ImageWriter())
# 设置条形码选项
options = {
'module_width': 0.2, # 单个条/空的宽度
'module_height': height / 10, # 条的高度(根据所需高度调整)
'font_size': 0, # 不显示文本
'quiet_zone': 1.0, # 空白区大小
'background': 'white',
'foreground': 'black'
}
# 生成条形码图像
filename = barcode_img.save("temp_barcode", options)
# 打开图像并调整尺寸
img = Image.open(filename)
# 计算缩放比例以保持宽高比
original_width, original_height = img.size
ratio = min(width / original_width, height / original_height)
new_width = int(original_width * ratio)
new_height = int(original_height * ratio)
# 调整尺寸并创建新图像
resized_img = img.resize((new_width, new_height), Image.LANCZOS)
final_img = Image.new('RGB', (width, height), 'white')
final_img.paste(resized_img, ((width - new_width) // 2, (height - new_height) // 2))
# 转换为Tkinter格式并显示
tk_image = ImageTk.PhotoImage(final_img)
self.barcode_label.config(image=tk_image)
self.barcode_label.image = tk_image # 保持引用
# 删除临时文件
os.remove(filename)
if __name__ == "__main__":
root = tk.Tk()
app = BarcodeGeneratorApp(root)
root.mainloop()
最新发布