Complete label printer redesign: file monitoring, SVG templates, sharp print quality
- Redesigned GUI for automatic file monitoring workflow - Changed label format to 35x25mm landscape - Implemented SVG template support with variable substitution - Added configuration auto-save/load (conf/app.conf) - Added system tray minimize functionality - Fixed print quality: landscape orientation, vector fonts, 600 DPI - Auto-clear file after print to prevent duplicates - All popups auto-dismiss after 2-3 seconds - Semicolon separator for data format (article;nr_art;serial) - SumatraPDF integration with noscale settings - Printer configured for outline fonts (sharp output) - Reorganized documentation into documentation/ folder
This commit is contained in:
121
print_label.py
121
print_label.py
@@ -200,16 +200,16 @@ def create_label_pdf(text):
|
||||
PDFs are saved to the pdf_backup folder.
|
||||
|
||||
Args:
|
||||
text (str): Combined text in format "SAP|CANTITATE|LOT" or single value
|
||||
text (str): Combined text in format "article;nr_art;serial" or single value
|
||||
|
||||
Returns:
|
||||
str: Path to the generated PDF file
|
||||
"""
|
||||
# Parse the text input
|
||||
parts = text.split('|') if '|' in text else [text, '', '']
|
||||
sap_nr = parts[0].strip() if len(parts) > 0 else ''
|
||||
cantitate = parts[1].strip() if len(parts) > 1 else ''
|
||||
lot_number = parts[2].strip() if len(parts) > 2 else ''
|
||||
# Parse the text input - using semicolon separator
|
||||
parts = text.split(';') if ';' in text else [text, '', '']
|
||||
article = parts[0].strip() if len(parts) > 0 else ''
|
||||
nr_art = parts[1].strip() if len(parts) > 1 else ''
|
||||
serial = parts[2].strip() if len(parts) > 2 else ''
|
||||
|
||||
# Create PDF using high-quality generator
|
||||
generator = PDFLabelGenerator()
|
||||
@@ -221,7 +221,16 @@ def create_label_pdf(text):
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
pdf_filename = os.path.join(pdf_backup_dir, f"final_label_{timestamp}.pdf")
|
||||
|
||||
return generator.create_label_pdf(sap_nr, cantitate, lot_number, pdf_filename)
|
||||
# Check for default SVG template
|
||||
svg_template = None
|
||||
default_svg = os.path.join('conf', 'label_template.svg')
|
||||
if os.path.exists(default_svg):
|
||||
svg_template = default_svg
|
||||
|
||||
# Check for default image path
|
||||
image_path = os.path.join('conf', 'accepted.png')
|
||||
|
||||
return generator.create_label_pdf(article, nr_art, serial, pdf_filename, image_path, svg_template)
|
||||
|
||||
|
||||
def print_to_printer(printer_name, file_path):
|
||||
@@ -249,58 +258,68 @@ def print_to_printer(printer_name, file_path):
|
||||
return True
|
||||
|
||||
elif SYSTEM == "Windows":
|
||||
# Windows: Print directly without opening PDF viewer
|
||||
# Windows: Print PDF using various methods
|
||||
try:
|
||||
if WIN32_AVAILABLE:
|
||||
import win32print
|
||||
import win32api
|
||||
if file_path.endswith('.pdf'):
|
||||
# Method 1: Try SumatraPDF for best silent printing
|
||||
sumatra_paths = [
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf', 'SumatraPDF.exe'),
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf', 'SumatraPDF-portable.exe'),
|
||||
r"C:\Program Files\SumatraPDF\SumatraPDF.exe",
|
||||
r"C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe",
|
||||
os.path.expandvars(r"%LOCALAPPDATA%\SumatraPDF\SumatraPDF.exe"),
|
||||
]
|
||||
|
||||
if file_path.endswith('.pdf'):
|
||||
# Use SumatraPDF command-line or direct raw printing
|
||||
# Try printing via subprocess to avoid opening a PDF viewer window
|
||||
|
||||
# Method: Use win32print raw API to send to printer silently
|
||||
sumatra_found = False
|
||||
for sumatra_path in sumatra_paths:
|
||||
if os.path.exists(sumatra_path):
|
||||
sumatra_found = True
|
||||
try:
|
||||
# Use SumatraPDF silent printing with high quality settings
|
||||
# noscale = print at actual size without scaling
|
||||
# landscape = force landscape orientation for 35x25mm labels
|
||||
# Note: SumatraPDF uses printer driver's quality settings
|
||||
subprocess.run([
|
||||
sumatra_path,
|
||||
'-print-to', printer_name,
|
||||
'-silent',
|
||||
'-print-settings', 'noscale,landscape',
|
||||
file_path
|
||||
], check=True, creationflags=subprocess.CREATE_NO_WINDOW)
|
||||
print(f"Label sent to printer via SumatraPDF: {printer_name}")
|
||||
return True
|
||||
except Exception as sumatra_err:
|
||||
print(f"SumatraPDF print failed: {sumatra_err}")
|
||||
break
|
||||
|
||||
# Method 2: Use ShellExecute with printto (requires default PDF viewer)
|
||||
if not sumatra_found or WIN32_AVAILABLE:
|
||||
try:
|
||||
hprinter = win32print.OpenPrinter(printer_name)
|
||||
try:
|
||||
# Start a print job
|
||||
job_info = ("Label Print", None, "RAW")
|
||||
hjob = win32print.StartDocPrinter(hprinter, 1, job_info)
|
||||
win32print.StartPagePrinter(hprinter)
|
||||
|
||||
# Read PDF file and send to printer
|
||||
with open(file_path, 'rb') as f:
|
||||
pdf_data = f.read()
|
||||
win32print.WritePrinter(hprinter, pdf_data)
|
||||
|
||||
win32print.EndPagePrinter(hprinter)
|
||||
win32print.EndDocPrinter(hprinter)
|
||||
print(f"Label sent to printer: {printer_name}")
|
||||
finally:
|
||||
win32print.ClosePrinter(hprinter)
|
||||
import win32api
|
||||
win32api.ShellExecute(
|
||||
0, "printto", file_path,
|
||||
f'"{printer_name}"', ".", 0
|
||||
)
|
||||
print(f"Label sent to printer via ShellExecute: {printer_name}")
|
||||
return True
|
||||
except Exception as raw_err:
|
||||
print(f"Raw print failed ({raw_err}), trying ShellExecute silently...")
|
||||
# Fallback: Use ShellExecute with printto (minimized, auto-closes)
|
||||
except Exception as shell_err:
|
||||
print(f"ShellExecute print failed: {shell_err}")
|
||||
# Method 3: Open PDF with default viewer (last resort)
|
||||
try:
|
||||
win32api.ShellExecute(
|
||||
0, "printto", file_path,
|
||||
f'"{printer_name}"', ".", 0
|
||||
)
|
||||
print(f"Label sent to printer: {printer_name}")
|
||||
os.startfile(file_path, "print")
|
||||
print(f"Opened PDF for printing: {file_path}")
|
||||
print("Please close the PDF viewer after printing.")
|
||||
return True
|
||||
except Exception as shell_err:
|
||||
print(f"ShellExecute print failed: {shell_err}")
|
||||
except Exception as startfile_err:
|
||||
print(f"Could not open PDF: {startfile_err}")
|
||||
print("PDF saved as backup only")
|
||||
return True
|
||||
else:
|
||||
# Non-PDF files: print silently with notepad
|
||||
subprocess.run(['notepad', '/p', file_path],
|
||||
check=False,
|
||||
creationflags=subprocess.CREATE_NO_WINDOW)
|
||||
print(f"Label sent to printer: {printer_name}")
|
||||
return True
|
||||
else:
|
||||
print("win32print not available, PDF saved as backup only")
|
||||
# Non-PDF files: print silently with notepad
|
||||
subprocess.run(['notepad', '/p', file_path],
|
||||
check=False,
|
||||
creationflags=subprocess.CREATE_NO_WINDOW)
|
||||
print(f"Label sent to printer: {printer_name}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Windows print error: {e}")
|
||||
|
||||
Reference in New Issue
Block a user