diff --git a/python/Bag2.py b/python/Bag2.py index bad12c6..8ddc79a 100644 --- a/python/Bag2.py +++ b/python/Bag2.py @@ -414,6 +414,62 @@ def send_image_to_label_printer(printer_name: str, pil_image: "Image.Image") -> pass +def run_dataflex_continuous_print( + root: tk.Tk, + ip: str, + port: int, + zpl: str, + label_text: str, + set_status_message: Callable[[str, bool], None], +) -> None: + """ + Run DataFlex continuous print (up to 100) in a background thread. + Shows a small window with "已列印: N" and a 停止 button; user can stop anytime. + """ + stop_event = threading.Event() + win = tk.Toplevel(root) + win.title("打袋機 連續列印") + win.geometry("320x140") + win.transient(root) + win.configure(bg=BG_TOP) + tk.Label(win, text="連續列印中,按「停止」結束", font=get_font(FONT_SIZE), bg=BG_TOP).pack(pady=(12, 4)) + count_lbl = tk.Label(win, text="已列印: 0", font=get_font(FONT_SIZE), bg=BG_TOP) + count_lbl.pack(pady=4) + + def on_stop(): + stop_event.set() + + ttk.Button(win, text="停止", command=on_stop, width=12).pack(pady=8) + win.protocol("WM_DELETE_WINDOW", lambda: (stop_event.set(), win.destroy())) + + def worker(): + sent = 0 + try: + for _ in range(100): + if stop_event.is_set(): + break + send_zpl_to_dataflex(ip, port, zpl) + sent += 1 + root.after(0, lambda s=sent: count_lbl.configure(text=f"已列印: {s}")) + if stop_event.is_set(): + break + time.sleep(2) + except ConnectionRefusedError: + root.after(0, lambda: set_status_message(f"無法連線至 {ip}:{port},請確認印表機已開機且 IP 正確。", is_error=True)) + except socket.timeout: + root.after(0, lambda: set_status_message(f"連線逾時 ({ip}:{port}),請檢查網路與連接埠。", is_error=True)) + except OSError as err: + root.after(0, lambda e=err: set_status_message(f"列印失敗:{e}", is_error=True)) + else: + if stop_event.is_set(): + root.after(0, lambda: set_status_message(f"已送出列印:批次 {label_text} x {sent} 張 (已停止)", is_error=False)) + else: + root.after(0, lambda: set_status_message(f"已送出列印:批次 {label_text} x {sent} 張 (連續完成)", is_error=False)) + root.after(0, win.destroy) + + threading.Thread(target=worker, daemon=True).start() + + def send_zpl_to_dataflex(ip: str, port: int, zpl: str) -> None: """Send ZPL to DataFlex printer via TCP. Raises on connection/send error.""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -1246,21 +1302,23 @@ def main() -> None: stock_in_line_id=stock_in_line_id, lot_no=lot_no, ) - n = 100 if count == -1 else count label_text = (lot_no or b).strip() - try: - for i in range(n): - send_zpl_to_dataflex(ip, port, zpl) - if i < n - 1: - time.sleep(2) - msg = f"已送出列印:批次 {label_text} x {n} 張" if count != -1 else f"已送出列印:批次 {label_text} x {n} 張 (連續)" - set_status_message(msg, is_error=False) - except ConnectionRefusedError: - set_status_message(f"無法連線至 {ip}:{port},請確認印表機已開機且 IP 正確。", is_error=True) - except socket.timeout: - set_status_message(f"連線逾時 ({ip}:{port}),請檢查網路與連接埠。", is_error=True) - except OSError as err: - set_status_message(f"列印失敗:{err}", is_error=True) + if count == -1: + run_dataflex_continuous_print(root, ip, port, zpl, label_text, set_status_message) + else: + n = count + try: + for i in range(n): + send_zpl_to_dataflex(ip, port, zpl) + if i < n - 1: + time.sleep(2) + set_status_message(f"已送出列印:批次 {label_text} x {n} 張", is_error=False) + except ConnectionRefusedError: + set_status_message(f"無法連線至 {ip}:{port},請確認印表機已開機且 IP 正確。", is_error=True) + except socket.timeout: + set_status_message(f"連線逾時 ({ip}:{port}),請檢查網路與連接埠。", is_error=True) + except OSError as err: + set_status_message(f"列印失敗:{err}", is_error=True) elif printer_var.get() == "標簽機": com = (settings.get("label_com") or "").strip() if not com: