| @@ -414,6 +414,62 @@ def send_image_to_label_printer(printer_name: str, pil_image: "Image.Image") -> | |||||
| pass | 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: | def send_zpl_to_dataflex(ip: str, port: int, zpl: str) -> None: | ||||
| """Send ZPL to DataFlex printer via TCP. Raises on connection/send error.""" | """Send ZPL to DataFlex printer via TCP. Raises on connection/send error.""" | ||||
| sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||
| @@ -1246,21 +1302,23 @@ def main() -> None: | |||||
| stock_in_line_id=stock_in_line_id, | stock_in_line_id=stock_in_line_id, | ||||
| lot_no=lot_no, | lot_no=lot_no, | ||||
| ) | ) | ||||
| n = 100 if count == -1 else count | |||||
| label_text = (lot_no or b).strip() | 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() == "標簽機": | elif printer_var.get() == "標簽機": | ||||
| com = (settings.get("label_com") or "").strip() | com = (settings.get("label_com") or "").strip() | ||||
| if not com: | if not com: | ||||