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:
NAME
2026-02-12 22:25:51 +02:00
parent 0743c44051
commit 8954135f93
51 changed files with 1209 additions and 6396 deletions

2
.gitignore vendored
View File

@@ -2,3 +2,5 @@ label/
build/
logs/
pdf_backup/
venv/

View File

@@ -1,178 +0,0 @@
# Building LabelPrinter.exe on Windows
This guide explains how to build a standalone `LabelPrinter.exe` single-file executable on a Windows machine.
## Prerequisites
1. **Python 3.10, 3.11, 3.12, or 3.13** - Download from https://www.python.org/
- ⚠️ **IMPORTANT**: Check "Add Python to PATH" during installation
- ⚠️ **Note**: Python 3.14+ may have compatibility issues with Kivy 2.2.1
- Verify: Open Command Prompt and type `python --version`
2. **Git** (optional, for cloning the repository)
3. **Internet connection** - To download dependencies
## Quick Start (Using Provided Scripts)
### Option 1: Batch Script (Recommended for CMD users)
1. Open **Command Prompt** (cmd.exe)
2. Navigate to the project folder:
```
cd C:\path\to\label_print
```
3. Run the build script:
```
build_windows.bat
```
4. Wait 5-15 minutes for the build to complete
5. The executable will be in: `dist\LabelPrinter.exe`
### Option 2: PowerShell Script
1. Open **PowerShell** (as Administrator recommended)
2. Navigate to the project folder:
```
cd C:\path\to\label_print
```
3. Allow script execution (if needed):
```
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
4. Run the build script:
```
.\build_windows.ps1
```
5. Wait 5-15 minutes for the build to complete
6. The executable will be in: `dist\LabelPrinter.exe`
## Manual Build Steps
If you prefer to run commands manually:
### Step 1: Prepare Python Environment
```bash
# Upgrade pip, setuptools, and wheel
python -m pip install --upgrade pip setuptools wheel
```
### Step 2: Install Dependencies
```bash
# Install required Python packages
pip install python-barcode pillow reportlab kivy==2.2.1 pyinstaller==6.1.0
```
### Step 3: Build the Executable
```bash
# Create single-file executable
pyinstaller label_printer_gui.py ^
--onefile ^
--windowed ^
--name=LabelPrinter ^
--distpath=./dist ^
--workpath=./build ^
--hidden-import=kivy ^
--hidden-import=PIL ^
--hidden-import=barcode ^
--hidden-import=reportlab ^
--hidden-import=print_label ^
--hidden-import=print_label_pdf ^
-y
```
The build process will take 5-15 minutes depending on your PC speed.
### Step 4: Test the Executable
```bash
# Run the built executable
dist\LabelPrinter.exe
```
## Output
After successful build, you'll have:
```
dist/
└── LabelPrinter.exe ← Single executable file
```
## Distributing the Executable
You can:
1. **Copy `LabelPrinter.exe`** to any Windows PC (no Python needed!)
2. **Share via USB** or file transfer
3. **Create an installer** using NSIS or InnoSetup (optional)
4. **Upload to GitHub Releases** for public distribution
## Troubleshooting
### Error: "Python is not recognized"
- Reinstall Python and check "Add Python to PATH"
- Restart Command Prompt after reinstalling Python
### Error: "pip command not found"
- Use `python -m pip` instead of `pip`
### Build takes too long (>30 minutes)
- **Normal for first build** - Kivy framework is large
- Subsequent builds will be faster due to caching
- Close other applications to free up RAM
### Error: "No module named 'kivy'"
- Make sure dependencies installed correctly: `pip install kivy==2.2.1`
- Check internet connection
### Python 3.14 Compatibility Issues
If you have Python 3.14 installed and get errors like:
- `ModuleNotFoundError: No module named 'kivy'`
- `ImportError: DLL load failed`
- PyInstaller compatibility errors
**Solution:**
- Install Python 3.11, 3.12, or 3.13 instead
- Download from: https://www.python.org/downloads/
- Uninstall Python 3.14 first
- Then use one of the recommended versions
- Make sure all files are in the project folder:
- `label_printer_gui.py`
- `print_label.py`
- `print_label_pdf.py`
- Antivirus might be blocking it - check security software
## Build Time Reference
- **First build**: 10-15 minutes (downloading dependencies)
- **Subsequent builds**: 5-10 minutes (cached dependencies)
## Advanced Options
### Reduce Build Time
```bash
pyinstaller label_printer_gui.py --onefile --windowed --name=LabelPrinter -y
```
### Add Icon to Executable
```bash
pyinstaller label_printer_gui.py --onefile --windowed --name=LabelPrinter --icon=path\to\icon.ico -y
```
### Faster: Use --onedir (Directory) instead of --onefile
```bash
pyinstaller label_printer_gui.py --onedir --windowed --name=LabelPrinter -y
# Builds in ~3-5 minutes, but creates a folder instead of single file
```
## Support
If you encounter issues:
1. Check the error message carefully
2. Make sure Python 3.10+ is installed
3. Verify all dependencies: `pip list`
4. Check internet connection
5. Try again with a fresh Command Prompt window

View File

@@ -1,227 +0,0 @@
# Building a Standalone EXE with PyInstaller
This guide explains how to create a standalone Windows executable (`.exe`) file that doesn't require Python to be installed.
## Quick Start (Windows)
### Prerequisites
- Python 3.11+ installed
- Virtual environment activated
- All dependencies installed
### One-Command Build
```bash
# Activate virtual environment
venv\Scripts\activate
# Build the executable
python build_exe.py
```
That's it! Your executable will be in `dist/LabelPrinter.exe`
---
## What Happens During Build
1. **Analyzes your code** - Finds all imported modules
2. **Collects dependencies** - Bundles Kivy, PIL, barcode, reportlab, etc.
3. **Creates executable** - Packages everything into one `.exe` file
4. **Output**: `dist/LabelPrinter.exe` (~150-200 MB)
---
## Detailed Build Instructions
### Step 1: Install PyInstaller
```bash
venv\Scripts\activate
pip install pyinstaller
```
### Step 2: Build Using Script
```bash
python build_exe.py
```
### Step 3: Alternative Manual Build
If the script doesn't work, use this command directly:
```bash
pyinstaller ^
--onefile ^
--windowed ^
--name=LabelPrinter ^
--hidden-import=kivy ^
--hidden-import=kivy.core.window ^
--hidden-import=kivy.core.text ^
--hidden-import=kivy.core.image ^
--hidden-import=kivy.uix.boxlayout ^
--hidden-import=kivy.uix.gridlayout ^
--hidden-import=kivy.uix.label ^
--hidden-import=kivy.uix.textinput ^
--hidden-import=kivy.uix.button ^
--hidden-import=kivy.uix.spinner ^
--hidden-import=kivy.uix.scrollview ^
--hidden-import=kivy.uix.popup ^
--hidden-import=kivy.clock ^
--hidden-import=kivy.graphics ^
--hidden-import=PIL ^
--hidden-import=barcode ^
--hidden-import=reportlab ^
--hidden-import=print_label ^
--hidden-import=print_label_pdf ^
--collect-all=kivy ^
--collect-all=PIL ^
label_printer_gui.py
```
---
## Output Files
After building, you'll have:
```
Label-design/
├── dist/
│ └── LabelPrinter.exe ← Your standalone executable (150-200 MB)
├── build/ ← Temporary build files (can delete)
└── label_printer.spec ← PyInstaller spec file
```
---
## Running the Executable
### On Your Computer
1. Double-click `dist/LabelPrinter.exe`
2. App starts immediately (first run takes ~5 seconds)
3. Works like the Python version
### Sharing with Others
1. Copy `dist/LabelPrinter.exe` to a folder
2. Create a shortcut to it on the desktop
3. Share the folder or executable
4. **No Python installation needed on their computer!**
### Creating a Shortcut
1. Right-click `LabelPrinter.exe`
2. Send to → Desktop (create shortcut)
3. Double-click the shortcut to run
---
## Troubleshooting
### "Failed to build the executable"
**Solution 1**: Check Python version
```bash
python --version # Should be 3.11+
```
**Solution 2**: Update PyInstaller
```bash
pip install --upgrade pyinstaller
```
**Solution 3**: Install missing dependencies
```bash
pip install -r requirements_windows.txt
pip install pyinstaller
```
### "DLL load failed" when running exe
This usually means a library isn't bundled correctly.
**Solution**: Rebuild with verbose output
```bash
pyinstaller --debug=imports label_printer_gui.py
```
### Executable is very large (200+ MB)
This is normal for Kivy applications. The size includes:
- Python runtime (~50 MB)
- Kivy framework (~30 MB)
- Dependencies (PIL, barcode, reportlab, etc.) (~20 MB)
- Your code (~1 KB)
You can reduce size slightly with:
```bash
--exclude-module=matplotlib
--exclude-module=numpy
--exclude-module=scipy
```
### Slow to start (5-10 seconds)
Normal for Kivy apps. The first startup initializes:
- Python runtime
- Kivy graphics system
- Font rendering
- Window initialization
Subsequent runs are faster (~3 seconds).
---
## Advanced Options
### Add an Icon
1. Create a 256x256 PNG icon: `app_icon.png`
2. Convert to ICO: Use an online tool or ImageMagick
3. Build with icon:
```bash
pyinstaller --icon=app_icon.ico label_printer_gui.py
```
### Two-File Distribution
Instead of `--onefile`, use separate files for faster startup:
```bash
pyinstaller label_printer_gui.py
```
Creates `dist/` folder with all files (faster to run, easier to debug).
### Console Output
To see error messages, remove `--windowed`:
```bash
pyinstaller --onefile --name=LabelPrinter label_printer_gui.py
```
---
## Build Options Reference
| Option | Purpose |
|--------|---------|
| `--onefile` | Single executable (recommended) |
| `--windowed` | No console window |
| `--icon=file.ico` | Custom icon |
| `--hidden-import=module` | Include module that's not imported directly |
| `--collect-all=module` | Include all module data |
| `--distpath=folder` | Output directory |
| `--name=AppName` | Executable name |
---
## Final Steps
1. **Test the executable**: Run `LabelPrinter.exe` and test all features
2. **Verify PDF backup**: Check `pdf_backup/` folder is created
3. **Test printing**: Print a label to ensure PDF output works
4. **Share**: Distribute the `.exe` file to users
---
## Questions?
- Check the error message in the console
- Try rebuilding with `python build_exe.py`
- Ensure all dependencies are installed: `pip install -r requirements_windows.txt`
- Check that Python 3.11+ is installed: `python --version`
Good luck! 🚀

234
README.md
View File

@@ -1,234 +0,0 @@
# Label Printer GUI
A cross-platform barcode label printing application with a modern GUI. Create, generate, and print labels with automatic Code128 barcode encoding.
## Features
**Core Features**
- 🎨 Beautiful Kivy GUI interface
- 📊 Automatic Code128 barcode generation
- 📄 High-quality PDF label generation
- 💾 Automatic PDF backup system
- ✅ Input validation with 25-character limit
- 🔢 Number-only filter for quantity field
🖨️ **Printer Support**
- Windows printer detection and printing
- Linux CUPS printer support
- macOS printing support
- PDF fallback (works everywhere)
🚀 **Distribution**
- PyInstaller support for standalone Windows .exe
- No Python installation needed
- Cross-platform source code (Windows, Linux, macOS)
## Quick Start
### Option 1: Python Source (Recommended for Development)
```bash
# 1. Clone/Download the project
cd Label-design
# 2. Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements_gui.txt
# 4. Run the app
python label_printer_gui.py
```
### Option 2: Windows Standalone Executable
1. Download `LabelPrinter.exe` from releases
2. Double-click to run (no Python needed!)
3. First run takes ~5 seconds to initialize
## Building Your Own Executable
### Windows Build Steps
```bash
# 1. Activate virtual environment
venv\Scripts\activate
# 2. Install PyInstaller
pip install pyinstaller
# 3. Build executable
python build_exe.py
```
Your executable will be in `dist/LabelPrinter.exe` (~200 MB)
### Manual Build Command
```bash
pyinstaller --onefile --windowed --name=LabelPrinter ^
--hidden-import=kivy ^
--hidden-import=kivy.core.window ^
--hidden-import=kivy.core.text ^
--hidden-import=kivy.core.image ^
--hidden-import=kivy.uix.boxlayout ^
--hidden-import=kivy.uix.gridlayout ^
--hidden-import=kivy.uix.label ^
--hidden-import=kivy.uix.textinput ^
--hidden-import=kivy.uix.button ^
--hidden-import=kivy.uix.spinner ^
--hidden-import=kivy.uix.scrollview ^
--hidden-import=kivy.uix.popup ^
--hidden-import=kivy.clock ^
--hidden-import=kivy.graphics ^
--hidden-import=PIL ^
--hidden-import=barcode ^
--hidden-import=reportlab ^
--hidden-import=print_label ^
--hidden-import=print_label_pdf ^
label_printer_gui.py
```
## File Structure
```
Label-design/
├── label_printer_gui.py # Main GUI application
├── print_label.py # Printing functionality
├── print_label_pdf.py # PDF generation
├── build_exe.py # PyInstaller build script
├── requirements_gui.txt # GUI dependencies
├── pdf_backup/ # Generated label PDFs
├── dist/ # Built executables
├── documentation/ # Docs and guides
│ ├── WINDOWS_SETUP.md
│ ├── PYINSTALLER_GUIDE.md
│ └── [other docs]
└── venv/ # Python virtual environment
```
## Dependencies
**Required (Core):**
- `python-barcode` - Barcode generation
- `pillow` - Image processing
- `reportlab` - PDF generation
**GUI:**
- `kivy` - Cross-platform GUI framework
**Optional (Printing):**
- `pycups` - Linux CUPS support
- `pywin32` - Windows printer support
## Usage
### Basic Workflow
1. **Enter Data:**
- **SAP-Nr**: Article code (up to 25 chars)
- **Cantitate**: Quantity (numbers only)
- **ID rola**: Reel/Cable ID (up to 25 chars)
2. **Select Printer:**
- Choose from detected printers
- Or select "PDF" for PDF output
3. **Print:**
- Click "PRINT LABEL"
- PDF is auto-saved to `pdf_backup/` folder
- Label sent to printer
### PDF Backup
All generated labels are automatically saved with timestamps:
```
pdf_backup/
├── final_label_20260205_120530.pdf
├── final_label_20260205_120542.pdf
└── final_label_20260205_120555.pdf
```
## Guides
- **[WINDOWS_SETUP.md](documentation/WINDOWS_SETUP.md)** - Windows installation guide
- **[PYINSTALLER_GUIDE.md](documentation/PYINSTALLER_GUIDE.md)** - Building executables
- **[documentation/](documentation/)** - All documentation
## Troubleshooting
### "No Printers Found"
This is normal. Select "PDF" option - labels will be saved to `pdf_backup/` folder.
### "GUI Won't Start"
Ensure all dependencies are installed:
```bash
pip install -r requirements_gui.txt
```
### Windows Executable Issues
- Update PyInstaller: `pip install --upgrade pyinstaller`
- Rebuild: `python build_exe.py`
- Check dependencies: `pip list`
### Kivy Graphics Issues
On Linux, you may need SDL2 dependencies:
```bash
sudo apt-get install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev
```
## Platform Support
| Platform | Source | Executable | Status |
|----------|--------|-----------|--------|
| Windows | ✅ Yes | ✅ Yes | ✅ Fully Supported |
| Linux | ✅ Yes | ❌ No | ✅ Fully Supported |
| macOS | ✅ Yes | ⚠️ Possible | ⚠️ Untested |
## Technical Details
### Barcode Format
- **Type**: Code128
- **Max Length**: 25 characters
- **DPI**: 300 (print quality)
### PDF Specifications
- **Page Size**: 11.5 x 8 cm (landscape)
- **Quality**: High-resolution barcodes
- **Font**: Helvetica with automatic sizing
### GUI Specifications
- **Framework**: Kivy 2.3+
- **Size**: 420 x 700 pixels (mobile-optimized)
- **Color**: White text on dark background
## Contributing
Feel free to fork, modify, and improve!
Suggested improvements:
- [ ] Custom barcode formats (QR, Code39, etc.)
- [ ] Batch label printing
- [ ] Label preview before printing
- [ ] Printer-specific settings
- [ ] Multi-language support
- [ ] Database integration
## License
Open source - modify and use freely
## Support
For issues, questions, or suggestions:
1. Check the documentation in `documentation/` folder
2. Review the code comments
3. Test with the source code first before building exe
---
**Status**: Production Ready ✅
Last Updated: February 2026

View File

@@ -1,99 +0,0 @@
# Label Printer - Windows Build Script (Single File EXE)
# This script builds a standalone LabelPrinter.exe on Windows
# Requirements: Python 3.10-3.13 installed and in PATH
# Note: Python 3.14+ may have compatibility issues
Write-Host ""
Write-Host "========================================================"
Write-Host " Label Printer - Windows Build Script"
Write-Host " Creates: LabelPrinter.exe (Single File)"
Write-Host "========================================================"
Write-Host ""
# Check if Python is installed
try {
$pythonVersion = python --version 2>&1
if ($LASTEXITCODE -ne 0) {
throw "Python not found"
}
} catch {
Write-Host "ERROR: Python is not installed or not in PATH" -ForegroundColor Red
Write-Host "Please install Python 3.10-3.13 from https://www.python.org/"
Write-Host "Make sure to check 'Add Python to PATH' during installation"
Read-Host "Press Enter to exit"
exit 1
}
Write-Host "[1/5] Checking Python installation..." -ForegroundColor Cyan
Write-Host $pythonVersion
Write-Host ""
Write-Host "[2/5] Upgrading pip, setuptools, and wheel..." -ForegroundColor Cyan
python -m pip install --upgrade pip setuptools wheel
if ($LASTEXITCODE -ne 0) {
Write-Host "ERROR: Failed to upgrade pip" -ForegroundColor Red
Read-Host "Press Enter to exit"
exit 1
}
Write-Host ""
Write-Host "[3/5] Installing dependencies..." -ForegroundColor Cyan
Write-Host "Installing: python-barcode, pillow, reportlab, kivy, pyinstaller, pywin32, wmi..."
pip install python-barcode pillow reportlab kivy pyinstaller pywin32 wmi
if ($LASTEXITCODE -ne 0) {
Write-Host "ERROR: Failed to install dependencies" -ForegroundColor Red
Read-Host "Press Enter to exit"
exit 1
}
Write-Host ""
Write-Host "[4/5] Cleaning old build artifacts..." -ForegroundColor Cyan
if (Test-Path "dist") { Remove-Item -Recurse -Force "dist" }
if (Test-Path "build") { Remove-Item -Recurse -Force "build" }
Remove-Item -Force "*.spec" -ErrorAction SilentlyContinue
Write-Host ""
Write-Host "[5/5] Building executable with PyInstaller..." -ForegroundColor Cyan
Write-Host "This may take 5-15 minutes, please wait..."
Write-Host ""
$pyinstallerArgs = @(
"label_printer_gui.py",
"--onefile",
"--windowed",
"--name=LabelPrinter",
"--distpath=./dist",
"--workpath=./build",
"--hidden-import=kivy",
"--hidden-import=PIL",
"--hidden-import=barcode",
"--hidden-import=reportlab",
"--hidden-import=print_label",
"--hidden-import=print_label_pdf",
"-y"
)
pyinstaller @pyinstallerArgs
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host "ERROR: Build failed!" -ForegroundColor Red
Write-Host "Please check the error messages above." -ForegroundColor Red
Read-Host "Press Enter to exit"
exit 1
}
Write-Host ""
Write-Host "========================================================"
Write-Host " BUILD SUCCESSFUL!" -ForegroundColor Green
Write-Host "========================================================"
Write-Host ""
Write-Host "Executable Location: dist\LabelPrinter.exe" -ForegroundColor Green
Write-Host ""
Write-Host "Next steps:"
Write-Host " 1. Navigate to the dist folder"
Write-Host " 2. Double-click LabelPrinter.exe to run"
Write-Host " 3. You can copy LabelPrinter.exe to other machines"
Write-Host ""
Write-Host "Note: First run may take a moment as Kivy initializes"
Write-Host ""
Read-Host "Press Enter to exit"

67
check_printer_quality.ps1 Normal file
View File

@@ -0,0 +1,67 @@
# Check and configure printer quality settings for Labels printer
$printerName = "Labels"
Write-Host "=== Checking Printer: $printerName ===" -ForegroundColor Cyan
Write-Host ""
# Get printer object
$printer = Get-Printer -Name $printerName -ErrorAction SilentlyContinue
if ($null -eq $printer) {
Write-Host "ERROR: Printer '$printerName' not found!" -ForegroundColor Red
exit 1
}
Write-Host "Printer Name: $($printer.Name)" -ForegroundColor Green
Write-Host "Driver Name: $($printer.DriverName)" -ForegroundColor Green
Write-Host "Port Name: $($printer.PortName)" -ForegroundColor Green
Write-Host ""
# Get printer configuration
try {
$printerConfig = Get-PrintConfiguration -PrinterName $printerName
Write-Host "=== Current Print Configuration ===" -ForegroundColor Cyan
Write-Host "Print Quality: $($printerConfig.PrintQuality)"
Write-Host "Color Mode: $($printerConfig.Color)"
Write-Host "Duplex Mode: $($printerConfig.DuplexingMode)"
Write-Host ""
} catch {
Write-Host "Could not retrieve print configuration: $_" -ForegroundColor Yellow
}
# Get printer driver properties
Write-Host "=== Checking Printer Properties ===" -ForegroundColor Cyan
try {
$printerProperties = Get-PrinterProperty -PrinterName $printerName
foreach ($prop in $printerProperties) {
Write-Host "$($prop.PropertyName): $($prop.Value)"
}
} catch {
Write-Host "Could not retrieve printer properties: $_" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "=== Recommendations ===" -ForegroundColor Cyan
Write-Host "1. Open Windows Settings > Devices > Printers & scanners"
Write-Host "2. Click on 'Labels' printer"
Write-Host "3. Click 'Manage' > 'Printing preferences'"
Write-Host "4. Look for quality settings and set to:"
Write-Host " - Print Quality: Best/Highest/600 DPI or higher"
Write-Host " - Graphics Mode: Vector or High Quality"
Write-Host " - Dithering: None (for sharp text)"
Write-Host "5. Save settings and try printing again"
Write-Host ""
Write-Host "Would you like to try setting print quality to high? (Y/N)" -ForegroundColor Yellow
$response = Read-Host
if ($response -eq 'Y' -or $response -eq 'y') {
try {
# Try to set print quality to high
Set-PrintConfiguration -PrinterName $printerName -PrintQuality 4 # 4 = High quality
Write-Host "Print quality set to HIGH" -ForegroundColor Green
} catch {
Write-Host "Could not set print quality automatically: $_" -ForegroundColor Yellow
Write-Host "Please set manually through printer preferences" -ForegroundColor Yellow
}
}

View File

@@ -0,0 +1,94 @@
# For documentation, see https://www.sumatrapdfreader.org/settings/settings3-5-1.html
Theme = Light
FixedPageUI [
TextColor = #000000
BackgroundColor = #ffffff
SelectionColor = #f5fc0c
WindowMargin = 2 4 2 4
PageSpacing = 4 4
InvertColors = false
HideScrollbars = false
]
ComicBookUI [
WindowMargin = 0 0 0 0
PageSpacing = 4 4
CbxMangaMode = false
]
ChmUI [
UseFixedPageUI = false
]
SelectionHandlers [
]
ExternalViewers [
]
ZoomLevels = 8.33 12.5 18 25 33.33 50 66.67 75 100 125 150 200 300 400 600 800 1000 1200 1600 2000 2400 3200 4800 6400
ZoomIncrement = 0
PrinterDefaults [
PrintScale = noscale
]
ForwardSearch [
HighlightOffset = 0
HighlightWidth = 15
HighlightColor = #6581ff
HighlightPermanent = false
]
Annotations [
HighlightColor = #ffff00
UnderlineColor = #00ff00
SquigglyColor = #ff00ff
StrikeOutColor = #ff0000
FreeTextColor =
FreeTextSize = 12
FreeTextBorderWidth = 1
TextIconColor =
TextIconType =
DefaultAuthor =
]
RememberOpenedFiles = true
RememberStatePerDocument = true
RestoreSession = true
UiLanguage = en
EnableTeXEnhancements = false
DefaultDisplayMode = automatic
DefaultZoom = fit page
Shortcuts [
]
EscToExit = false
ReuseInstance = false
ReloadModifiedDocuments = true
MainWindowBackground = #80fff200
FullPathInTitle = false
ShowMenubar = true
ShowToolbar = true
ShowFavorites = false
ShowToc = true
NoHomeTab = false
TocDy = 0
SidebarDx = 0
ToolbarSize = 18
TabWidth = 300
TreeFontSize = 0
TreeFontWeightOffset = 0
TreeFontName = automatic
SmoothScroll = false
ShowStartPage = false
CheckForUpdates = true
WindowState = 1
WindowPos = 566 0 788 1020
UseTabs = true
UseSysColors = false
CustomScreenDPI = 0
FileStates [
]
SessionData [
]
TimeOfLastUpdateCheck = 0 0
OpenCountWeek = 788
# Settings below are not recognized by the current version

BIN
conf/SumatraPDF.exe Normal file

Binary file not shown.

BIN
conf/accepted.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

4
conf/app.conf Normal file
View File

@@ -0,0 +1,4 @@
[Settings]
file_path = C:\Users\Public\Documents\check.txt
printer = Labels

63
conf/label_template.svg Normal file
View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="35mm" height="25mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 35 25"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
<defs>
<font id="FontID0" horiz-adv-x="722" font-variant="normal" style="fill-rule:nonzero" font-style="normal" font-weight="700">
<font-face
font-family="Arial">
<font-face-src>
<font-face-name name="Arial Bold"/>
</font-face-src>
</font-face>
<missing-glyph><path d="M0 0z"/></missing-glyph>
<glyph unicode="." horiz-adv-x="277" d="M71.0096 0l0 136.998 136.998 0 0 -136.998 -136.998 0z"/>
<glyph unicode=":" horiz-adv-x="332" d="M98.0096 381.997l0 136.998 136.998 0 0 -136.998 -136.998 0zm0 -381.997l0 136.998 136.998 0 0 -136.998 -136.998 0z"/>
<glyph unicode="A" horiz-adv-x="722" d="M718.011 0l-156.185 0 -61.8388 162.999 -287.163 0 -59.482 -162.999 -153.342 0 277.993 715.987 153.162 0 286.856 -715.987zm-265.005 284.013l-99.4954 264.979 -96.6775 -264.979 196.173 0z"/>
<glyph unicode="C" horiz-adv-x="722" d="M531.009 264.006l139.995 -43.0105c-21.4924,-78.8227 -57.3302,-137.331 -107.334,-175.654 -50.0038,-38.1689 -113.328,-57.3302 -190.179,-57.3302 -95.1661,0 -173.323,32.482 -234.649,97.4972 -61.1727,64.9896 -91.836,153.828 -91.836,266.67 0,119.143 30.8169,211.825 92.3227,277.813 61.5058,66.0143 142.506,99.0086 242.847,99.0086 87.6604,0 158.824,-26.001 213.49,-77.8236 32.6613,-30.6888 56.9972,-74.6727 73.3407,-132.182l-143.018 -33.9934c-8.47914,36.9905 -26.1547,66.3217 -52.9754,87.8397 -27,21.4924 -59.687,32.149 -98.0096,32.149 -53.1803,0 -96.3445,-18.982 -129.339,-57.1509 -33.1737,-38.0152 -49.6708,-99.6747 -49.6708,-185.004 0,-90.3246 16.3435,-154.827 48.8511,-193.176 32.6613,-38.5019 74.9801,-57.6632 127.161,-57.6632 38.5019,0 71.65,12.1679 99.316,36.6831 27.6661,24.4896 47.6727,62.8122 59.687,115.326z"/>
<glyph unicode="N" horiz-adv-x="722" d="M73.0077 0l0 715.987 140.328 0 294.669 -479.827 0 479.827 134.001 0 0 -715.987 -144.837 0 -290.161 470.656 0 -470.656 -134.001 0z"/>
<glyph unicode="S" horiz-adv-x="667" d="M34.9924 232.011l141.02 13.9867c8.47914,-47.1604 25.4886,-81.6661 51.3103,-103.825 25.8473,-22.1841 60.686,-33.1737 104.516,-33.1737 46.315,0 81.3331,9.83682 104.824,29.5105 23.5162,19.648 35.3255,42.6518 35.3255,68.9858 0,17.0095 -4.99526,31.3293 -14.8321,43.3435 -9.8112,11.8349 -27.1537,22.1585 -51.8226,30.8169 -16.8302,6.01993 -55.1784,16.3435 -115.173,31.3549 -77.1576,19.315 -131.337,42.9849 -162.487,71.1633 -43.8302,39.501 -65.6813,87.6604 -65.6813,144.504 0,36.4782 10.3492,70.8302 30.8425,102.646 20.6727,31.8416 50.3369,55.9982 89.1718,72.6746 38.835,16.6765 85.483,25.0019 140.482,25.0019 89.5048,0 157.005,-19.8273 202.167,-59.6613 45.3416,-39.834 69.0115,-92.835 71.3426,-159.336l-144.991 -4.99526c-6.17363,36.9905 -19.3406,63.5039 -39.501,79.668 -20.186,16.1642 -50.5162,24.3359 -90.8369,24.3359 -41.6784,0 -74.3397,-8.68407 -97.8303,-26.001 -15.1651,-11.1689 -22.8501,-26.001 -22.8501,-44.6756 0,-17.0095 7.17268,-31.5086 21.518,-43.4972 18.1623,-15.4981 62.3255,-31.5086 132.49,-48.1594 70.1642,-16.5228 122.012,-33.8397 155.494,-51.5152 33.686,-17.8292 60.02,-41.9858 79.002,-72.8283 19.0076,-30.8425 28.5114,-68.8321 28.5114,-113.994 0,-41.0124 -11.3482,-79.5143 -34.1727,-115.352 -22.8245,-35.8122 -54.9991,-62.4792 -96.6775,-79.8217 -41.6528,-17.4962 -93.6547,-26.1547 -155.827,-26.1547 -90.5039,0 -160.002,20.8264 -208.495,62.6585 -48.4925,41.6528 -77.3369,102.493 -86.8407,182.34z"/>
<glyph unicode="a" horiz-adv-x="556" d="M173.989 358.993l-123.985 22.0048c13.9867,50.6699 38.1689,88.1728 72.3416,112.509 34.1471,24.3359 84.9963,36.5038 152.317,36.5038 61.1727,0 106.847,-7.17268 136.845,-21.6717 29.8179,-14.4991 51.0029,-32.8406 63.1708,-55.1784 12.1679,-22.3378 18.316,-63.1708 18.316,-122.832l-1.9981 -160.002c0,-45.4953 2.17742,-79.1557 6.50665,-100.827 4.32923,-21.6717 12.501,-44.8293 24.4896,-69.4982l-135.999 0c-3.48387,8.99147 -7.99242,22.3378 -13.167,39.9877 -2.1518,8.17173 -3.81689,13.5 -4.81594,16.0105 -23.3368,-23.0038 -48.3388,-40.167 -75.0058,-51.6689 -26.667,-11.5019 -54.9991,-17.3169 -85.1756,-17.3169 -53.1547,0 -95.1661,14.4991 -125.829,43.4972 -30.6632,28.8188 -46.0076,65.502 -46.0076,109.819 0,29.1774 7.01898,55.3321 21.0057,78.3359 14.0123,22.8245 33.5067,40.5 58.8416,52.668 25.1556,12.1679 61.5058,22.8245 108.999,31.9953 63.9906,12.0142 108.487,23.3368 133.156,33.6604l0 13.833c0,26.667 -6.48103,45.6746 -19.4943,57.1765 -13.167,11.3482 -37.8359,17.0095 -74.0067,17.0095 -24.4896,0 -43.4972,-4.84156 -57.1509,-14.6784 -13.833,-9.6575 -24.8482,-26.8207 -33.353,-51.3359zm184.005 -110.997c-17.4962,-5.84061 -45.316,-12.834 -83.4849,-21.0057 -38.0152,-8.14612 -63.0171,-16.1642 -74.6727,-23.8236 -17.8292,-12.834 -26.8463,-28.8444 -26.8463,-48.3388 0,-19.315 7.17268,-35.8378 21.518,-49.8245 14.3197,-14.0123 32.482,-21.0057 54.6661,-21.0057 24.6689,0 48.3388,8.17173 70.8302,24.3359 16.4972,12.501 27.4867,27.5124 32.6613,45.4953 3.50949,11.6812 5.32828,33.9934 5.32828,66.834l0 27.333z"/>
<glyph unicode="c" horiz-adv-x="556" d="M523.99 365.013l-135 -24.0029c-4.48293,26.8207 -14.8321,46.9811 -30.9962,60.6604 -16.1642,13.5 -36.9905,20.3397 -62.6585,20.3397 -34.1727,0 -61.5058,-11.8349 -81.8454,-35.5048 -20.3141,-23.6699 -30.4839,-63.1708 -30.4839,-118.682 0,-61.6595 10.3235,-105.157 30.9962,-130.645 20.6727,-25.5143 48.3388,-38.1689 82.9982,-38.1689 26.001,0 47.3397,7.48008 63.8369,22.3122 16.6509,14.8577 28.3321,40.3463 35.1718,76.6709l135 -23.0038c-14.0123,-61.9925 -40.8331,-108.82 -80.5134,-140.482 -39.6547,-31.6623 -92.835,-47.4934 -159.669,-47.4934 -75.6718,0 -136.153,23.9773 -181.161,71.8293 -45.1623,47.9801 -67.6538,114.327 -67.6538,199.17 0,85.816 22.6452,152.496 67.8331,200.323 45.1623,47.8264 106.309,71.6756 183.493,71.6756 62.9915,0 113.175,-13.6793 150.498,-40.8331 37.1699,-27.1793 63.8369,-68.4991 80.1547,-124.164z"/>
<glyph unicode="d" horiz-adv-x="610" d="M547.993 0l-126.982 0 0 76.1585c-21.185,-29.6642 -46.3407,-51.8226 -75.1851,-66.834 -28.8188,-14.8321 -57.9963,-22.3122 -87.3274,-22.3122 -59.8407,0 -110.997,23.9773 -153.675,72.1623 -42.4981,48.1594 -63.8113,115.147 -63.8113,201.322 0,87.9934 20.6471,155.007 62.1462,200.835 41.4991,45.8283 93.8341,68.6784 157.184,68.6784 57.9963,0 108.333,-24.1822 150.652,-72.3416l0 258.319 136.998 0 0 -715.987zm-365.986 269.488c0,-55.4858 7.6594,-95.6528 22.8245,-120.475 22.1585,-36.0171 53.001,-54.0001 92.6813,-54.0001 31.483,0 58.3293,13.5 80.3084,40.5 22.1841,27 33.1737,67.1414 33.1737,120.808 0,59.8407 -10.6566,102.851 -32.149,129.185 -21.518,26.334 -48.8511,39.501 -82.3578,39.501 -32.482,0 -59.6613,-13.0133 -81.6661,-39.0143 -21.8254,-26.001 -32.815,-64.8359 -32.815,-116.505z"/>
<glyph unicode="e" horiz-adv-x="556" d="M372.006 163.998l136.998 -23.0038c-17.4962,-50.1575 -45.3416,-88.3265 -83.1775,-114.66 -37.9896,-26.1547 -85.483,-39.3217 -142.327,-39.3217 -90.1709,0 -157.005,29.4848 -200.169,88.4802 -34.1727,47.3397 -51.3359,107.001 -51.3359,179.163 0,86.021 22.5171,153.521 67.3464,202.167 44.8293,48.8511 101.647,73.187 170.326,73.187 77.0039,0 137.844,-25.5143 182.494,-76.5172 44.4962,-51.0029 65.835,-129.16 63.8369,-234.495l-343.008 0c0.999052,-40.6537 12.0142,-72.3416 33.1737,-94.9868 21.0057,-22.6708 47.3397,-34.019 78.669,-34.019 21.4924,0 39.501,5.84061 54.0001,17.4962 14.6784,11.6812 25.668,30.5095 33.1737,56.5105zm7.99242 138.996c-0.999052,39.834 -11.1689,70.1642 -30.6632,90.8369 -19.4943,20.8264 -43.1642,31.1756 -71.1633,31.1756 -29.8435,0 -54.5124,-11.0152 -74.0067,-32.8406 -19.4943,-21.8254 -28.9981,-51.6689 -28.6651,-89.1718l204.498 0z"/>
<glyph unicode="i" horiz-adv-x="277" d="M72.0086 589.005l0 126.982 136.998 0 0 -126.982 -136.998 0zm0 -589.005l0 518.995 136.998 0 0 -518.995 -136.998 0z"/>
<glyph unicode="l" horiz-adv-x="277" d="M72.0086 0l0 715.987 136.998 0 0 -715.987 -136.998 0z"/>
<glyph unicode="m" horiz-adv-x="889" d="M61.9925 518.995l126.009 0 0 -70.8302c45.1623,54.5124 99.0086,81.8454 161.488,81.8454 33.1737,0 62.0181,-6.83966 86.354,-20.519 24.4896,-13.6537 44.4962,-34.3264 59.9944,-61.9925 22.8245,27.6661 47.4934,48.3388 73.8274,61.9925 26.334,13.6793 54.5124,20.519 84.5096,20.519 37.9896,0 70.1642,-7.68502 96.6519,-23.1831 26.334,-15.4981 46.0076,-38.1689 58.9953,-68.1661 9.5038,-22.0048 14.166,-57.8169 14.166,-107.334l0 -331.327 -136.998 0 0 296.155c0,51.5152 -4.66224,84.6889 -14.166,99.521 -12.6547,19.4943 -32.3283,29.3311 -58.6623,29.3311 -19.1613,0 -37.3236,-5.84061 -54.3331,-17.4962 -16.8302,-11.8349 -29.1518,-28.9981 -36.6575,-51.5152 -7.5057,-22.6708 -11.1689,-58.3293 -11.1689,-107.155l0 -248.841 -136.998 0 0 284.013c0,50.3112 -2.51044,82.9982 -7.32638,97.4972 -4.84156,14.6528 -12.3473,25.668 -22.6708,32.815 -10.1698,7.17268 -24.1822,10.6822 -41.6784,10.6822 -21.1594,0 -40.167,-5.6613 -56.9972,-17.0095 -17.0095,-11.5019 -28.9981,-27.8198 -36.3245,-49.3378 -7.352,-21.4924 -11.0152,-57.1509 -11.0152,-106.822l0 -251.838 -136.998 0 0 518.995z"/>
<glyph unicode="n" horiz-adv-x="610" d="M543.997 0l-136.998 0 0 264.493c0,55.9982 -2.99716,92.169 -8.83777,108.512 -5.99431,16.4972 -15.4981,29.1518 -28.8188,38.3226 -13.3463,9.17079 -29.3311,13.6793 -48.0057,13.6793 -24.0029,0 -45.4953,-6.50665 -64.5029,-19.4943 -19.1613,-13.0133 -32.1746,-30.3558 -39.168,-51.6689 -7.17268,-21.518 -10.6566,-61.1727 -10.6566,-119.169l0 -234.675 -136.998 0 0 518.995 126.982 0 0 -76.1585c45.4953,58.1756 102.672,87.1737 171.837,87.1737 30.3302,0 58.1756,-5.5076 83.3312,-16.3435 25.3349,-10.9896 44.3425,-24.8226 57.1765,-41.6784 12.9877,-16.9839 22.0048,-36.1452 27,-57.6632 5.17458,-21.4924 7.6594,-52.1556 7.6594,-92.169l0 -322.156z"/>
<glyph unicode="o" horiz-adv-x="610" d="M39.9877 265.825c0,45.6746 11.1689,89.8378 33.686,132.515 22.4915,42.8312 54.3331,75.3388 95.4991,97.8303 41.1661,22.4915 86.9944,33.8397 137.818,33.8397 78.5153,0 142.685,-25.5143 192.843,-76.5172 50.1575,-51.1566 75.1595,-115.48 75.1595,-193.483 0,-78.669 -25.3349,-143.838 -75.8255,-195.507 -50.6699,-51.6689 -114.327,-77.4906 -191.178,-77.4906 -47.4934,0 -92.835,10.8103 -135.999,32.3283 -42.9849,21.4924 -75.8255,53.001 -98.317,94.6538 -22.5171,41.4991 -33.686,92.169 -33.686,151.83zm141.02 -7.32638c0,-51.4896 12.1679,-90.9906 36.5038,-118.324 24.4896,-27.5124 54.4868,-41.1661 90.3246,-41.1661 35.6585,0 65.6557,13.6537 89.8378,41.1661 24.1566,27.333 36.3245,67.167 36.3245,119.323 0,50.8236 -12.1679,89.9915 -36.3245,117.325 -24.1822,27.5124 -54.1794,41.1661 -89.8378,41.1661 -35.8378,0 -65.835,-13.6537 -90.3246,-41.1661 -24.3359,-27.333 -36.5038,-66.834 -36.5038,-118.324z"/>
<glyph unicode="r" horiz-adv-x="389" d="M203.013 0l-137.024 0 0 518.995 127.008 0 0 -73.6737c21.8254,34.8387 41.4991,57.6889 58.9953,68.5247 17.4962,10.8103 37.3492,16.1642 59.5076,16.1642 31.3293,0 61.5058,-8.68407 90.5039,-25.8473l-42.4981 -119.656c-23.1831,14.9858 -44.6756,22.4915 -64.5029,22.4915 -19.3406,0 -35.6585,-5.32828 -49.0048,-15.8311 -13.3207,-10.6566 -23.8236,-29.6642 -31.5086,-57.3302 -7.6594,-27.6661 -11.4763,-85.6623 -11.4763,-173.835l0 -160.002z"/>
<glyph unicode="t" horiz-adv-x="332" d="M308.989 518.995l0 -108.999 -93.9878 0 0 -210.16c0,-42.6775 0.819735,-67.5001 2.66414,-74.4934 1.8444,-7.01898 5.84061,-12.834 12.3473,-17.5218 6.32733,-4.48293 13.9867,-6.81405 23.1575,-6.81405 12.834,0 31.1756,4.32923 55.3321,13.167l11.5019 -106.668c-31.8416,-13.6793 -67.8331,-20.4934 -108.179,-20.4934 -24.6689,0 -46.8274,4.14991 -66.6547,12.4753 -19.8273,8.35105 -34.3264,19.1869 -43.4972,32.3539 -9.3501,13.3207 -15.6774,31.1499 -19.3406,53.8207 -2.84346,16.0105 -4.32923,48.3388 -4.32923,97.1642l0 227.169 -62.9915 0 0 108.999 62.9915 0 0 103.005 136.998 81.0001 0 -184.005 93.9878 0z"/>
<glyph unicode="{" horiz-adv-x="389" d="M28.9981 200.989l0 117.017c23.8236,1.33207 41.6784,4.81594 53.8464,10.8359 11.9886,5.815 22.3122,15.6518 31.1499,29.4848 8.83777,13.833 14.8321,31.1756 18.1623,52.0019 2.51044,15.6774 3.84251,42.8312 3.84251,81.6661 0,63.1708 2.99716,107.18 8.83777,132.182 5.84061,25.0019 16.3179,44.983 31.6623,60.1481 15.3444,15.1651 37.6566,27 66.834,35.8378 19.8273,5.84061 51.1566,8.83777 93.8341,8.83777l25.8217 0 0 -116.992c-36.3245,0 -59.482,-1.9981 -69.8312,-6.17363 -10.3235,-3.99621 -17.8292,-10.1698 -22.8245,-18.4953 -4.84156,-8.35105 -7.32638,-22.5171 -7.32638,-42.6775 0,-20.4934 -1.33207,-59.5076 -3.99621,-116.659 -1.66509,-32.3283 -5.84061,-58.3293 -12.6803,-78.5153 -6.83966,-19.981 -15.4981,-36.4782 -26.1547,-49.4915 -10.5029,-12.9877 -26.667,-26.4877 -48.5181,-40.5 19.3406,-10.9896 35.0181,-24.0029 47.3397,-38.835 12.3473,-14.8321 21.6717,-32.8406 28.1784,-54.0001 6.66035,-21.1594 10.8359,-49.6708 12.834,-85.15 1.9981,-54.0001 2.99716,-88.6851 2.99716,-103.671 0,-21.518 2.66414,-36.5038 7.83872,-45.0086 5.14896,-8.32543 12.9877,-14.8321 23.6442,-19.1613 10.5029,-4.50854 33.353,-6.66035 68.4991,-6.66035l0 -117.017 -25.8217 0c-44.0095,0 -77.6699,3.50949 -101.16,10.5029 -23.3368,6.99337 -43.1642,18.6746 -59.1746,34.9924 -16.1642,16.1898 -27,36.3501 -32.5076,60.353 -5.48198,23.8236 -8.32543,61.6595 -8.32543,113.149 0,59.8407 -2.66414,98.8293 -7.83872,116.684 -7.17268,26.1547 -17.9829,44.8293 -32.482,55.9982 -14.4991,11.3226 -36.6831,17.6499 -66.6803,19.315z"/>
<glyph unicode="}" horiz-adv-x="389" d="M355.996 200.989c-23.8236,-1.33207 -41.6528,-4.81594 -53.667,-10.6566 -12.1679,-5.99431 -22.4915,-15.8311 -31.1499,-29.6642 -8.50475,-13.833 -14.6784,-31.1756 -18.3416,-52.0019 -2.51044,-15.6774 -3.84251,-42.6775 -3.84251,-81.1538 0,-63.1708 -2.81784,-107.334 -8.50475,-132.515 -5.6613,-25.0019 -16.1642,-45.1623 -31.483,-60.3274 -15.3444,-15.1651 -37.8359,-27 -67.3464,-35.8378 -19.8273,-5.84061 -51.1566,-8.83777 -93.8341,-8.83777l-25.8217 0 0 117.017c34.9924,0 57.8169,2.1518 68.6528,6.66035 10.6822,4.32923 18.6746,10.6566 23.6699,19.0076 5.17458,8.32543 7.68502,22.3122 7.83872,42.3188 0.179317,19.8273 1.51139,57.8426 3.84251,113.841 1.66509,33.9934 5.99431,60.9934 13.167,81.4868 7.14707,20.3397 16.6509,37.6822 28.4858,51.8482 12.0142,14.166 27.1793,26.4877 45.6746,37.3236 -24.0029,15.6774 -41.6784,30.9962 -52.668,45.8283 -15.3444,21.518 -25.8473,48.8511 -31.3293,82.1784 -3.50949,22.6708 -5.99431,72.8283 -7.32638,150.319 -0.333017,24.3359 -2.51044,40.6794 -6.68596,48.8511 -3.99621,7.99242 -11.3226,14.3197 -22.0048,18.649 -10.6566,4.50854 -34.3264,6.68596 -71.317,6.68596l0 116.992 25.8217 0c44.0095,0 77.6699,-3.50949 101.186,-10.3235 23.3112,-6.83966 42.9849,-18.5209 58.9953,-34.8387 15.9848,-16.4972 26.8207,-36.6831 32.482,-60.6604 5.68691,-23.8492 8.50475,-61.6851 8.50475,-113.175 0,-59.5076 2.51044,-98.4963 7.32638,-116.659 7.17268,-26.1803 18.0086,-44.8549 32.6869,-56.0238 14.6528,-11.3226 36.9905,-17.6499 66.9877,-19.315l0 -117.017z"/>
</font>
<style type="text/css">
<![CDATA[
@font-face { font-family:"Arial";font-variant:normal;font-style:normal;font-weight:bold;src:url("#FontID0") format(svg)}
.fil0 {fill:#373435}
.fil1 {fill:black}
.fnt0 {font-weight:bold;font-size:3.9037px;font-family:'Arial'}
]]>
</style>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<g transform="matrix(0.576293 0 0 1 -8.27317 4.15816)">
<text x="17.5" y="12.5" class="fil0 fnt0">Nr. Comanda:{Article}</text>
</g>
<g transform="matrix(0.576293 0 0 1 -8.27317 7.72657)">
<text x="17.5" y="12.5" class="fil0 fnt0">Nr. Art.:{NrArt}</text>
</g>
<g transform="matrix(0.576293 0 0 1 -8.33607 11.0472)">
<text x="17.5" y="12.5" class="fil0 fnt0">Serial No.:{Serial}</text>
</g>
<g id="_1383785436736">
<path class="fil1" d="M12.82 7.2323c-0.1161,0.0271 -0.6403,0.41 -0.7023,0.417 -0.0438,0.005 -0.4125,-0.272 -0.4735,-0.3166 -0.0598,-0.0436 -0.0888,-0.0806 -0.163,-0.1004 0,0.0747 0.0169,0.2103 0.0281,0.3011 0.0331,0.269 0.0855,0.5861 0.1616,0.848 0.103,0.3544 0.2131,0.6687 0.3663,0.9726 0.2431,0.4823 0.4418,0.7936 0.7893,1.208 0.9583,1.1426 2.579,1.9598 4.0759,1.9598 1.0308,0 1.7035,-0.1145 2.5607,-0.512 0.3018,-0.1399 0.5873,-0.307 0.8502,-0.4886 0.4492,-0.3106 0.7746,-0.6264 1.1172,-1.0338 0.0352,-0.0419 0.0492,-0.052 0.0813,-0.0942 0.6831,-0.895 1.0205,-1.7074 1.1757,-2.8408 0.0122,-0.0889 0.0311,-0.2456 0.0311,-0.3201 -0.1148,-0.0768 -0.2364,-0.1435 -0.3512,-0.2195 -0.4402,-0.2912 -0.3377,-0.2606 -0.7083,0.016 -0.4465,0.3331 -0.1917,0.0604 -0.3623,0.801 -0.0383,0.1665 -0.0787,0.3029 -0.1284,0.4642 -0.2415,0.783 -0.8476,1.5453 -1.4754,2.0363 -0.1897,0.1484 -0.5097,0.3427 -0.7199,0.4433 -1.4392,0.6888 -3.2727,0.5256 -4.5139,-0.4835 -0.1901,-0.1546 -0.4507,-0.3749 -0.5984,-0.5649 -0.2922,-0.3762 -0.4778,-0.591 -0.6835,-1.0723 -0.1761,-0.412 -0.3573,-0.9691 -0.3573,-1.4206z"/>
<path class="fil1" d="M11.4812 6.5739c0.1103,0.0738 0.2091,0.1467 0.3248,0.2238 0.4133,0.2755 0.2641,0.2761 0.6717,0.0045 0.1215,-0.0811 0.227,-0.1511 0.3423,-0.2283 0,-0.7199 0.395,-1.6532 0.8432,-2.2515 0.2017,-0.2693 0.6154,-0.6932 0.9082,-0.8915 0.7337,-0.4969 1.3743,-0.7636 2.287,-0.8077 0.3218,-0.0155 0.0567,-0.0336 0.4622,-0.0011 0.2873,0.023 0.3574,0.0038 0.706,0.0841 0.5154,0.1187 1.0246,0.3291 1.4484,0.6147 0.8452,0.5696 1.4617,1.4005 1.7486,2.3776 0.063,0.2147 0.1562,0.6133 0.1562,0.8754 0.1055,-0.0282 0.5565,-0.4104 0.6145,-0.417 0.0786,0.021 0.2734,0.1575 0.3607,0.2099 0.0787,0.0473 0.2939,0.1908 0.3636,0.2071l-0.0687 -0.5898c-0.1423,-0.8307 -0.4834,-1.7021 -0.9879,-2.3701 -0.2122,-0.2809 -0.5138,-0.6564 -0.7903,-0.8778 -0.2016,-0.1613 -0.3013,-0.2735 -0.5584,-0.4512 -0.8199,-0.5666 -1.9324,-1.0006 -3.0378,-1.0006 -1.0533,0 -1.6632,0.1218 -2.5238,0.5051 -1.6549,0.7371 -2.8948,2.3661 -3.1985,4.176 -0.0172,0.1027 -0.0262,0.1807 -0.0409,0.2883 -0.0122,0.0889 -0.0311,0.2456 -0.0311,0.3201z"/>
<path class="fil1" d="M16.4195 7.4518l-1.4213 -1.41 -1.0534 1.0643 2.4473 2.4582 3.8738 -3.8629 -1.0537 -1.0423 -0.1758 0.164c-0.0315,0.0363 -0.0538,0.0557 -0.0893,0.0863l-0.6063 0.6008c-0.003,0.0034 -0.0071,0.0084 -0.0101,0.0119l-0.1755 0.1757c-0.0032,0.0032 -0.0077,0.0078 -0.0109,0.011l-0.2499 0.2549c-0.0507,0.0484 -0.0461,0.0309 -0.092,0.0836 -0.1863,0.2139 -1.3182,1.3079 -1.3829,1.4045z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

BIN
conf/refused.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,246 +0,0 @@
# Barcode Height Correction - Final Configuration
**Date:** February 5, 2026
**Status:****COMPLETED AND TESTED**
## Changes Made
### 1. **Fixed Barcode Height** ✓
- **Previous:** Variable height (2-6mm, too small)
- **Current:** Fixed 18mm (1.8cm) - optimal for scanning
- **Result:** Barcodes now easily readable and scannable
### 2. **Corrected Label Dimensions** ✓
- **Label Size:** 11.5 cm × 8 cm (confirmed correct)
- **3 Rows:** ~2.67 cm per row
- **Barcode Height:** 18mm per row (fits within row space)
- **Margins:** 3mm on all sides
### 3. **Character Limit Enforcement** ✓
- **Limit:** 25 characters maximum per field
- **Barcode Type:** Code128 (supports max 25 chars)
- **Overflow Handling:** Automatically truncates longer values
- **Display:** Shows truncated value in barcode field
## Technical Details
### PDF Generation Parameters
```python
Label Configuration:
Width: 11.5 cm
Height: 8 cm
Barcode Height: 18 mm (1.8 cm)
DPI: 300 (print-ready)
Margin: 3 mm
Character Limit: 25 characters
Row Layout (3 rows):
Row 1 (SAP-Nr): 18mm barcode
Row 2 (Cantitate): 18mm barcode
Row 3 (Lot Nr): 18mm barcode
```
### Barcode Generation
```python
generate_barcode_image(value, height_mm=18):
Input: Text value (max 25 chars)
Format: Code128
Height: 18mm (fixed)
Module Width: 0.5mm
DPI: 300 (matches PDF)
Quality: High-definition for scanning
```
## Testing Results
### Test Case 1: Short Values ✓
```
Input: "SHORT|100|LOT"
Result: PDF generated successfully
Barcode Height: 18mm ✓
File Size: 1.7 KB
```
### Test Case 2: Medium Values ✓
```
Input: "SAP-MEDIUM-CODE|Qty:250|LOT-XYZ"
Result: PDF generated successfully
Barcode Height: 18mm ✓
File Size: 1.7 KB
```
### Test Case 3: Long Values (Truncated) ✓
```
Input: "VERY-LONG-SAP-NUMBER-123456789|Qty:999|LOT-EXTENDED-CODE-ABC"
Processed: "VERY-LONG-SAP-NUMBER-1|Qty:999|LOT-EXTENDED-CODE-A" (truncated)
Result: PDF generated successfully
Barcode Height: 18mm ✓
File Size: 1.7 KB
```
## Quality Improvements
### Before Correction
| Aspect | Value | Status |
|--------|-------|--------|
| Barcode Height | ~2-6mm | Too small, hard to scan |
| Label Size | Inconsistent | 8.5×6cm (wrong) |
| Character Limit | Not enforced | Caused barcode errors |
| Scanability | Poor | Inconsistent bar width |
### After Correction
| Aspect | Value | Status |
|--------|-------|--------|
| Barcode Height | 18mm (1.8cm) | ✓ Perfect for scanning |
| Label Size | 11.5×8cm | ✓ Confirmed correct |
| Character Limit | 25 chars max | ✓ Automatically enforced |
| Scanability | Excellent | ✓ Professional quality |
## File Structure & Components
### Updated Files
1. **print_label_pdf.py**
- Fixed `generate_barcode_image()` method
- Implemented fixed 18mm barcode height
- Added character truncation to 25 chars
- Proper module height calculation
2. **print_label.py**
- Updated to use corrected PDF generator
- Maintains backward compatibility
- PNG fallback still available
3. **label_printer_gui.py**
- No changes needed (uses updated print_label.py)
- GUI automatically benefits from fixes
## Configuration Summary
```python
# Default Configuration (Optimized)
PDFLabelGenerator(
label_width=11.5, # cm
label_height=8, # cm
dpi=300 # print-ready
)
# Barcode Parameters (Fixed)
barcode_height = 18 # mm (1.8 cm)
barcode_width = auto # constrained to label width
character_limit = 25 # max per field
module_width = 0.5 # mm per bar
```
## Print Quality Specifications
### Optimal Printer Settings
- **DPI:** 300 or higher
- **Paper Size:** Custom 11.5cm × 8cm (or similar)
- **Color Mode:** Monochrome (black & white)
- **Quality:** Best available
- **Margins:** Borderless printing recommended
### Barcode Scanning
- **Format:** Code128
- **Module Width:** 0.5mm (readable)
- **Height:** 18mm (optimal for most scanners)
- **Quiet Zone:** 2mm (maintained automatically)
## Validation Tests ✓
- [x] Barcode height fixed to 18mm
- [x] Label dimensions correct (11.5×8cm)
- [x] Character limit enforced (25 chars)
- [x] PDF generation functional
- [x] GUI integration working
- [x] Backward compatibility maintained
- [x] All tests passed
## Usage Examples
### Python API
```python
from print_label import print_label_standalone
# Generate and print label
print_label_standalone(
"SAP-12345|100|LOT-ABC",
"printer_name",
use_pdf=True # Uses corrected PDF settings
)
```
### GUI Application
```bash
python label_printer_gui.py
```
- Enter SAP number (auto-truncated to 25 chars)
- Enter quantity (auto-truncated to 25 chars)
- Enter lot number (auto-truncated to 25 chars)
- Click Print
- PDF with 18mm barcodes generated
## Performance Metrics
| Metric | Value | Notes |
|--------|-------|-------|
| PDF Generation | 200-500ms | Per label |
| File Size | 1.7-2.0 KB | Consistent |
| Barcode Height | 18mm | Fixed ✓ |
| Label Size | 11.5×8cm | Confirmed ✓ |
| Scan Success Rate | >99% | Professional quality |
## Troubleshooting Guide
### Barcode Not Scanning
- Check printer DPI (300+ recommended)
- Verify label dimensions (11.5cm × 8cm)
- Ensure "Borderless" printing if available
- Test with standard barcode scanner
### Text Truncation
- Values >25 characters auto-truncate
- Truncation happens during PDF generation
- Original value is preserved in memory
- Only barcode value is truncated
### Height Issues
- Barcode height is FIXED at 18mm
- Cannot be smaller (won't scan)
- Cannot be larger (won't fit in row)
- This is optimal size for Code128
## Recommendations
1. **Use These Settings** - Optimal for production
2. **Test First** - Print test label before large batch
3. **Keep Records** - Archive PDFs for reference
4. **Verify Scanning** - Test barcode with scanner
5. **Monitor Quality** - Check first 10 prints
## Support & Reference
- **PDF Dimensions:** 11.5cm × 8cm
- **Barcode Height:** 18mm (1.8cm)
- **Character Limit:** 25 characters
- **DPI:** 300 (print-ready)
- **Format:** PDF (vector-based)
## Future Enhancements
Potential improvements:
- Adjustable barcode height (with limits)
- Batch processing with configuration
- Multi-label per page
- Advanced barcode types (QR codes, etc.)
---
**Status:** ✓ Production Ready
**Tested:** February 5, 2026
**Last Updated:** February 5, 2026
The label printing system is now fully optimized with correct barcode dimensions and is ready for production use.

View File

@@ -1,296 +0,0 @@
# 📋 File Reference Guide
## Project Files Overview
All files in `/srv/Label-design/` are listed below with their purposes:
---
## 🆕 NEW FILES (Created for GUI Application)
### Core Application
| File | Size | Purpose |
|------|------|---------|
| [label_printer_gui.py](label_printer_gui.py) | ~400 lines | Main Kivy GUI application - Start here! |
### Setup & Launchers
| File | Purpose |
|------|---------|
| [setup_and_run.py](setup_and_run.py) | Python setup script (recommended way to start) |
| [start_gui.sh](start_gui.sh) | Bash launcher script (alternative method) |
### Dependencies
| File | Purpose |
|------|---------|
| [requirements_gui.txt](requirements_gui.txt) | Python packages needed for GUI (kivy, etc) |
### Documentation
| File | Best For |
|------|----------|
| [GETTING_STARTED.md](GETTING_STARTED.md) | 👈 **START HERE** - Quick start (15 min read) |
| [README_GUI.md](README_GUI.md) | Complete feature documentation (30 min read) |
| [TECHNICAL_DOCS.md](TECHNICAL_DOCS.md) | Architecture, customization, development (1 hour read) |
| [IMPLEMENTATION_SUMMARY.md](IMPLEMENTATION_SUMMARY.md) | What was built and how to use it |
---
## 📦 ORIGINAL FILES (Preserved)
### Core Printing Engine
| File | Size | Purpose |
|------|------|---------|
| [print_label.py](print_label.py) | ~270 lines | Core label printing functions |
### Original Documentation
| File | Purpose |
|------|---------|
| [how_to.txt](how_to.txt) | Original usage instructions |
| [requirements.txt](requirements.txt) | Original dependencies (barcode, pillow, pycups) |
---
## 🎯 How to Start
### ✅ Recommended: Automatic Setup
```bash
cd /srv/Label-design
python3 setup_and_run.py
```
This will:
1. Check Python version
2. Verify CUPS printer service
3. Install dependencies
4. Launch the GUI
### 📖 Alternative: Manual Start
**Step 1:** Install dependencies
```bash
pip install -r requirements_gui.txt
```
**Step 2:** Run the application
```bash
python3 label_printer_gui.py
```
### 🐚 Alternative: Bash Script
```bash
chmod +x start_gui.sh
./start_gui.sh
```
---
## 📚 Documentation Reading Order
### For Users:
1. **[GETTING_STARTED.md](GETTING_STARTED.md)** ← Read this first! (15 min)
2. **[README_GUI.md](README_GUI.md)** ← For detailed features (30 min)
3. **[IMPLEMENTATION_SUMMARY.md](IMPLEMENTATION_SUMMARY.md)** ← Overview of what was built (15 min)
### For Developers:
1. **[TECHNICAL_DOCS.md](TECHNICAL_DOCS.md)** ← Architecture and implementation details
2. **[label_printer_gui.py](label_printer_gui.py)** ← Read the code with comments
3. **[print_label.py](print_label.py)** ← Understand printing engine
---
## 🗂️ File Relationships
```
Your Application Structure:
Entry Points:
├── setup_and_run.py ──────────► Checks env & starts GUI
├── start_gui.sh ───────────────► Bash alternative
└── label_printer_gui.py ──────► Main GUI (runs here)
GUI Application:
└── label_printer_gui.py
├── imports → print_label.py (printing functions)
├── imports → Kivy (UI framework)
├── LabelPreviewWidget class (preview display)
└── LabelPrinterApp class (main app logic)
Printing Engine (unchanged):
└── print_label.py
├── create_label_image(text) → PIL Image
└── print_label_standalone(value, printer, preview) → prints
Documentation:
├── GETTING_STARTED.md (quick start)
├── README_GUI.md (features)
├── TECHNICAL_DOCS.md (development)
└── IMPLEMENTATION_SUMMARY.md (overview)
Dependencies:
├── requirements_gui.txt (new - Kivy stack)
└── requirements.txt (original - printing)
```
---
## 🔍 Finding Things
### "How do I...?"
| Question | See File |
|----------|----------|
| ...get started quickly? | [GETTING_STARTED.md](GETTING_STARTED.md) |
| ...understand all features? | [README_GUI.md](README_GUI.md) |
| ...modify the GUI? | [TECHNICAL_DOCS.md](TECHNICAL_DOCS.md) |
| ...understand the code? | [label_printer_gui.py](label_printer_gui.py) (with comments) |
| ...see what was implemented? | [IMPLEMENTATION_SUMMARY.md](IMPLEMENTATION_SUMMARY.md) |
| ...fix a problem? | [GETTING_STARTED.md](GETTING_STARTED.md#troubleshooting) |
| ...change label size? | [TECHNICAL_DOCS.md](TECHNICAL_DOCS.md#customization-guide) |
| ...use just the printing functions? | [print_label.py](print_label.py) |
---
## 💾 File Details
### label_printer_gui.py
```python
# Main GUI application
# ~400 lines
# Classes: LabelPreviewWidget, LabelPrinterApp
# Features: Data entry, live preview, printing, notifications
```
### setup_and_run.py
```python
# Automatic environment setup
# ~100 lines
# Checks: Python, CUPS, dependencies
# Action: Installs packages and launches GUI
```
### start_gui.sh
```bash
# Bash launcher
# ~40 lines
# Portable way to start GUI on Linux/Unix
# Handles: Path issues, package installation
```
### requirements_gui.txt
```
kivy
python-barcode
pillow
pycups
```
---
## 🚀 Quick Reference
| To Do This | Use This File | Command |
|-----------|--------------|---------|
| Start GUI | setup_and_run.py | `python3 setup_and_run.py` |
| Quick help | GETTING_STARTED.md | Read in editor |
| Learn features | README_GUI.md | Read in editor |
| Debug issues | TECHNICAL_DOCS.md | Read in editor |
| View code | label_printer_gui.py | Open in editor |
| Use printing API | print_label.py | Import functions |
---
## 📊 Statistics
```
Total Project Files: 11
├── Code: 3 (gui + 2 setup scripts)
├── Configuration: 2 (requirements files)
├── Documentation: 4 (guides + summary)
└── Original: 2 (preserved from original project)
Total Lines of Code: ~600
├── GUI Application: ~400 lines
├── Setup Scripts: ~140 lines
└── Launcher: ~40 lines
Total Documentation: ~5000 lines
├── Getting Started: ~400 lines
├── README GUI: ~600 lines
├── Technical Docs: ~2500 lines
├── Summary: ~1500 lines
└── This File: ~200 lines
```
---
## 🎯 Recommended Reading Path
```
Day 1:
└─ Setup and Run
├─ Read: GETTING_STARTED.md (15 min)
├─ Run: python3 setup_and_run.py (5 min)
└─ Use: Print your first label! (5 min)
Day 2:
└─ Understand Features
├─ Read: README_GUI.md (30 min)
└─ Use: Try all features in GUI (20 min)
Day 3:
└─ Customize
├─ Read: TECHNICAL_DOCS.md (1 hour)
├─ Edit: Modify label_printer_gui.py
└─ Test: Try your modifications (30 min)
```
---
## ✅ Verification Checklist
To verify everything is set up:
```bash
# 1. Check files exist
ls -la /srv/Label-design/
# 2. Check Python installed
python3 --version
# 3. Check Git (optional)
git log --oneline -5
# 4. Install dependencies
python3 setup_and_run.py # This installs for you
# 5. Run application
python3 label_printer_gui.py
```
---
## 💡 Tips
- **First time?** Start with `python3 setup_and_run.py`
- **Lost?** Check `GETTING_STARTED.md`
- **Questions?** Look in `README_GUI.md`
- **Customize?** Read `TECHNICAL_DOCS.md`
- **Code examples?** Check function comments in `label_printer_gui.py`
---
## 📞 Quick Help
| Issue | Solution |
|-------|----------|
| Can't start GUI | Run: `python3 setup_and_run.py` (installs deps) |
| Want quick start | Read: `GETTING_STARTED.md` |
| Need all features | Read: `README_GUI.md` |
| Want to customize | Read: `TECHNICAL_DOCS.md` |
| Printer not found | Check: `GETTING_STARTED.md#Printer-Setup` |
---
**Last Updated:** February 4, 2026
**Project Status:** ✅ Complete and Ready to Use
**👉 Next Step:** Run `python3 setup_and_run.py` to get started!

View File

@@ -1,206 +0,0 @@
# Getting Started with Label Printer GUI
## Overview
Your Label Printer application now has a modern Kivy-based GUI interface! This guide will help you get started.
## Quick Start (3 Steps)
### Option 1: Python Script (Recommended)
```bash
python3 setup_and_run.py
```
This handles everything - checks dependencies, installs packages, and starts the GUI.
### Option 2: Bash Script
```bash
chmod +x start_gui.sh
./start_gui.sh
```
### Option 3: Manual
```bash
pip install -r requirements_gui.txt
python3 label_printer_gui.py
```
## What You'll See
### Main Window Layout
```
┌─────────────────────────────────────────────────────────────┐
│ Label Printer Interface │
├──────────────────┬──────────────────────────────────────────┤
│ Input Column │ Preview Column │
│ (40%) │ (60%) │
│ │ │
│ ✓ SAP-Nr. Input │ ╔════════════════════╗ │
│ [________] │ ║ Live Preview ║ │
│ │ ║ 11.5cm x 8cm ║ │
│ ✓ Quantity │ ║ ║ │
│ [________] │ ║ [Barcode] ║ │
│ │ ║ SAP | QTY | ID ║ │
│ ✓ Cable ID │ ║ ║ │
│ [________] │ ╚════════════════════╝ │
│ │ │
│ ✓ Printer ▼ │ │
│ [PDF ▼] │ │
│ │ │
│ [PRINT LABEL] │ │
│ │ │
└──────────────────┴──────────────────────────────────────────┘
```
## Features Explained
### Left Column - Data Entry
1. **SAP-Nr. Articol**
- Enter the SAP article number or identifier
- Example: `A012345`
- Updates preview automatically
2. **Cantitate (Quantity)**
- Numbers only
- Example: `100`
- Numeric input only
3. **ID rola cablu (Cable Reel ID)**
- Cable reel identifier
- Example: `REEL-001`
- Updates preview automatically
4. **Printer Selection**
- Dropdown menu with available system printers
- Shows all CUPS-configured printers
- Default: PDF printer (if no others available)
5. **Print Label Button**
- Green button at bottom
- Triggers printing to selected printer
- Shows status notifications
### Right Column - Live Preview
- Shows exactly what will print
- Updates in real-time as you type
- Label dimensions: 11.5 cm × 8 cm
- Displays:
- Barcode (Code128 format)
- SAP number, quantity, and cable ID combined
- High quality 300 DPI rendering
## Workflow Example
1. **Start the application:**
```bash
python3 setup_and_run.py
```
2. **Enter data:**
- SAP-Nr: `A456789`
- Cantitate: `50`
- ID rola cablu: `REEL-042`
3. **Check preview** (automatically updates on right)
4. **Select printer** (use dropdown)
5. **Click PRINT LABEL** button
6. **Confirm** when notification appears
## Printer Setup
### Check Available Printers
```bash
lpstat -p -d
```
### Add a Printer (if needed)
```bash
# Use CUPS web interface
http://localhost:631
```
### Common Printer Names
- `PDF` - Virtual PDF printer (for testing)
- `Brother_HL_L2350DW` - Brother laser printer
- `Canon_PIXMA` - Canon printer
- Check your system for exact name
## Troubleshooting
### "No Printers Found"
```bash
# Start CUPS service
sudo systemctl start cups
# Check status
sudo systemctl status cups
# List printers
lpstat -p -d
```
### Preview Not Updating
- Check Python console for errors
- Verify all dependencies installed: `pip list | grep -E 'kivy|barcode|pillow'`
- Try restarting the application
### Print Fails
```bash
# Test print command manually
echo "test" | lp -d PDF
# Check printer status
lpstat -p -l
```
### Kivy Window Issues
- If window doesn't open, check X11 display:
```bash
echo $DISPLAY
```
- Resize window manually if elements overlap
## File Guide
- **label_printer_gui.py** - Main GUI application
- **print_label.py** - Core printing functions
- **setup_and_run.py** - Automatic setup script
- **start_gui.sh** - Bash launcher script
- **requirements_gui.txt** - Python dependencies
- **README_GUI.md** - Complete documentation
## Tips & Tricks
1. **Fast Printing:**
- Preset SAP number as most common value
- Just change quantity/ID for each label
2. **Batch Printing:**
- Print one label at a time
- Small UI makes it quick
3. **Testing:**
- Use "PDF" printer to save test labels
- Check output files to verify format
4. **Keyboard:**
- Tab between fields
- Enter in printer dropdown to confirm selection
- Alt+P might activate Print button (Kivy dependent)
## Next Steps
- **Learn More:** See [README_GUI.md](README_GUI.md)
- **Customize:** Modify `label_printer_gui.py` for your needs
- **Integrate:** Use functions in other Python applications
- **Support:** Check console output for detailed error messages
---
**Ready to print?** Start with: `python3 setup_and_run.py`

View File

@@ -1,307 +0,0 @@
# Label Printer GUI - Implementation Summary
## ✅ Completed Implementation
Your Label Printer GUI application has been successfully created with all requested features!
## 📋 Features Implemented
### ✓ Two-Column Layout
- **Left Column (40%):** Data entry form
- **Right Column (60%):** Real-time label preview
### ✓ Data Entry Fields (Left Column)
1. **SAP-Nr. Articol** - Text input for SAP article number
2. **Cantitate** - Numeric input for quantity
3. **ID rola cablu** - Text input for cable reel identifier
4. **Printer Selection** - Dropdown menu with CUPS printers
5. **Print Label Button** - Green button to trigger printing
### ✓ Live Preview (Right Column)
- Real-time preview of label as you type
- Label size: 11.5 cm × 8 cm (adjustable)
- Displays barcode + all three fields combined
- High-quality 300 DPI rendering
### ✓ Advanced Features
- **Dynamic Preview:** Updates instantly with each keystroke
- **Printer Detection:** Auto-detects all CUPS-installed printers
- **Non-blocking Printing:** Background threads prevent UI freezing
- **Error Handling:** User-friendly error messages
- **Status Notifications:** Popups confirm print success/failure
## 📁 Project Structure
```
/srv/Label-design/
├── print_label.py # Core printing engine (ORIGINAL)
├── label_printer_gui.py # Kivy GUI application (NEW)
├── setup_and_run.py # Python setup launcher (NEW)
├── start_gui.sh # Bash launcher script (NEW)
├── requirements_gui.txt # Kivy dependencies (NEW)
├── README_GUI.md # Full documentation (NEW)
├── GETTING_STARTED.md # Quick start guide (NEW)
├── TECHNICAL_DOCS.md # Technical reference (NEW)
├── requirements.txt # Original dependencies
└── how_to.txt # Original how-to guide
```
## 🚀 Quick Start
### Three Ways to Launch
**Option 1: Automatic Setup (Recommended)**
```bash
python3 setup_and_run.py
```
**Option 2: Bash Script**
```bash
chmod +x start_gui.sh
./start_gui.sh
```
**Option 3: Manual**
```bash
pip install -r requirements_gui.txt
python3 label_printer_gui.py
```
## 🎯 How It Works
### User Workflow
1. Enter SAP Number in first field
2. Enter Quantity (numbers only)
3. Enter Cable Reel ID
4. **Preview updates automatically** on the right
5. Select printer from dropdown
6. Click **PRINT LABEL** button
7. Receive confirmation message
### Technical Workflow
```
User Input
TextInput event → on_input_change()
Combine fields: "SAP|QTY|CABLE_ID"
create_label_image(text) from print_label.py
Generate barcode + render text
Display in preview widget
User clicks Print
Background thread: print_label_standalone()
Send to CUPS printer
Success/Error notification
```
## 💻 System Requirements
- **OS:** Linux/Unix with CUPS
- **Python:** 3.7 or higher
- **Display:** X11 or Wayland
- **Printer:** Any CUPS-configured printer (or PDF virtual printer)
## 📦 Dependencies
| Package | Purpose | Version |
|---------|---------|---------|
| kivy | GUI framework | 2.0+ |
| python-barcode | Barcode generation | Latest |
| pillow | Image processing | 8.0+ |
| pycups | CUPS printer interface | Latest |
## 🎨 UI Layout
```
┌────────────────────────────────────────────────────────────┐
│ Label Printer Interface (1600×900) │
├──────────────────┬─────────────────────────────────────────┤
│ │ │
│ INPUT COLUMN │ PREVIEW COLUMN │
│ (40% width) │ (60% width) │
│ │ │
│ ┌──────────────┐ │ ┌─────────────────────────────────┐ │
│ │ SAP-Nr. Artic│ │ │ Label Preview │ │
│ │ [text input] │ │ │ 11.5 cm × 8 cm │ │
│ ├──────────────┤ │ │ │ │
│ │ Cantitate │ │ │ ┌─────────────────────────────┐│ │
│ │ [0 input] │ │ │ │ ╔═══════════════════════╗ ││ │
│ ├──────────────┤ │ │ │ ║ [BARCODE] ║ ││ │
│ │ ID rola │ │ │ │ ║ SAP|QTY|CABLE_ID ║ ││ │
│ │ [text input] │ │ │ │ ╚═══════════════════════╝ ││ │
│ ├──────────────┤ │ │ └─────────────────────────────┘│ │
│ │ Printer: [PDF│ │ │ │ │
│ │ ▼] │ │ │ │ │
│ ├──────────────┤ │ │ │ │
│ │ [PRINT LABEL]│ │ └─────────────────────────────────┘ │
│ │ │ │ │
│ └──────────────┘ │ │
│ │ │
└──────────────────┴─────────────────────────────────────────┘
```
## 🔧 Customization
All aspects can be customized:
### UI Elements
- Window size
- Colors and fonts
- Field labels and types
- Button layout
### Label Format
- Label physical size
- Barcode type (currently Code128)
- Text positioning
- DPI/quality
### Data Fields
- Add/remove input fields
- Change field validation rules
- Modify data combination format
See `TECHNICAL_DOCS.md` for customization examples.
## 🐛 Troubleshooting
### Common Issues & Solutions
**"No printers found"**
```bash
sudo systemctl start cups
lpstat -p -d
```
**"Kivy window won't open"**
- Check X11 display: `echo $DISPLAY`
- Or use headless mode
**"Preview not updating"**
- Check Python console for errors
- Verify Pillow installed: `python3 -c "from PIL import Image"`
**"Print fails with permission error"**
- Add user to lpadmin group: `sudo usermod -aG lpadmin $USER`
## 📚 Documentation
- **GETTING_STARTED.md** - Quick start and workflow guide
- **README_GUI.md** - Full feature documentation
- **TECHNICAL_DOCS.md** - Architecture and development reference
- **print_label.py** - Inline code comments explaining functions
## 🎓 Learning Path
1. **Start:** Read `GETTING_STARTED.md`
2. **Use:** Run `python3 setup_and_run.py`
3. **Explore:** Open files in VS Code
4. **Customize:** Follow `TECHNICAL_DOCS.md`
5. **Integrate:** Use functions in your own code
## 🔌 Integration with Other Code
Use the printing function in your own Python applications:
```python
from print_label import print_label_standalone, create_label_image
# Just the barcode image (no printing)
image = create_label_image("YOUR_TEXT_HERE")
image.save("my_label.png")
# Print directly
success = print_label_standalone(
value="YOUR_TEXT",
printer="PDF",
preview=0
)
if success:
print("Printed successfully!")
```
## 📊 Key Files
| File | Purpose | Modified |
|------|---------|----------|
| label_printer_gui.py | Main GUI application | NEW |
| print_label.py | Printing engine | Updated (removed main code) |
| setup_and_run.py | Setup automation | NEW |
| start_gui.sh | Bash launcher | NEW |
| requirements_gui.txt | Kivy dependencies | NEW |
| README_GUI.md | Feature documentation | NEW |
| GETTING_STARTED.md | Quick start | NEW |
| TECHNICAL_DOCS.md | Developer reference | NEW |
## ✨ Special Features
1. **Real-time Preview**
- Instant visual feedback
- See exactly what will print
2. **Intelligent Printer Detection**
- Auto-detects CUPS printers
- Falls back to PDF if none found
3. **Non-blocking UI**
- Printing in background threads
- Never freezes the interface
4. **Professional Layout**
- Two-column responsive design
- Scales to any window size
5. **Data Persistence**
- Fields retain values
- Quick reprinting with modifications
## 🚦 Status
| Component | Status | Notes |
|-----------|--------|-------|
| GUI Framework | ✅ Complete | Kivy 2.0+ ready |
| Data Entry | ✅ Complete | All 3 fields + printer |
| Live Preview | ✅ Complete | Real-time updates |
| Printing | ✅ Complete | CUPS integration |
| Error Handling | ✅ Complete | User-friendly messages |
| Documentation | ✅ Complete | 3 documentation files |
| Setup Scripts | ✅ Complete | Python + Bash launchers |
## 🎉 You're Ready!
Everything is set up and ready to use. Start with:
```bash
python3 setup_and_run.py
```
## 📝 Notes
- Original `print_label.py` functionality fully preserved
- GUI adds modern interface without changing core logic
- Can be used independently or integrated with other systems
- Fully customizable for your needs
## 🆘 Support
1. Check **GETTING_STARTED.md** for quick help
2. See **TECHNICAL_DOCS.md** for detailed reference
3. Check console output for error details
4. Review inline code comments
---
**Created:** February 4, 2026
**Status:** Production Ready
**Version:** 1.0
**Fully Implemented:** ✅ All Requirements Met
**Enjoy your new Label Printer GUI!** 🎊

View File

@@ -1,415 +0,0 @@
# 🎉 Label Printer GUI - Complete Project Index
## Welcome! 👋
Your Label Printer GUI application is **complete and ready to use**!
---
## ⚡ Quick Start (60 seconds)
```bash
cd /srv/Label-design
python3 setup_and_run.py
```
That's it! The script will:
1. ✅ Check your system
2. ✅ Install dependencies
3. ✅ Launch the GUI
---
## 📖 Documentation Overview
### For First-Time Users 👶
Start with these in order:
1. **[GETTING_STARTED.md](GETTING_STARTED.md)** ⭐
- 15-minute quick start
- Screenshots of the interface
- Basic workflow
- Troubleshooting guide
2. **[README_GUI.md](README_GUI.md)**
- Complete feature list
- Detailed instructions
- Usage examples
- Common problems
### For Advanced Users 🚀
Dive deeper with these:
3. **[TECHNICAL_DOCS.md](TECHNICAL_DOCS.md)**
- Architecture overview
- Code structure
- Customization guide
- Integration examples
4. **[FILE_GUIDE.md](FILE_GUIDE.md)**
- File-by-file reference
- Project structure
- Quick lookup table
### Reference 📚
Quick lookups:
- **[IMPLEMENTATION_SUMMARY.md](IMPLEMENTATION_SUMMARY.md)** - What was built
- **[validate_project.py](validate_project.py)** - Check if everything is set up
---
## 🗂️ Project Files (13 files total)
### Application Code (3 files)
| File | Lines | Purpose |
|------|-------|---------|
| [label_printer_gui.py](label_printer_gui.py) | ~400 | Main Kivy GUI application ⭐ |
| [setup_and_run.py](setup_and_run.py) | ~100 | Python setup launcher |
| [start_gui.sh](start_gui.sh) | ~40 | Bash launcher script |
### Configuration (2 files)
| File | Purpose |
|------|---------|
| [requirements_gui.txt](requirements_gui.txt) | Python packages for GUI (new) |
| [requirements.txt](requirements.txt) | Python packages for printing (original) |
### Documentation (5 files)
| File | Target Audience | Read Time |
|------|-----------------|-----------|
| [GETTING_STARTED.md](GETTING_STARTED.md) | Everyone | 15 min ⭐ |
| [README_GUI.md](README_GUI.md) | Users | 30 min |
| [TECHNICAL_DOCS.md](TECHNICAL_DOCS.md) | Developers | 60 min |
| [FILE_GUIDE.md](FILE_GUIDE.md) | Developers | 10 min |
| [IMPLEMENTATION_SUMMARY.md](IMPLEMENTATION_SUMMARY.md) | Everyone | 15 min |
### Validation (1 file)
| File | Purpose |
|------|---------|
| [validate_project.py](validate_project.py) | Check if setup is complete |
### Original Files (2 files - preserved)
| File | Purpose |
|------|---------|
| [print_label.py](print_label.py) | Original printing engine |
| [how_to.txt](how_to.txt) | Original documentation |
---
## 🎯 What You Can Do
### ✅ Use the GUI
```bash
python3 setup_and_run.py
```
Beautiful interface to:
- Enter label data
- See live preview
- Select printer
- Print labels
### ✅ Use the API
```python
from print_label import print_label_standalone, create_label_image
# Create image
image = create_label_image("DATA_HERE")
image.save("label.png")
# Print directly
print_label_standalone("DATA", "PrinterName", preview=1)
```
### ✅ Customize Everything
- UI colors and layout
- Label size and format
- Data fields
- Printing behavior
### ✅ Integrate with Systems
- Use printing functions in your apps
- Call GUI programmatically
- Extend with new features
---
## 🚀 Getting Started Paths
### Path 1: Just Use It (5 minutes)
```
Setup → Run → Print → Done!
└─ python3 setup_and_run.py
```
### Path 2: Understand It (30 minutes)
```
Read GETTING_STARTED.md
Run setup_and_run.py
Use the GUI
Read README_GUI.md
```
### Path 3: Modify It (2 hours)
```
Read FILE_GUIDE.md
Read TECHNICAL_DOCS.md
Edit label_printer_gui.py
Test your changes
```
### Path 4: Integrate It (1 hour)
```
Read TECHNICAL_DOCS.md
Check integration examples
Import functions in your code
Use in your application
```
---
## 💡 Features at a Glance
| Feature | Details |
|---------|---------|
| **Data Entry** | 3 input fields + printer dropdown |
| **Live Preview** | Real-time label preview (11.5×8 cm) |
| **Barcode** | Code128 format, auto-generated |
| **Printing** | Direct to CUPS printers |
| **UI** | Two-column responsive layout |
| **Threading** | Background printing (non-blocking) |
| **Notifications** | Success/error popups |
| **Auto-Detection** | Finds installed printers automatically |
---
## 🔧 System Requirements
- **OS:** Linux/Unix with CUPS
- **Python:** 3.7 or higher
- **Display:** X11 or Wayland
- **Disk:** ~50MB (with dependencies)
- **RAM:** 2GB minimum
---
## 📦 Dependencies
Automatically installed by setup_and_run.py:
```
kivy - GUI framework
python-barcode - Barcode generation
pillow - Image processing
pycups - Printer interface
```
---
## ✅ Verification
Check if everything is working:
```bash
python3 validate_project.py
```
This will check:
- ✅ All files present
- ✅ Python version
- ✅ Dependencies installed
- ✅ CUPS available
- ✅ Printers configured
---
## 📞 Quick Troubleshooting
| Problem | Solution |
|---------|----------|
| Can't run GUI | `python3 setup_and_run.py` (installs deps) |
| No printers | `sudo systemctl start cups` |
| Python too old | Install Python 3.7+ |
| Dependencies fail | Check internet connection, retry |
| Window won't open | Check `echo $DISPLAY` |
See **[GETTING_STARTED.md](GETTING_STARTED.md#Troubleshooting)** for more help.
---
## 🎓 Learning Resources
### Quick Reference
- [FILE_GUIDE.md](FILE_GUIDE.md) - Find what you need
- Inline comments in [label_printer_gui.py](label_printer_gui.py)
### Step-by-Step Guides
- [GETTING_STARTED.md](GETTING_STARTED.md) - How to use
- [README_GUI.md](README_GUI.md) - Features explained
### In-Depth Knowledge
- [TECHNICAL_DOCS.md](TECHNICAL_DOCS.md) - Architecture & customization
- [print_label.py](print_label.py) - Printing engine code
---
## 🎯 Next Steps
### Immediate (now):
1. Run: `python3 setup_and_run.py`
2. Read: [GETTING_STARTED.md](GETTING_STARTED.md)
3. Print: Your first label
### Soon (today):
1. Explore all GUI features
2. Try different printers
3. Read: [README_GUI.md](README_GUI.md)
### Later (this week):
1. Customize colors/layout (if needed)
2. Read: [TECHNICAL_DOCS.md](TECHNICAL_DOCS.md)
3. Integrate with your systems
---
## 📊 Project Statistics
```
📁 Total Files: 13
├─ Code Files: 3 (GUI app + setup scripts)
├─ Config Files: 2 (dependencies)
├─ Documentation: 5 (guides)
└─ Other: 3 (validation + original)
💻 Total Code Lines: ~600
├─ GUI Application: ~400 lines
├─ Setup Scripts: ~140 lines
└─ Validation: ~60 lines
📚 Total Documentation: ~6,000 lines
├─ Technical Docs: ~2,500 lines
├─ README: ~600 lines
├─ Getting Started: ~400 lines
└─ Other guides: ~2,500 lines
⏱️ Time to First Print: 5-10 minutes
```
---
## 🎉 You're All Set!
Everything is ready to go. Choose your path:
### 🏃 Just Want to Start?
```bash
python3 setup_and_run.py
```
### 📖 Want to Learn First?
→ Read [GETTING_STARTED.md](GETTING_STARTED.md)
### 🔍 Want to Explore?
→ Check [FILE_GUIDE.md](FILE_GUIDE.md)
### 🔧 Want to Customize?
→ Read [TECHNICAL_DOCS.md](TECHNICAL_DOCS.md)
---
## 📝 Quick Reference Card
```
┌─────────────────────────────────────────────────┐
│ LABEL PRINTER GUI - QUICK REFERENCE │
├─────────────────────────────────────────────────┤
│ │
│ Start GUI: │
│ $ python3 setup_and_run.py │
│ │
│ Check Status: │
│ $ python3 validate_project.py │
│ │
│ Manual Start: │
│ $ python3 label_printer_gui.py │
│ │
│ First Read: │
│ → GETTING_STARTED.md │
│ │
│ File Reference: │
│ → FILE_GUIDE.md │
│ │
│ Full Docs: │
│ → README_GUI.md │
│ │
│ Technical Details: │
│ → TECHNICAL_DOCS.md │
│ │
└─────────────────────────────────────────────────┘
```
---
## 🏆 Implementation Status
| Component | Status | Notes |
|-----------|--------|-------|
| GUI Framework | ✅ Complete | Kivy 2.0+ |
| Data Entry Fields | ✅ Complete | 3 fields + printer |
| Live Preview | ✅ Complete | Real-time updates |
| Printing | ✅ Complete | CUPS integration |
| Barcode | ✅ Complete | Code128 format |
| Error Handling | ✅ Complete | User-friendly |
| Documentation | ✅ Complete | 5 guide files |
| Setup Automation | ✅ Complete | Python + Bash |
| All Requirements | ✅ Met | 100% complete |
---
## 👏 Summary
Your label printing application now has:
- ✅ Modern Kivy GUI interface
- ✅ Two-column responsive design
- ✅ Real-time barcode preview
- ✅ Automatic printer detection
- ✅ Non-blocking background printing
- ✅ Comprehensive documentation
- ✅ Easy setup and installation
- ✅ Complete code comments
- ✅ Ready for customization
- ✅ Production-ready quality
---
## 🚀 Ready to Print?
**Run this command and you're off:**
```bash
python3 setup_and_run.py
```
**That's it!** Enjoy your new Label Printer GUI! 🎊
---
**Version:** 1.0
**Status:** ✅ Production Ready
**Last Updated:** February 4, 2026
**All Requirements:** ✅ Implemented
Happy printing! 🖨️

View File

@@ -1,254 +0,0 @@
# PDF Label System - Final Optimization Summary
**Date:** February 5, 2026
**Status:****OPTIMIZED & PRODUCTION READY**
## Recent Improvements
### 1. Label Dimensions Corrected ✓
- **Previous:** 8.5 cm × 6 cm
- **Current:** 11.5 cm × 8 cm
- **Result:** Much larger working area for barcodes
### 2. Barcode Height Optimized ✓
- **Previous:** Variable, up to ~2.5 cm (row height - 8mm)
- **Current:** Fixed at 1.6 cm (optimal for scanners)
- **Range:** 1.5-1.8 cm recommended (1.6 cm is center)
- **Benefit:** Consistent, readable barcodes
### 3. Text Character Limit ✓
- **Enforcement:** Maximum 25 characters per field
- **Barcode Format:** Code128 (native limit: 25 characters)
- **Truncation:** Automatic, silent (doesn't break)
- **Result:** 100% barcode compatibility
### 4. Layout Improvements ✓
- **Margins:** Reduced to 3mm (was 5mm)
- **Usable Width:** Increased for barcode display
- **Centering:** Barcodes vertically centered in rows
- **Spacing:** Optimized for three-row layout
## Current Specifications
### Label Format
```
┌─────────────────────────────────┐
│ 11.5 cm × 8 cm (Full Label) │
│ │
│ ┌──────────────────────────────┐│
│ │ SAP-Nr [BARCODE] ││ 1.6 cm height
│ ├──────────────────────────────┤│
│ │ Cantitate [BARCODE] ││ 1.6 cm height
│ ├──────────────────────────────┤│
│ │ Lot Nr [BARCODE] ││ 1.6 cm height
│ └──────────────────────────────┘│
└─────────────────────────────────┘
```
### Technical Details
| Parameter | Value |
|-----------|-------|
| Label Width | 11.5 cm |
| Label Height | 8 cm |
| Rows | 3 (SAP-Nr, Cantitate, Lot Nr) |
| Barcode Height | 1.6 cm per row |
| Barcode Format | Code128 |
| Max Text Length | 25 characters |
| Margins | 3 mm all sides |
| DPI (Default) | 300 (print-quality) |
| File Format | PDF (vector-based) |
## Test Results
### Generated Test Cases
```
Test 1: Short values
Input: SAP-123 | 100 | LOT-ABC
Output: test_height_1.pdf (8.5 KB)
Status: ✓ PASS
Test 2: Medium values
Input: SAP-12345678901234567890 | 250 | LOT-XYZ123456789
Output: test_height_2.pdf (11.6 KB)
Status: ✓ PASS
Test 3: Long values (truncation test)
Input: VERYLONGSAPNUMBERTEST12345 | 999 | LOT-EXTENDED-TEST
Truncated: VERYLONGSAPNUMBERTEST1234 (25 chars)
Output: test_height_3.pdf (13.5 KB)
Status: ✓ PASS (automatic truncation)
```
### System Integration Test
```
Function: print_label_standalone("SAP-98765|Qty:500|LOT-FINAL", printer)
Generated: final_label_20260205_001351.pdf (10.1 KB)
Status: ✓ PASS
Specifications Applied:
✓ Correct dimensions (11.5 × 8 cm)
✓ Correct barcode height (1.6 cm)
✓ Text truncation (25 chars max)
✓ PDF format (high quality)
✓ Ready for printing
```
## Performance
| Operation | Time | Notes |
|-----------|------|-------|
| Single PDF generation | ~200-500ms | Per label |
| Batch processing (4 labels) | ~1.5s | Total time |
| Barcode generation | ~100-200ms | Per barcode |
| Text truncation | <1ms | Per field |
## Quality Improvements
### Barcode Readability
- ✓ Optimal height for scanners (1.6 cm)
- ✓ Consistent size across all rows
- ✓ Proper spacing within label
- ✓ No overflow or clipping
- ✓ 100% Code128 compatibility
### Label Layout
- ✓ Balanced three-row design
- ✓ Proper vertical centering
- ✓ Optimized horizontal spacing
- ✓ Clean, professional appearance
- ✓ Consistent formatting
### Text Handling
- ✓ Automatic truncation at 25 characters
- ✓ No barcode generation failures
- ✓ Graceful fallback to text display
- ✓ Clear visual separation
- ✓ Readable label names
## Backward Compatibility
| Feature | Status | Notes |
|---------|--------|-------|
| PNG fallback | ✓ Supported | `use_pdf=False` |
| Original API | ✓ Maintained | All functions work |
| Custom dimensions | ✓ Supported | Override defaults |
| High DPI mode | ✓ Supported | 600 DPI available |
| GUI integration | ✓ Working | Full compatibility |
## Usage Examples
### Basic Usage (Recommended)
```python
from print_label import print_label_standalone
# PDF format (default, recommended)
print_label_standalone("SAP-123|100|LOT-ABC", "printer_name")
```
### With Text Truncation Handling
```python
from print_label_pdf import PDFLabelGenerator
# Long text automatically truncates to 25 chars
generator = PDFLabelGenerator()
pdf = generator.create_label_pdf(
sap_nr="VERYLONGSAPNUMBER123456789", # Will truncate to 25 chars
cantitate="100",
lot_number="LOT-ABC",
filename="label.pdf"
)
```
### Custom Label Size
```python
# Create different label size
generator = PDFLabelGenerator(label_width=10, label_height=7, dpi=600)
pdf = generator.create_label_pdf(sap_nr, qty, lot, filename)
```
## Known Limitations
| Limitation | Details | Workaround |
|-----------|---------|-----------|
| Text Length | Max 25 chars | Truncates automatically |
| Barcode Types | Code128 only | Covers 95% of use cases |
| Rows | 3 fixed | Meets all current needs |
| DPI | 300 default | Change via constructor |
## Deployment Checklist
- [x] Barcode height optimized (1.6 cm)
- [x] Label dimensions corrected (11.5 × 8 cm)
- [x] Text truncation implemented (25 chars)
- [x] All tests passing (✓ 100%)
- [x] GUI integration verified
- [x] PDF quality verified
- [x] Backward compatibility maintained
- [x] Documentation updated
- [x] Performance validated
- [x] Error handling tested
## Recommendations for Users
1. **Always use PDF format** - Superior quality and smaller files
2. **Test with your printer** - Verify barcode scanning
3. **Use standard text** - Keep values under 25 characters
4. **Archive PDFs** - Much smaller than PNG backups
5. **Monitor first batch** - Ensure everything scans properly
## File Manifest
**Core Files:**
- `print_label_pdf.py` - PDF generation engine
- `print_label.py` - Printing interface
- `label_printer_gui.py` - GUI application
**Documentation:**
- `PDF_UPGRADE_GUIDE.md` - Full documentation
- `QUICK_START.md` - Quick reference
- `TEST_RESULTS_PDF_SYSTEM.md` - Test results
**Demo:**
- `demo_pdf_system.py` - Comprehensive demo
## Support & Troubleshooting
### Barcode Not Scanning
1. Check text length (should be ≤ 25 characters)
2. Verify printer supports PDF format
3. Ensure 300 DPI minimum for barcodes
4. Test with known barcode scanner
### Text Truncation
1. This is automatic and intentional
2. Values over 25 characters are silently truncated
3. Fallback to text display if barcode fails
4. Check console output for details
### Label Overflow
1. Labels will now fit within 11.5 × 8 cm
2. Barcodes limited to 1.6 cm height
3. Text auto-truncates at 25 characters
4. Should not overflow in normal use
## Next Steps
1. **Deploy to production** - All optimizations complete
2. **Update printer settings** - Verify PDF support
3. **Test with actual printer** - First batch verification
4. **Train users** - Document new specifications
5. **Monitor usage** - Collect feedback
---
## Summary
The PDF label generation system is now **fully optimized** with:
- ✓ Correct label dimensions (11.5 × 8 cm)
- ✓ Optimal barcode height (1.6 cm)
- ✓ Automatic text truncation (25 chars max)
- ✓ Professional quality output
- ✓ 100% production ready
**Status: APPROVED FOR PRODUCTION DEPLOYMENT**

View File

@@ -1,179 +0,0 @@
# PDF Label Generation System - Upgrade Guide
## Overview
The label printing system has been upgraded from PNG-based printing to **high-quality PDF generation**. This provides significantly better print quality, sharper barcodes, and professional results.
## Key Improvements
### 1. **Vector-Based PDF Generation**
- **Before**: PNG rasterization at 300 DPI (blurry when zoomed)
- **After**: PDF with vector graphics and embedded barcodes (sharp at any scale)
- Result: Professional print quality with crisp barcodes and text
### 2. **Better Barcode Rendering**
- PDF format preserves barcode quality for reliable scanning
- 300 DPI barcode generation ensures readability
- Proper spacing and quiet zones maintained
### 3. **Improved Printing Pipeline**
- Files are retained with timestamps for easy reference
- Better error handling and fallback support
- Both PDF and PNG formats supported (backward compatible)
## New Files
### `print_label_pdf.py`
High-quality PDF label generator using ReportLab library.
**Key Classes:**
- `PDFLabelGenerator`: Main class for PDF generation
- `__init__(label_width=8.5, label_height=6, dpi=300)`: Initialize with custom dimensions
- `create_label_pdf()`: Generate PDF bytes or file
- `generate_barcode_image()`: Create high-quality barcodes
**Functions:**
- `create_label_pdf_simple(text)`: Simple wrapper for PDF generation
- `create_label_pdf_file(text, filename)`: Generate PDF file with auto-naming
## Updated Files
### `print_label.py`
Enhanced with PDF support while maintaining backward compatibility.
**New Functions:**
- `create_label_pdf(text)`: Create high-quality PDF labels
**Updated Functions:**
- `print_label_standalone(value, printer, preview=0, use_pdf=True)`
- New parameter: `use_pdf` (default: True)
- Set `use_pdf=False` to use PNG format
### `label_printer_gui.py`
Updated Kivy GUI to use PDF by default.
**Changes:**
- Preview now shows "High-quality PDF format for printing" indicator
- Print button uses PDF generation by default
- Success message mentions superior PDF quality
- Updated imports for PDF module
## Installation
### Install New Dependencies
```bash
pip install reportlab
```
Or install all requirements:
```bash
pip install -r requirements_gui.txt
```
## Usage
### Using the GUI
1. Launch the application as usual
2. Enter SAP number, Quantity, and Lot ID
3. Select printer
4. Click "PRINT LABEL"
5. PDF is automatically generated and sent to printer
### Programmatic Usage
**Using PDF (Recommended):**
```python
from print_label import print_label_standalone
# Generate and print PDF (default)
print_label_standalone("SAP123|100|LOT456", "printer_name")
# With preview
print_label_standalone("SAP123|100|LOT456", "printer_name", preview=1, use_pdf=True)
```
**Using PNG (Backward Compatible):**
```python
from print_label import print_label_standalone
print_label_standalone("SAP123|100|LOT456", "printer_name", use_pdf=False)
```
**Direct PDF Generation:**
```python
from print_label import create_label_pdf
# Create PDF file
pdf_file = create_label_pdf("SAP123|100|LOT456")
print(f"Generated: {pdf_file}")
```
## Quality Comparison
| Aspect | PNG | PDF |
|--------|-----|-----|
| **Print Quality** | Rasterized, may blur | Vector, always sharp |
| **Barcode Reliability** | Fair | Excellent |
| **File Size** | ~50-100 KB | ~20-40 KB |
| **Scalability** | Fixed resolution | Infinite |
| **Color Accuracy** | Good | Excellent |
## Technical Details
### PDF Dimensions
- Label Size: 11.5 cm × 8 cm (3 rows × 1 column layout)
- DPI: 300 (print-ready)
- Margins: 3 mm on all sides
### Barcode Specifications
- Format: Code128
- Height: 1.6 cm per row (optimized for 1.5-1.8 cm range)
- Maximum text length: 25 characters (Code128 limitation)
- Module Width: Auto-scaled for row width
- Quiet Zone: 2 modules
## Troubleshooting
### PDF Not Printing
1. Check printer CUPS configuration
2. Verify PDF viewer support on printer
3. Check PDF file was created: `ls -lh label_*.pdf`
### Barcode Quality Issues
1. Check printer resolution (300 DPI recommended minimum)
2. Verify printer supports PDF format
3. Ensure proper barcode values (max 25 characters)
### Font Issues
1. System uses DejaVu fonts by default
2. Fallback to default fonts if not available
3. PDF embeds font metrics automatically
## Performance
- PDF generation: ~200-500ms per label
- Print queue submission: ~100ms
- Total time: Similar to PNG but with superior quality
## Backward Compatibility
The system is fully backward compatible:
- Old PNG files still work
- Can switch between PDF and PNG with `use_pdf` parameter
- All existing code continues to function
## Future Enhancements
Potential improvements for future versions:
- Custom label sizes and layouts
- Multi-label per page support
- Batch printing with optimization
- Advanced barcode types (QR, EAN, etc.)
- Label preview in PDF format
## Support
For issues or questions:
1. Check the error messages in console output
2. Verify all dependencies are installed
3. Ensure printer is properly configured in CUPS
4. Check file permissions in working directory

View File

@@ -1,246 +0,0 @@
# Label Printing System - Quick Reference Card
## System Specifications ✓
| Parameter | Value | Notes |
|-----------|-------|-------|
| **Label Width** | 11.5 cm | Full width |
| **Label Height** | 8 cm | Full height |
| **Rows** | 3 | SAP-Nr, Cantitate, Lot Nr |
| **Barcode Height** | 18 mm (1.8 cm) | Fixed, optimal for scanning |
| **Barcode Format** | Code128 | Standard barcode format |
| **Character Limit** | 25 chars max | Per field |
| **DPI** | 300 | Print-ready quality |
| **File Format** | PDF | Vector-based, professional |
| **Margin** | 3 mm | All sides |
## Quick Start
### 1. Activate Environment
```bash
cd /srv/Label-design
source venv/bin/activate
```
### 2. Run GUI
```bash
python label_printer_gui.py
```
### 3. Enter Data
- SAP-Nr: Up to 25 characters
- Cantitate: Up to 25 characters
- Lot Nr: Up to 25 characters
- Select Printer
### 4. Print
- Click "PRINT LABEL"
- PDF generates automatically
- Sends to printer
## Command Line Usage
```bash
# Generate PDF label
python3 -c "from print_label import print_label_standalone; \
print_label_standalone('SAP-123|100|LOT-ABC', 'printer_name')"
# Generate without printing (test)
python3 -c "from print_label import create_label_pdf; \
pdf = create_label_pdf('SAP-123|100|LOT-ABC'); \
print(f'Generated: {pdf}')"
```
## Label Data Format
```
Input Format: "SAP|CANTITATE|LOT"
Example: "SAP-12345|100|LOT-ABC"
└─────┬─────┘ └──┬──┘ └──┬──┘
SAP-Nr Qty Lot Nr
Each becomes a barcode row in the PDF
```
## Barcode Specifications
| Aspect | Specification | Details |
|--------|---------------|---------|
| **Type** | Code128 | Standard barcode |
| **Height** | 18 mm | Fixed (1.8 cm) |
| **Width** | Auto | Fits within label |
| **Module Width** | 0.5 mm | Bar thickness |
| **Quiet Zone** | 2 mm | Auto-applied |
| **Max Length** | 25 chars | Auto-truncates |
## File Locations
```
/srv/Label-design/
├── label_printer_gui.py ← GUI application
├── print_label.py ← Main module (PDF/PNG)
├── print_label_pdf.py ← PDF generation engine
├── requirements_gui.txt ← Dependencies
└── venv/ ← Virtual environment
```
## Generated Files
Labels are saved with timestamps:
```
final_label_20260205_001617.pdf
└─────────┬─────────┘
YYYYMMDD_HHMMSS
```
Files are retained in working directory for reprinting.
## Troubleshooting
### PDF Won't Generate
```bash
# Check dependencies
pip list | grep reportlab
# Reinstall if needed
pip install reportlab
```
### Barcode Won't Scan
- Verify printer DPI (300+ required)
- Check label dimensions (11.5cm × 8cm)
- Use "Borderless" printing
- Test with standard scanner
### Text Gets Cut Off
- Max 25 characters per field
- Longer text auto-truncates
- Check for special characters
### File Not Found
```bash
# Verify virtual environment is active
which python
# Should show: /srv/Label-design/venv/bin/python
```
## Printer Setup (CUPS)
### View Available Printers
```bash
lpstat -p -d
```
### Configure Printer Size
```bash
# Open CUPS web interface
http://localhost:631
```
### Test Print
```bash
python3 -c "from print_label import print_label_standalone; \
print_label_standalone('TEST|123|ABC', 'your_printer_name', use_pdf=True)"
```
## Documentation
- **Full Guide:** `PDF_UPGRADE_GUIDE.md`
- **Setup Guide:** `QUICK_START.md`
- **Barcode Details:** `BARCODE_HEIGHT_CORRECTION.md`
- **Test Results:** `TEST_RESULTS_PDF_SYSTEM.md`
## API Summary
### Simple Function
```python
from print_label import print_label_standalone
print_label_standalone(text, printer, use_pdf=True)
```
### PDF Generation
```python
from print_label import create_label_pdf
pdf_file = create_label_pdf("SAP|QTY|LOT")
```
### Advanced (Custom Size)
```python
from print_label_pdf import PDFLabelGenerator
gen = PDFLabelGenerator(label_width=11.5, label_height=8)
pdf = gen.create_label_pdf("SAP", "QTY", "LOT", "output.pdf")
```
## Performance
| Task | Time |
|------|------|
| Single label PDF | 200-500ms |
| Single label PNG | 300-600ms |
| Batch (4 labels) | ~1.5 sec |
| Print submission | ~100ms |
## Quality Levels
### Standard (300 DPI)
- Good for most applications
- Barcode easily scannable
- Default setting
### High Quality (600 DPI)
```python
gen = PDFLabelGenerator(dpi=600)
```
- Premium color reproduction
- Extra-high barcode precision
## Common Issues & Solutions
| Issue | Cause | Solution |
|-------|-------|----------|
| Barcode too small | Old config | Update to v2.0+ |
| Text cut off | >25 chars | Values auto-truncate |
| PDF won't print | Printer config | Check CUPS settings |
| Module not found | Missing venv | Run `source venv/bin/activate` |
| No barcodes | Generation error | Falls back to text |
## Environment Variables (Optional)
```bash
# Set default printer
export CUPS_DEFAULT_PRINTER="your_printer"
# Set temporary directory
export TMPDIR="/tmp/labels"
```
## Support Resources
1. **Error Messages** - Check console output
2. **GUI Issues** - Verify Kivy installation
3. **Print Issues** - Check CUPS configuration
4. **Barcode Issues** - Test with standard scanner
## System Requirements
- **Python:** 3.10+
- **OS:** Linux (CUPS required)
- **Printer:** Any CUPS-compatible printer
- **Display:** For GUI (optional, can run headless)
## Version Info
- **System Version:** 2.0 (PDF-based)
- **Release Date:** February 5, 2026
- **Status:** ✓ Production Ready
---
**Quick Notes:**
- Always activate venv before running
- Label size is 11.5cm × 8cm (fixed)
- Barcode height 18mm (fixed)
- Max 25 characters per field (auto-truncates)
- PDF format for best quality
- Use CUPS for printing

View File

@@ -1,226 +0,0 @@
# Quick Start Guide - PDF Label Printing System
## Installation & Setup
### 1. Activate Virtual Environment
```bash
cd /srv/Label-design
source venv/bin/activate
```
### 2. Install Dependencies (One-time)
```bash
pip install -r requirements_gui.txt
```
Or manually:
```bash
pip install python-barcode pillow pycups kivy reportlab
```
## Running the Application
### GUI Application (Recommended for Users)
```bash
source venv/bin/activate
python label_printer_gui.py
```
The GUI will open with:
- Input fields for SAP number, quantity, and lot ID
- Real-time label preview
- Printer selection dropdown
- Print button for easy printing
### Command Line (For Scripts/Integration)
```bash
source venv/bin/activate
python3 -c "from print_label import print_label_standalone; print_label_standalone('SAP-123|100|LOT-456', 'printer_name')"
```
## Using the System
### Basic PDF Label Generation
```python
from print_label import create_label_pdf
# Generate PDF file
pdf_file = create_label_pdf("SAP-123|100|LOT-456")
print(f"Created: {pdf_file}")
```
### Print to Printer
```python
from print_label import print_label_standalone
# PDF (recommended - highest quality)
print_label_standalone("SAP-123|100|LOT-456", "printer_name", use_pdf=True)
# PNG (fallback)
print_label_standalone("SAP-123|100|LOT-456", "printer_name", use_pdf=False)
```
### Advanced: Custom Label Size
```python
from print_label_pdf import PDFLabelGenerator
# Create 6cm × 4cm labels at 600 DPI
generator = PDFLabelGenerator(label_width=6, label_height=4, dpi=600)
pdf = generator.create_label_pdf(
sap_nr="SAP-123",
cantitate="100",
lot_number="LOT-456",
filename="custom_label.pdf"
)
```
## Key Features
### PDF Generation (Default)
- **Quality:** Professional vector-based format
- **File Size:** ~1.7 KB per label (91% smaller than PNG)
- **Scalability:** Works at any print resolution
- **Speed:** 200-500ms per label
- **Barcodes:** Sharp, reliable Code128 barcodes
### PNG Format (Fallback)
- **Quality:** Rasterized at 300 DPI
- **Compatibility:** Works with older systems
- **File Size:** ~19 KB per label
- **Use Case:** Legacy printer support
## Finding Printer Name
To see available printers:
```bash
# Using CUPS
lpstat -p -d
# Or in Python
import cups
conn = cups.Connection()
printers = conn.getPrinters()
for name in printers.keys():
print(name)
```
## Generated Files
Labels are saved with timestamps:
- `final_label_20260205_000537.pdf` (timestamp format)
- Files are retained in current directory
- Easy to retrieve for reprinting
## Format Options
### Text Format: "SAP|QUANTITY|LOT"
```
"SAP-12345|100|LOT-ABC123"
↓ ↓ ↓
SAP-Nr Cantitate Lot Nr
```
Each part becomes a barcode + label row in the output.
## Troubleshooting
### "No module named reportlab"
```bash
source venv/bin/activate
pip install reportlab
```
### "No such file or directory" (printer error)
This is normal - it means the printer doesn't exist.
Create a valid printer in CUPS first:
```bash
# Configure printer in CUPS web interface
http://localhost:631
```
### GUI Won't Start
Make sure display is available:
```bash
# Check if X11 is running
echo $DISPLAY
```
### Barcode Not Showing
The system falls back to text if barcode generation fails.
Make sure:
- Value is under 25 characters
- Text contains valid barcode characters
- System has write access to temp directory
## Testing
Run the comprehensive demo:
```bash
source venv/bin/activate
python demo_pdf_system.py
```
This tests:
- Basic PDF generation
- Custom dimensions
- Batch processing
- High DPI support
- PNG fallback
- API usage examples
## File Structure
```
/srv/Label-design/
├── label_printer_gui.py # GUI Application
├── print_label.py # Main printing module (updated with PDF support)
├── print_label_pdf.py # PDF generation engine
├── demo_pdf_system.py # Comprehensive demo
├── requirements.txt # Base dependencies
├── requirements_gui.txt # GUI dependencies
├── PDF_UPGRADE_GUIDE.md # Full documentation
├── TEST_RESULTS_PDF_SYSTEM.md # Test results
├── QUICK_START.md # This file
└── venv/ # Virtual environment
```
## Performance
| Task | Time | Notes |
|------|------|-------|
| Single PDF generation | 200-500ms | Per label |
| Single PNG generation | 300-600ms | Legacy |
| Batch (4 labels) | ~1.5 seconds | PDF format |
| Print submission | ~100ms | To CUPS |
## Tips & Best Practices
1. **Use PDF by default** - Better quality, smaller files
2. **Keep PNG option** - For backward compatibility
3. **Use 300 DPI** - Standard for barcode scanning
4. **Archive PDFs** - Smaller file sizes = less storage
5. **Test printer** - Verify PDF support before large runs
## Support Resources
- **Full Documentation:** See `PDF_UPGRADE_GUIDE.md`
- **Test Results:** See `TEST_RESULTS_PDF_SYSTEM.md`
- **Demo Code:** Run `demo_pdf_system.py`
- **Code Examples:** Look at function docstrings
## Environment Variables
Optional environment customization:
```bash
# Set default printer
export CUPS_DEFAULT_PRINTER="your_printer_name"
# Set temp directory for label files
export TMPDIR="/path/to/temp"
```
---
**Status:** ✓ Production Ready
**Last Updated:** February 5, 2026
**Version:** 2.0 (PDF-based)

View File

@@ -1,168 +0,0 @@
# Label Printer GUI Application
A modern Kivy-based graphical interface for printing labels with barcodes, featuring real-time preview and printer selection.
## Features
**Two-Column Layout**
- Left: Data entry form with input fields
- Right: Real-time label preview
**Input Fields**
- SAP-Nr. Articol (SAP Number/Article)
- Cantitate (Quantity)
- ID rola cablu (Cable Reel ID)
**Live Preview**
- Real-time preview of label as you type
- Label size: 11.5 cm × 8 cm
- Shows barcode and all entered information
**Printer Management**
- Dropdown to select from available system printers
- Automatic detection of installed CUPS printers
**Printing**
- Direct printing to selected printer
- Background printing with status notifications
- Error handling and user feedback
## Installation
### Prerequisites
- Python 3.7 or higher
- CUPS (Common Unix Printing System) - usually pre-installed on Linux
- System printer configured and installed
### Setup Steps
1. **Install dependencies:**
```bash
pip install -r requirements_gui.txt
```
2. **Install Kivy garden dependencies** (if using matplotlib preview):
```bash
garden install matplotlib
```
3. **Ensure system printer is configured:**
```bash
# Check available printers
lpstat -p -d
# Or using CUPS web interface
# Open: http://localhost:631
```
## Usage
### Run the GUI Application
```bash
python label_printer_gui.py
```
### Operation
1. **Enter Label Data:**
- Type the SAP Number in the first field
- Enter the quantity (numbers only)
- Enter the Cable Reel ID
2. **Monitor Preview:**
- The preview updates automatically as you type
- Shows combined barcode with all entered data
3. **Select Printer:**
- Use the dropdown to select your target printer
- Default is "PDF" if no other printers available
4. **Print:**
- Click "PRINT LABEL" button
- Wait for confirmation message
- Label will print to selected printer
## Label Format
The label contains:
- **Row 1:** SAP Number | Quantity | Cable ID (combined in barcode)
- **Barcode:** Code128 format encoding the combined information
- **Size:** 11.5 cm width × 8 cm height
- **DPI:** 300 DPI for high-quality printing
## File Structure
```
/srv/Label-design/
├── print_label.py # Core printing functions
├── label_printer_gui.py # Kivy GUI application
├── requirements.txt # Original dependencies
├── requirements_gui.txt # GUI-specific dependencies
└── how_to.txt # Original documentation
```
## Troubleshooting
### No printers detected
- Check CUPS service: `sudo systemctl status cups`
- List printers: `lpstat -p`
- Restart CUPS if needed: `sudo systemctl restart cups`
### Preview not updating
- Ensure all input fields are properly connected
- Check console for error messages
- Verify PIL/Pillow installation: `python -c "from PIL import Image; print('OK')"`
### Print fails
- Verify printer name is correct
- Check printer status: `lpstat -p -d`
- Test direct print: `echo "test" | lp -d printername`
- Ensure CUPS daemon is running
### Kivy window sizing issues
- The app defaults to 1600×900 window
- Can be resized freely after launch
- Modify `Window.size = (1600, 900)` in code to change default
## Code Integration
To integrate the printing function into other applications:
```python
from print_label import print_label_standalone
# Print a label
success = print_label_standalone(
value="YOUR_TEXT",
printer="printername",
preview=0 # 0=no preview, 1-3=3s preview, >3=5s preview
)
```
## Requirements
- **kivy**: GUI framework
- **python-barcode**: Barcode generation
- **pillow**: Image processing
- **pycups**: CUPS printer interface
- **matplotlib**: (Optional) For advanced visualization
## License
Based on the existing print_label.py printing framework.
## Notes
- All data is combined into a single barcode for easy scanning
- Labels are printed at 300 DPI for sharp quality
- Temporary files are cleaned up automatically
- Printing happens in background threads to prevent UI blocking
## Support
For issues or questions, check:
1. Console output for error messages
2. CUPS printer configuration
3. System printer availability
4. Required dependencies installation

View File

@@ -1,251 +0,0 @@
# PDF Label Layout - Simplified & Fixed
**Date:** February 5, 2026
**Status:****FIXED AND TESTED**
## Changes Made
### 1. **Removed All Borders** ✓
- No rectangle borders around rows
- No visual boxes/frames
- Clean, minimal layout
### 2. **Simplified Layout** ✓
- Field names at top of each row (small text)
- Barcodes below field names
- Empty space around for clean appearance
- More usable space for barcodes
### 3. **Fixed Barcode Height** ✓
- Height: 18mm (1.8cm) - FIXED
- Properly displayed and readable
- No longer cut off or too small
### 4. **Character Limit Enforced** ✓
- Maximum 25 characters per field
- Automatic truncation
- No barcode generation errors
## Layout Structure
```
┌─ Label (11.5cm × 8cm) ─┐
│ │
│ SAP-Nr (small text) │
│ [ BARCODE ] │ 18mm height
│ │
│ Cantitate (small text) │
│ [ BARCODE ] │ 18mm height
│ │
│ Lot Nr (small text) │
│ [ BARCODE ] │ 18mm height
│ │
└────────────────────────┘
```
## PDF Specifications
| Parameter | Value | Notes |
|-----------|-------|-------|
| Label Width | 11.5 cm | Full width |
| Label Height | 8 cm | Full height |
| Barcode Height | 18 mm | Fixed, professional |
| Barcode Width | Auto | Fits within label |
| Margin | 3 mm | Minimal |
| Rows | 3 | SAP-Nr, Cantitate, Lot Nr |
| Border | None | Removed for clean look |
| Format | Code128 | Standard barcode |
| DPI | 300 | Print-ready |
## Field Layout
```
Row 1: SAP-Nr
- Field name: 8pt Helvetica-Bold
- Barcode: 18mm height
- Width: Auto-fit to label
Row 2: Cantitate
- Field name: 8pt Helvetica-Bold
- Barcode: 18mm height
- Width: Auto-fit to label
Row 3: Lot Nr
- Field name: 8pt Helvetica-Bold
- Barcode: 18mm height
- Width: Auto-fit to label
```
## File Changes
### print_label_pdf.py - RECREATED
- Removed all border drawing code
- Simplified row layout
- Fixed barcode height at 18mm
- Clean implementation
- No duplicate code
### print_label.py - NO CHANGES
- Still works with updated PDF module
- Backward compatible
- PNG fallback still available
### label_printer_gui.py - NO CHANGES
- Imports work correctly
- GUI functions unchanged
- Benefits from improved PDF layout
## Testing Results ✓
```
Test 1: Basic Label
Input: "SAP-ABC123|Qty:500|LOT-2024-XYZ"
Result: ✓ PDF generated (1,635 bytes)
Barcode Height: ✓ 18mm visible
Borders: ✓ None (clean layout)
Test 2: Truncation
Input: "VERY-LONG-SAP-NUMBER-LONGER|Qty|LOT"
Result: ✓ Auto-truncated to 25 chars
Barcode: ✓ Generated successfully
Test 3: GUI Integration
Result: ✓ All imports successful
Status: ✓ Ready to use
```
## Benefits of Simplified Layout
1. **Cleaner Appearance**
- No boxes or borders
- Professional look
- More space for content
2. **Better Barcode Visibility**
- More horizontal space
- No crowding
- Easier to scan
3. **Simpler Code**
- Fewer drawing operations
- Faster generation
- Less error-prone
4. **More Flexible**
- Easy to adjust spacing
- Easy to modify fonts
- Easier to extend
## Technical Details
### Barcode Generation
```python
barcode_height = 18 mm # Fixed
barcode_width = auto # Constrained to label width
barcode_format = Code128
character_limit = 25
```
### PDF Creation
```python
page_size = 11.5cm × 8cm
rows = 3
row_height = ~2.67cm each
margin = 3mm
```
### Field Names
```python
Font: Helvetica-Bold
Size: 8pt
Position: Top of each row
```
## Usage
### Command Line
```bash
python -c "from print_label import print_label_standalone; \
print_label_standalone('SAP-123|100|LOT-ABC', 'printer_name')"
```
### Python Script
```python
from print_label import create_label_pdf
pdf_file = create_label_pdf("SAP-123|100|LOT-ABC")
print(f"Generated: {pdf_file}")
```
### GUI Application
```bash
python label_printer_gui.py
# Enter data and click Print
```
## Barcode Quality
- **Format:** Code128 (professional standard)
- **Height:** 18mm (easily scannable)
- **Width:** Auto-fit to label (no overflow)
- **Module Width:** 0.5mm (optimal for 300 DPI)
- **Quiet Zone:** 2mm (maintained automatically)
## Performance
| Metric | Value |
|--------|-------|
| PDF Generation | 200-500ms |
| File Size | ~1.6 KB |
| Barcode Height | 18mm ✓ |
| Character Limit | 25 chars ✓ |
| Layout Simplicity | High ✓ |
## Verification Checklist
- [x] PDF generation works
- [x] No borders in layout
- [x] Barcode height is 18mm
- [x] Fields display correctly
- [x] Character limit enforced
- [x] GUI imports successfully
- [x] All tests passed
- [x] System is production-ready
## Print Settings Recommended
- **Printer DPI:** 300+
- **Paper Size:** 11.5cm × 8cm (custom)
- **Margins:** Borderless if available
- **Color Mode:** Monochrome/Black & White
- **Quality:** Best available
## Troubleshooting
### Barcode Not Visible
- Check printer DPI (300+ required)
- Verify PDF viewer supports images
- Try borderless printing mode
### Text Overlapping
- This shouldn't happen (simplified layout)
- Check if fields are too long (truncate to 25 chars)
### PDF Won't Print
- Check CUPS configuration
- Verify printer supports PDF
- Check printer connection
## Summary
The label printing system now has:
- ✓ Simplified, clean layout (no borders)
- ✓ Fixed 18mm barcode height
- ✓ 25-character limit per field
- ✓ 11.5cm × 8cm label size
- ✓ 300 DPI print quality
- ✓ Professional appearance
**Status:****PRODUCTION READY**
All tests passed. System is ready for deployment and use.

View File

@@ -1,390 +0,0 @@
# Technical Documentation - Label Printer GUI
## Architecture Overview
### Component Structure
```
label_printer_gui.py
├── LabelPreviewWidget (ScatterLayout)
│ ├── update_preview(text)
│ ├── display_preview()
│ └── Displays PIL image as Kivy widget
└── LabelPrinterApp (App)
├── build() → Main UI layout
├── create_input_column() → Left side form
├── create_preview_column() → Right side preview
├── get_available_printers() → CUPS integration
├── on_input_change() → Live preview update
├── print_label() → Print workflow
└── show_popup() → User notifications
```
### Data Flow
```
User Input (TextInput)
on_input_change() event
Combine fields: f"{sap}|{qty}|{cable_id}"
create_label_image() from print_label.py
LabelPreviewWidget.update_preview()
Display in right column
```
## Class Details
### LabelPreviewWidget
**Purpose:** Display real-time label preview
**Methods:**
- `update_preview(text)` - Create new label image from text
- `display_preview()` - Render image in Kivy widget
**Attributes:**
- `label_image` - Current PIL Image object
- `temp_preview_path` - Temporary PNG file path
**Key Features:**
- Uses PIL to generate labels at 300 DPI
- Displays in KivyImage widget
- Maintains aspect ratio (11.5cm × 8cm)
- Auto-updates on input change
### LabelPrinterApp
**Purpose:** Main application orchestrator
**Methods:**
| Method | Purpose |
|--------|---------|
| `build()` | Construct main UI layout |
| `create_input_column()` | Build left form panel |
| `create_preview_column()` | Build right preview panel |
| `get_available_printers()` | Fetch CUPS printer list |
| `on_input_change()` | Handle input updates |
| `print_label()` | Execute print workflow |
| `show_popup()` | Display notifications |
**Event Flow:**
1. **Initialization:**
```
__init__() → get_available_printers()
→ build()
→ create_input_column()
→ create_preview_column()
```
2. **User Interaction:**
```
TextInput.on_text → on_input_change()
→ preview_widget.update_preview()
```
3. **Printing:**
```
Button.on_press → print_label()
→ threading.Thread(print_thread)
→ print_label_standalone()
→ show_popup()
```
## Integration with print_label.py
### Functions Used
```python
from print_label import create_label_image, print_label_standalone
```
**create_label_image(text)**
- Input: Combined text (e.g., "SAP123|50|REEL001")
- Output: PIL Image (11.5cm × 8cm @ 300 DPI)
- Generates Code128 barcode
- Centers text below barcode
**print_label_standalone(value, printer, preview)**
- Input:
- `value`: Text to encode in barcode
- `printer`: CUPS printer name (e.g., "PDF")
- `preview`: 0=no preview, 1-3=3s, >3=5s
- Output: Boolean (True=success)
- Handles CUPS printing
- Manages temporary files
## UI Layout Structure
### Main Layout
```
BoxLayout (horizontal)
├── Left Column (40%)
│ BoxLayout (vertical)
│ ├── Title Label
│ ├── ScrollView
│ │ └── GridLayout (1 col)
│ │ ├── Label: "SAP-Nr. Articol"
│ │ ├── TextInput (sap_input)
│ │ ├── Label: "Cantitate"
│ │ ├── TextInput (qty_input)
│ │ ├── Label: "ID rola cablu"
│ │ ├── TextInput (cable_id_input)
│ │ ├── Label: "Select Printer"
│ │ └── Spinner (printer_spinner)
│ └── Button: "PRINT LABEL"
└── Right Column (60%)
BoxLayout (vertical)
├── Title Label
└── LabelPreviewWidget
```
### Styling
**Colors:**
- Print Button: `(0.2, 0.6, 0.2, 1)` - Green
- Background: Default Kivy theme
- Text: Black on white/gray
**Fonts:**
- Title: 18sp, bold
- Labels: 14sp, regular
- Input: 16sp, regular
**Sizing:**
- Window: 1600×900 (adjustable)
- Left column: 40% of width
- Right column: 60% of width
## Threading Model
### Background Printing
```python
def print_label(self, instance):
# ... validation ...
popup = Popup(...) # Show loading
popup.open()
def print_thread():
try:
success = print_label_standalone(...)
# Update UI in main thread
popup.dismiss()
self.show_popup(...)
except Exception as e:
# Error handling
self.show_popup("Error", str(e))
thread = threading.Thread(target=print_thread)
thread.daemon = True
thread.start()
```
**Why threading?**
- Prevents UI freezing during print
- CUPS operations can be slow
- User can continue working while printing
## Error Handling
### Validation
1. **Input Validation:**
```python
if not sap_nr and not quantity and not cable_id:
show_popup("Error", "Please enter at least one field")
```
2. **Printer Validation:**
- Fallback to "PDF" if none available
- Checks printer existence before print
3. **Exception Handling:**
- Try-except in preview generation
- Try-except in print thread
- User-friendly error messages
### Logging
- Console output for debugging
- Error messages in popups
- Exception info in thread callbacks
## Performance Considerations
### Preview Updates
- Only regenerates label when text changes
- Debouncing happens naturally via Kivy events
- PIL image operations are fast (~100ms)
### Memory Management
- Temporary files auto-deleted
- PIL images cached during preview
- Temp preview file cleaned when updated
### CUPS Operations
- Non-blocking via threading
- Timeout handling for printer ops
- Connection pooled by pycups
## Customization Guide
### Change Label Size
In `print_label.py`:
```python
# Modify label dimensions
label_width = 1063 # pixels for 9cm @ 300 DPI
label_height = 591 # pixels for 5cm @ 300 DPI
```
For 11.5cm × 8cm @ 300 DPI:
```python
label_width = 1378 # 11.5cm @ 300 DPI
label_height = 944 # 8cm @ 300 DPI
```
### Modify UI Colors
In `label_printer_gui.py`:
```python
# Change print button color
Button(
...
background_color=(R, G, B, A), # RGBA: 0.0-1.0
...
)
```
### Add New Input Fields
```python
# In create_input_column():
new_label = Label(text='New Field:', size_hint_y=None, height=40)
form_layout.add_widget(new_label)
self.new_input = TextInput(...)
self.new_input.bind(text=self.on_input_change)
form_layout.add_widget(self.new_input)
# In on_input_change():
new_field = self.new_input.text
```
## Dependencies Deep Dive
### Kivy
- **Version:** 2.0+
- **Role:** GUI framework
- **Key classes:** App, BoxLayout, TextInput, Button, Spinner
### python-barcode
- **Version:** Latest
- **Role:** Code128 barcode generation
- **Integration:** Used in print_label.py
### Pillow (PIL)
- **Version:** 8.0+
- **Role:** Image generation and processing
- **Features:** ImageDraw for text, Image for resizing
### pycups
- **Version:** Latest
- **Role:** CUPS printer interface
- **Functions:** getPrinters(), printFile()
## Testing
### Unit Test Example
```python
def test_label_preview_update():
app = LabelPrinterApp()
test_text = "TEST|123|REEL"
app.preview_widget.update_preview(test_text)
assert app.preview_widget.label_image is not None
def test_printer_list():
app = LabelPrinterApp()
printers = app.get_available_printers()
assert isinstance(printers, list)
assert len(printers) > 0
```
### Manual Testing
1. **Preview Update Test:**
- Type in each field
- Verify preview updates
- Check barcode changes
2. **Printer Test:**
- Select different printers
- Verify dropdown updates
3. **Print Test:**
- Use PDF printer for testing
- Check output file generated
## Deployment Notes
### System Requirements
- Linux/Unix (CUPS-based)
- X11 or Wayland display
- ~50MB disk space
- 2GB RAM minimum
### Installation Steps
1. Clone/download repository
2. Install Python 3.7+
3. Run setup_and_run.py
4. Configure system printer
### Containerization
For Docker deployment:
```dockerfile
FROM python:3.9-slim
RUN apt-get update && apt-get install -y cups
COPY . /app
WORKDIR /app
RUN pip install -r requirements_gui.txt
CMD ["python3", "label_printer_gui.py"]
```
## Future Enhancements
1. **Database Integration**
- Store label history
- Batch printing from CSV
2. **Label Templates**
- Multiple label formats
- Custom field layouts
3. **Advanced Features**
- QR code support
- Image/logo inclusion
- Multi-language support
4. **Mobile Integration**
- REST API server
- Web interface
---
**Last Updated:** February 4, 2026
**Version:** 1.0
**Status:** Production Ready

View File

@@ -1,199 +0,0 @@
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ LABEL PRINTER APPLICATION - TEST SUMMARY ║
║ ║
╚══════════════════════════════════════════════════════════════════════════════╝
DATE: February 4, 2026
STATUS: ✅ ALL CORE FUNCTIONALITY WORKING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TEST RESULTS SUMMARY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Functional Tests (test_functional.py):
✅ TEST 1: Module Imports [PASS]
✅ TEST 2: Label Image Generation [PASS]
✅ TEST 3: Printer Detection [PASS]
✅ TEST 4: Save Label to File [PASS]
✅ TEST 5: Data Format Testing [PASS]
RESULT: 5/5 tests PASSED ✅
Demonstration Tests (demo_usage.py):
✅ DEMO 1: Create Label Image [PASS]
✅ DEMO 2: Print Label (Simulated) [PASS]
✅ DEMO 3: Create Multiple Labels [PASS]
RESULT: All demonstrations successful ✅
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
COMPONENT STATUS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Core Printing Engine:
✅ Label image generation
✅ Barcode generation (Code128)
✅ Image file output (PNG)
✅ Data formatting and combining
✅ Error handling and validation
✅ File I/O operations
✅ Temporary file cleanup
CUPS Integration:
✅ Printer detection
✅ Printer listing
✅ Print file operations
⚠️ No printers configured (PDF available for testing)
GUI Application:
✅ Code implementation complete
✅ All layouts and widgets defined
✅ Event handling functional
✅ Preview system implemented
⚠️ Graphics display issue (system-level, not code issue)
API Functions:
✅ create_label_image() - Working
✅ print_label_standalone() - Working
✅ Integration-ready
✅ Well-documented
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ISSUES FOUND & RESOLVED
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Issue 1: Tkinter Not Available ❌ → ✅ FIXED
Problem: print_label.py imported ImageTk/tkinter
Solution: Removed GUI framework dependency
Result: Application now works without tkinter
Issue 2: Graphics Driver Problems ⚠️ → DOCUMENTED
Problem: Kivy GUI crashes on this system
Cause: System-level graphics driver issue
Status: Not an application issue, expected on headless systems
Solution: Deploy on systems with proper X11/graphics support
Workaround: Use API functions directly
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
WHAT WORKS ✅
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Creating Labels:
✅ Single labels
✅ Batch labels
✅ Complex data formatting
✅ Long strings
✅ Special characters
Printing:
✅ CUPS integration
✅ Printer detection
✅ File generation
✅ Error handling
API Usage:
✅ Import modules
✅ Generate images
✅ Save files
✅ Integration with other apps
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
VERIFICATION COMMANDS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Run these commands to verify:
# Test all functionality
$ python3 test_functional.py
# Run functional demo
$ python3 demo_usage.py
# Validate project
$ python3 validate_project.py
# Check git status
$ git log --oneline -3
Expected Results:
✅ test_functional.py: 5/5 tests PASS
✅ demo_usage.py: All demos complete successfully
✅ validate_project.py: All files present
✅ git: Latest commits visible
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DEPLOYMENT READINESS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
API/Headless Mode: ✅ READY
Use: print_label_standalone() and create_label_image()
Status: Fully tested and functional
Command-Line Mode: ✅ READY
Use: Python scripts or CLI wrapper
Status: Fully tested and functional
GUI Mode: ✅ CODE READY
Use: label_printer_gui.py
Status: Code complete, needs compatible display system
Deployment: Ready for systems with graphics support
Production: ✅ READY
Status: All core components tested and verified
Requirements: Hardware printer, display (GUI), or headless usage
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
USAGE EXAMPLES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Python API Usage
from print_label import create_label_image, print_label_standalone
# Generate label
image = create_label_image("SAP123|50|REEL001")
image.save("my_label.png")
# Print to printer
success = print_label_standalone(
value="SAP123|50|REEL001",
printer="PDF",
preview=0
)
# Command-line test
python3 -c "
from print_label import create_label_image
img = create_label_image('TEST|100|REEL')
img.save('output.png')
print('Label created: output.png')
"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CONCLUSION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ ALL TESTS PASSED
✅ CORE FUNCTIONALITY VERIFIED
✅ READY FOR PRODUCTION
The Label Printer application is fully functional and ready for deployment.
All core printing, label generation, and data processing features are working.
The GUI requires a system with proper graphics support, but the underlying
API is production-ready for immediate use.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Test Date: February 4, 2026
Repository: https://gitea.moto-adv.com/ske087/label_printer.git
Status: ✅ PRODUCTION READY

View File

@@ -1,271 +0,0 @@
# Testing Report - Label Printer Application
**Date:** February 4, 2026
**Status:****FULLY FUNCTIONAL**
---
## Executive Summary
The Label Printer application has been **successfully implemented and tested**. All core functionality is operational and ready for production use.
### Test Results
| Component | Status | Notes |
|-----------|--------|-------|
| Module Imports | ✅ PASS | All dependencies available |
| Label Generation | ✅ PASS | Barcode creation working |
| Image File Output | ✅ PASS | PNG files generated correctly |
| Data Formatting | ✅ PASS | Multiple data formats supported |
| Printer Detection | ✅ PASS | CUPS integration functional |
| **GUI Application** | ⚠️ LIMITED | Graphics driver issues on this system |
| **API Functions** | ✅ PASS | Ready for integration |
---
## Test Results Details
### ✅ Test 1: Module Imports
```
✓ PIL - Image processing
✓ barcode - Barcode generation
✓ cups - Printer interface
✓ print_label - Label printing module
```
**Result:** All modules import successfully
### ✅ Test 2: Label Image Generation
```
✓ Generated label for: 'SAP123' - Size: (1063, 591)
✓ Generated label for: 'SAP456|100' - Size: (1063, 591)
✓ Generated label for: 'SAP789|50|REEL001' - Size: (1063, 591)
```
**Result:** Label generation working at any data complexity
### ✅ Test 3: Printer Detection
```
⚠ No printers configured (will use PDF)
```
**Result:** CUPS integration ready, PDF printer available for testing
### ✅ Test 4: Save Label to File
```
✓ Label saved successfully
- File: /tmp/tmpvkuc_fzh.png
- Size: 15,769 bytes
- Cleaned up temporary file
```
**Result:** File I/O operations working correctly
### ✅ Test 5: Data Format Testing
```
✓ SAP only - OK
✓ SAP + Quantity - OK
✓ SAP + Quantity + Cable ID - OK
✓ Complex format - OK
✓ Long string - OK
```
**Result:** All data format combinations supported
### ⚠️ GUI Test (Graphics Issue)
**Finding:** The Kivy GUI requires X11/graphics drivers that are not properly configured on this system. This is a **system-level graphics driver issue**, not an application issue.
**Status:** GUI code is correct and ready for deployment on systems with proper graphics support.
---
## Fixes Applied During Testing
### 1. Removed Tkinter Dependency ✅
- **Issue:** Original `print_label.py` imported `tkinter` which was not available
- **Solution:** Removed `ImageTk` and `tkinter` imports
- **Result:** Application now works without GUI framework dependencies
### 2. Simplified Preview Function ✅
- **Issue:** Preview required Tkinter windows
- **Solution:** Replaced with command-line countdown timer
- **Result:** Preview functionality works in headless/CLI mode
### 3. Fixed Import Statements ✅
- **Issue:** Unused tkinter imports were breaking functionality
- **Solution:** Removed all tkinter references
- **Result:** Clean imports, no dependency conflicts
---
## What Works ✅
### Core Printing Functions
```python
# Create label image
from print_label import create_label_image
image = create_label_image("SAP123|50|REEL001")
image.save("my_label.png")
# Print to printer
from print_label import print_label_standalone
success = print_label_standalone(
value="SAP123|50|REEL001",
printer="PDF",
preview=0
)
```
### Features Tested & Working
- ✅ Barcode generation (Code128 format)
- ✅ Label image creation (1063×591 pixels @ 300 DPI)
- ✅ Data combining (SAP|QTY|CABLE_ID)
- ✅ File output (PNG format)
- ✅ Printer detection (CUPS integration)
- ✅ Multiple label batches
- ✅ Error handling
- ✅ File cleanup
### Data Formats Supported
- ✅ Simple text: `"DATA"`
- ✅ SAP + Quantity: `"SAP123|50"`
- ✅ Full format: `"SAP123|50|REEL001"`
- ✅ Complex values: `"SPEC-123|999|CABLE-X"`
- ✅ Long strings: Multi-character barcodes
---
## What Needs System Configuration ⚠️
### GUI Application
- **Status:** Code is correct, ready to deploy
- **Limitation:** This specific system has graphics driver issues
- **Solution:**
- Deploy on system with proper X11/graphics drivers
- Or use the Python API directly (recommended)
- Or access GUI remotely via X11 forwarding
### Printer Configuration
- **Status:** CUPS integration ready
- **Current:** PDF printer available for testing
- **Next:** Configure actual hardware printer on this system
---
## System Information
```
OS: Linux
Python: 3.13.5
Kivy: 2.3.1
Pillow: 12.1.0
python-barcode: Latest
pycups: Latest
Display: :1 (Available)
Disk Status: Root full, /srv has 194GB free
```
---
## Files Created for Testing
| File | Purpose |
|------|---------|
| `test_functional.py` | Comprehensive functional tests (5/5 PASS) |
| `test_gui_simple.py` | Simple GUI component test |
| `demo_usage.py` | Functional demonstration |
---
## Recommended Usage
### For Immediate Use (API)
```bash
python3 -c "
from print_label import create_label_image
image = create_label_image('TEST|100|REEL')
image.save('label.png')
print('Label created: label.png')
"
```
### For GUI Use
Deploy on a system with graphics support:
```bash
python3 label_printer_gui.py
```
### For Integration
```python
from print_label import create_label_image, print_label_standalone
# Generate
image = create_label_image(data)
# Print
success = print_label_standalone(data, printer_name, preview=0)
```
---
## Test Commands
Run these to verify functionality:
```bash
# All tests (5/5 should pass)
python3 test_functional.py
# Functional demo
python3 demo_usage.py
# Check validation
python3 validate_project.py
```
---
## Known Issues & Solutions
| Issue | Status | Solution |
|-------|--------|----------|
| GUI crashes on this system | ⚠️ EXPECTED | Graphics driver issue, not code issue |
| Root disk full | ⚠️ KNOWN | Use /srv or other partition |
| No printers configured | EXPECTED | Configure system printer for production |
| Tkinter missing | ✅ FIXED | Removed dependency |
---
## Deployment Checklist
- [x] Code implemented
- [x] Core functionality tested
- [x] Dependencies installed
- [x] Printing API verified
- [x] Label generation verified
- [x] Error handling tested
- [ ] Graphics driver fixed (requires system admin)
- [ ] Production printer configured (requires hardware setup)
- [ ] GUI deployed to compatible system
---
## Conclusion
**✅ The Label Printer application is fully functional and ready for production use.**
### Status Summary
- **Core functionality:** ✅ 100% operational
- **Testing:** ✅ 5/5 tests pass
- **API:** ✅ Ready for integration
- **GUI:** ✅ Code ready, awaiting compatible display system
- **Documentation:** ✅ Comprehensive
- **Code quality:** ✅ Production-ready
### Next Steps
1. Deploy on system with graphics support for GUI
2. Configure production printer
3. Integrate API into applications as needed
4. Monitor and maintain
---
**Test Date:** February 4, 2026
**Tested By:** Automated Test Suite
**Approval Status:** ✅ READY FOR PRODUCTION

View File

@@ -1,231 +0,0 @@
# PDF Label Generation System - Test Results
**Date:** February 5, 2026
**Status:****ALL TESTS PASSED**
## Environment Setup
```
Python Version: 3.13.5
Virtual Environment: /srv/Label-design/venv
```
### Installed Packages
- ✓ python-barcode 0.16.1
- ✓ pillow 12.1.0
- ✓ pycups 2.0.4
- ✓ kivy 2.3.1
- ✓ reportlab 4.4.9 (newly installed)
## Test Results
### 1. Basic PDF Generation ✓
```
Test: create_label_pdf("TEST-SAP|100|LOT123")
Result: Generated final_label_20260205_000537.pdf
Size: 8.2 KB
Status: ✓ PASS
```
### 2. PNG Fallback Format ✓
```
Test: print_label_standalone(..., use_pdf=False)
Result: Generated final_label.png (19 KB)
Status: ✓ PASS
```
### 3. PDF Format (Recommended) ✓
```
Test: print_label_standalone(..., use_pdf=True)
Result: Generated final_label_20260205_000543.pdf (9 KB)
Status: ✓ PASS
```
### 4. File Size Comparison ✓
| Format | Size | Notes |
|--------|------|-------|
| PNG | 18,669 bytes | Legacy/Fallback |
| PDF | 1,678 bytes | **91% smaller** |
### 5. Batch Processing ✓
```
Test: Generated 4 labels in batch
Results:
- demo_batch_label_01.pdf
- demo_batch_label_02.pdf
- demo_batch_label_03.pdf
- demo_batch_label_04.pdf
Total Size: 6,713 bytes
Status: ✓ PASS
```
### 6. Custom Dimensions ✓
```
Test: PDFLabelGenerator(label_width=6, label_height=4, dpi=300)
Result: Generated demo_label_custom.pdf (1.7 KB)
Status: ✓ PASS
```
### 7. High DPI Printing ✓
```
Test: PDFLabelGenerator(..., dpi=600)
Result: Generated demo_label_600dpi.pdf (1.7 KB)
Status: ✓ PASS
Recommended for: Color-critical and high-volume production
```
### 8. GUI Integration ✓
```
Test: from label_printer_gui import LabelPrinterApp
Result: All imports successful
GUI Framework: Kivy 2.3.1
OpenGL: 4.6 (Mesa Intel Iris Xe Graphics)
Status: ✓ PASS
```
### 9. Backward Compatibility ✓
- ✓ PNG format still works with use_pdf=False
- ✓ Original create_label_image() function intact
- ✓ All existing code paths supported
### 10. Error Handling ✓
- ✓ Graceful barcode generation failures (fallback to text)
- ✓ Printer not found handled gracefully
- ✓ Files retained for fallback usage
## Feature Testing
### PDF Generation Features
- ✓ Multiple label rows with barcodes
- ✓ Customizable dimensions (width, height)
- ✓ Adjustable DPI (300, 600, custom)
- ✓ Barcode encoding (Code128)
- ✓ Fallback text rendering
- ✓ File naming with timestamps
### Printing Features
- ✓ CUPS integration
- ✓ Preview mode support
- ✓ Format selection (PDF/PNG)
- ✓ Graceful error handling
- ✓ File persistence
### GUI Features
- ✓ Input fields for SAP number, quantity, lot ID
- ✓ Real-time preview generation
- ✓ Printer selection dropdown
- ✓ Status messages and popups
- ✓ Threading for non-blocking operations
## Performance Metrics
| Operation | Time | Notes |
|-----------|------|-------|
| PDF Generation | ~200-500ms | Per label |
| PNG Generation | ~300-600ms | Legacy format |
| Batch (4 labels) | ~1.5s | Total time |
| File I/O | ~100ms | Average |
## Quality Improvements
### Before (PNG)
- Rasterized format
- Fixed resolution (300 DPI)
- File size: 18.7 KB per label
- Barcode quality: Good (acceptable)
### After (PDF)
- Vector-based format
- Infinite scalability
- File size: 1.7 KB per label
- Barcode quality: Excellent (professional)
- **91% smaller files**
- **Better print reliability**
## Generated Test Files
The following test files were generated and verified:
- `final_label_20260205_000524.pdf` (1.7 KB)
- `final_label_20260205_000537.pdf` (8.2 KB)
- `final_label_20260205_000543.pdf` (9.0 KB)
- `final_label.png` (19 KB)
All files successfully generated and verified.
## Comprehensive Test Suite
Run the included demo to verify all functionality:
```bash
cd /srv/Label-design
. venv/bin/activate
python demo_pdf_system.py
```
This demo includes:
1. Basic PDF generation
2. Custom dimensions
3. Batch processing
4. High DPI support
5. API usage examples
6. PNG vs PDF comparison
## Compatibility Summary
| Component | Status | Notes |
|-----------|--------|-------|
| Python 3.13 | ✓ | Fully compatible |
| ReportLab | ✓ | Installed successfully |
| Barcode Library | ✓ | Works with fallback |
| Kivy GUI | ✓ | All imports successful |
| CUPS Printing | ✓ | Properly integrated |
| File System | ✓ | Proper persistence |
## System Ready for Production
### ✓ Requirements Met
- [x] PDF generation implemented
- [x] High-quality barcode rendering
- [x] Improved print quality
- [x] Backward compatibility maintained
- [x] All dependencies installed
- [x] Full test coverage
- [x] Error handling robust
- [x] GUI fully functional
### Next Steps
1. **Deploy to production** - All tests pass
2. **Train users** on PDF benefits (91% smaller, better quality)
3. **Monitor** first few printing jobs
4. **Document** any printer-specific settings needed
## Recommendations
1. **Use PDF by default** - Superior quality and smaller files
2. **Keep PNG option** - For legacy systems if needed
3. **Monitor printer settings** - Ensure printer supports PDF correctly
4. **Use 300 DPI** - Standard for barcode printing (default)
5. **Archive labels** - PDFs are smaller, easier to archive
## Test Coverage
- Unit tests: ✓ 10/10 passed
- Integration tests: ✓ 5/5 passed
- GUI tests: ✓ 8/8 passed
- Performance tests: ✓ 3/3 passed
- Compatibility tests: ✓ 4/4 passed
**Overall Score: 100% ✓**
---
## Conclusion
The PDF-based label generation system is **fully functional**, **production-ready**, and provides **significant improvements** over the previous PNG-based system:
- **91% file size reduction** (18.7 KB → 1.7 KB)
- **Professional print quality** (vector vs rasterized)
- **Reliable barcode scanning** (precise spacing/quiet zones)
- **Backward compatible** (PNG still supported)
- **Easy to use** (same API with optional parameters)
**Status: APPROVED FOR PRODUCTION**

View File

@@ -1,114 +0,0 @@
# Label Printer GUI - Windows Setup Guide
## Installation Steps
### 1. Install Python
- Download Python 3.11+ from [python.org](https://www.python.org/downloads/)
- **Important**: Check "Add Python to PATH" during installation
### 2. Create Virtual Environment
```bash
python -m venv venv
venv\Scripts\activate
```
### 3. Install Dependencies
```bash
pip install -r requirements_windows.txt
```
### 4. Optional: Windows Printer Support (pywin32)
After installing requirements, run:
```bash
python -m pip install --upgrade pywin32
python Scripts/pywin32_postinstall.py -install
```
This enables native Windows printer detection.
## Running the App
### From Command Prompt
```bash
venv\Scripts\activate
python label_printer_gui.py
```
### Create Shortcut (Optional)
Create a batch file `run_app.bat`:
```batch
@echo off
call venv\Scripts\activate.bat
python label_printer_gui.py
pause
```
Then double-click the batch file to run the app.
## Features
**Cross-Platform GUI** - Works on Windows, Linux, and macOS
**Barcode Generation** - Automatic Code128 barcode creation
**PDF Output** - High-quality PDF labels stored in `pdf_backup/` folder
**Printer Support** - Automatic printer detection (Windows, Linux, macOS)
**Input Validation** - 25-character limit with real-time validation
**PDF Backup** - All generated labels automatically saved
## Printer Setup
### Windows
1. Go to Settings → Devices → Printers & Scanners
2. Add your label printer
3. Run the app - printer will be auto-detected
4. Select printer from dropdown
### Alternative (No Printer)
- Select "PDF" option
- Labels will be saved to `pdf_backup/` folder
- Open and print from any PDF viewer
## Troubleshooting
### "No Printers Found"
- This is normal - select "PDF" option
- You can print PDFs manually from the backup folder
- Or install your printer driver
### Windows Defender Warning
- Click "More info" → "Run anyway"
- This is safe - the app is open-source
### Missing Dependencies
```bash
pip install --upgrade pip
pip install -r requirements_windows.txt
```
### Port Already in Use
If you get an error about ports, restart your computer or:
```bash
python -m pip uninstall -y pywin32
python -m pip install pywin32
```
## File Structure
```
Label-design/
├── label_printer_gui.py # Main GUI application
├── print_label.py # Print functionality
├── print_label_pdf.py # PDF generation
├── requirements_windows.txt # Windows dependencies
├── pdf_backup/ # Stored PDF labels
├── venv/ # Virtual environment
└── documentation/ # Documentation files
```
## Tips
- **Character Limit**: Each field supports up to 25 characters (barcode limit)
- **Quantity Field**: Only numbers allowed
- **PDF Backup**: All labels automatically saved with timestamp
- **Cross-Platform**: Same code runs on Windows, Linux, and macOS
For more information, see the documentation folder.

View File

@@ -1,237 +0,0 @@
#!/usr/bin/env python3
"""
Demo: PDF Label Generation System
Shows how to use the new PDF-based label printing system
"""
import os
import sys
# Add current directory to path
sys.path.insert(0, os.path.dirname(__file__))
from print_label_pdf import PDFLabelGenerator, create_label_pdf_file
from print_label import print_label_standalone, create_label_pdf
def demo_basic_pdf_generation():
"""Demo 1: Basic PDF generation"""
print("=" * 60)
print("DEMO 1: Basic PDF Label Generation")
print("=" * 60)
# Create a simple label
pdf_file = create_label_pdf_file(
text="SAP-12345|Qty:100|LOT-ABC",
filename="demo_label_basic.pdf"
)
print(f"✓ Generated: {pdf_file}")
print(f"✓ File size: {os.path.getsize(pdf_file)} bytes")
print()
def demo_custom_dimensions():
"""Demo 2: Custom label dimensions"""
print("=" * 60)
print("DEMO 2: Custom Label Dimensions")
print("=" * 60)
# Create generator with custom size (smaller label)
generator = PDFLabelGenerator(label_width=6, label_height=4, dpi=300)
pdf_file = generator.create_label_pdf(
sap_nr="SAP-67890",
cantitate="Qty:250",
lot_number="LOT-XYZ",
filename="demo_label_custom.pdf"
)
print(f"✓ Custom 6cm × 4cm label generated")
print(f"✓ File: {pdf_file}")
print(f"✓ File size: {os.path.getsize(pdf_file)} bytes")
print()
def demo_batch_generation():
"""Demo 3: Batch label generation"""
print("=" * 60)
print("DEMO 3: Batch Label Generation")
print("=" * 60)
labels_data = [
("SAP-001", "Qty:100", "LOT-A"),
("SAP-002", "Qty:200", "LOT-B"),
("SAP-003", "Qty:300", "LOT-C"),
("SAP-004", "Qty:150", "LOT-D"),
]
generator = PDFLabelGenerator()
generated_files = []
for idx, (sap, qty, lot) in enumerate(labels_data, 1):
pdf_file = generator.create_label_pdf(
sap_nr=sap,
cantitate=qty,
lot_number=lot,
filename=f"demo_batch_label_{idx:02d}.pdf"
)
generated_files.append(pdf_file)
print(f" [{idx}] Generated {pdf_file}")
total_size = sum(os.path.getsize(f) for f in generated_files)
print(f"\n✓ Total: {len(generated_files)} labels generated")
print(f"✓ Combined size: {total_size} bytes")
print()
def demo_high_dpi():
"""Demo 4: High DPI for ultra-quality printing"""
print("=" * 60)
print("DEMO 4: High DPI Generation (600 DPI)")
print("=" * 60)
# Create generator with higher DPI for premium printing
generator = PDFLabelGenerator(label_width=8.5, label_height=6, dpi=600)
pdf_file = generator.create_label_pdf(
sap_nr="SAP-PREMIUM",
cantitate="Qty:500",
lot_number="LOT-PREMIUM",
filename="demo_label_600dpi.pdf"
)
print(f"✓ 600 DPI Ultra-quality label generated")
print(f"✓ File: {pdf_file}")
print(f"✓ File size: {os.path.getsize(pdf_file)} bytes")
print(f"✓ Use this for color-critical or high-volume production")
print()
def demo_api_usage():
"""Demo 5: Using the convenience API"""
print("=" * 60)
print("DEMO 5: Convenience API Usage")
print("=" * 60)
# Method 1: Simple function
print("Method 1: Using print_label_standalone()")
print(" Usage: print_label_standalone(text, printer, preview=0, use_pdf=True)")
print()
# Method 2: Direct PDF creation
print("Method 2: Using create_label_pdf()")
pdf_file = create_label_pdf("SAP-TEST|Qty:999|LOT-TEST")
print(f" ✓ Generated: {pdf_file}")
print()
# Method 3: Generator class
print("Method 3: Using PDFLabelGenerator class")
print(" Usage:")
print(" generator = PDFLabelGenerator()")
print(" pdf = generator.create_label_pdf(sap_nr, qty, lot, filename)")
print()
def demo_comparison():
"""Demo 6: PNG vs PDF comparison"""
print("=" * 60)
print("DEMO 6: PNG vs PDF Comparison")
print("=" * 60)
from print_label import create_label_image
# Generate PNG
png_img = create_label_image("SAP-CMP|Qty:100|LOT-CMP")
png_file = "demo_comparison_png.png"
png_img.save(png_file)
png_size = os.path.getsize(png_file)
# Generate PDF
pdf_file = create_label_pdf_file("SAP-CMP|Qty:100|LOT-CMP", "demo_comparison_pdf.pdf")
pdf_size = os.path.getsize(pdf_file)
print("File Size Comparison:")
print(f" PNG: {png_size:,} bytes")
print(f" PDF: {pdf_size:,} bytes")
print(f" Savings: {png_size - pdf_size:,} bytes ({((png_size-pdf_size)/png_size)*100:.1f}%)")
print()
print("Quality Comparison:")
print(" PNG: Rasterized, fixed resolution")
print(" PDF: Vector-based, infinite scalability")
print()
print("Recommended Use:")
print(" ✓ Use PDF for production printing (recommended)")
print(" ✓ Use PNG for legacy systems or special cases")
print()
def cleanup_demo_files():
"""Clean up generated demo files"""
print("=" * 60)
print("Cleaning up demo files...")
print("=" * 60)
demo_files = [
"demo_label_basic.pdf",
"demo_label_custom.pdf",
"demo_batch_label_01.pdf",
"demo_batch_label_02.pdf",
"demo_batch_label_03.pdf",
"demo_batch_label_04.pdf",
"demo_label_600dpi.pdf",
"demo_comparison_png.png",
"demo_comparison_pdf.pdf",
]
for filename in demo_files:
if os.path.exists(filename):
os.remove(filename)
print(f" ✓ Removed {filename}")
print("\n✓ Cleanup complete")
print()
if __name__ == "__main__":
print("\n")
print("" + "" * 58 + "")
print("" + " " * 58 + "")
print("" + " PDF Label Generation System - Comprehensive Demo".center(58) + "")
print("" + " " * 58 + "")
print("" + "" * 58 + "")
print("\n")
try:
# Run all demos
demo_basic_pdf_generation()
demo_custom_dimensions()
demo_batch_generation()
demo_high_dpi()
demo_api_usage()
demo_comparison()
# Ask about cleanup
print("\nDo you want to clean up demo files? (y/n): ", end="")
# For automated testing, auto-cleanup
cleanup_demo_files()
print("\n" + "=" * 60)
print("✓ All demos completed successfully!")
print("=" * 60)
print("\nKey Takeaways:")
print(" 1. PDF generation is the recommended format for printing")
print(" 2. Supports custom dimensions and DPI settings")
print(" 3. File sizes are comparable to PNG with better quality")
print(" 4. Batch processing is simple and efficient")
print(" 5. Full backward compatibility with PNG option")
print("\nFor more information, see PDF_UPGRADE_GUIDE.md")
print()
except Exception as e:
print(f"\n❌ Error during demo: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

View File

@@ -1,153 +0,0 @@
#!/usr/bin/env python3
"""
Label Printer - Quick Functional Test & Printing Demo
Demonstrates printing without GUI
"""
from print_label import create_label_image, print_label_standalone
import os
def demo_create_label():
"""Demo: Create a label image"""
print("\n" + "=" * 70)
print("DEMO 1: Create Label Image")
print("=" * 70)
# Example data
sap_nr = "A456789"
quantity = "50"
cable_id = "REEL-042"
# Combine data
label_data = f"{sap_nr}|{quantity}|{cable_id}"
print(f"\nLabel Information:")
print(f" SAP-Nr. Articol: {sap_nr}")
print(f" Cantitate: {quantity}")
print(f" ID rola cablu: {cable_id}")
print(f"\nCombined data: {label_data}")
# Create label
print("\nGenerating label...")
image = create_label_image(label_data)
# Save label
output_file = "demo_label.png"
image.save(output_file)
file_size = os.path.getsize(output_file)
print(f"✓ Label created successfully!")
print(f" File: {output_file}")
print(f" Size: {image.size} (width x height)")
print(f" File size: {file_size:,} bytes")
return output_file
def demo_print_label():
"""Demo: Print a label"""
print("\n" + "=" * 70)
print("DEMO 2: Print Label (Simulated)")
print("=" * 70)
sap_nr = "TEST-001"
quantity = "100"
cable_id = "DEMO-REEL"
label_data = f"{sap_nr}|{quantity}|{cable_id}"
print(f"\nLabel data: {label_data}")
print("\nNote: Printing is simulated (no actual printer output)")
print(" In production, use: print_label_standalone(data, printer_name, preview)")
# Just show what would happen
print("\n✓ Would send to printer: PDF")
print("✓ Label file would be: final_label.png")
print("✓ Print format: Code128 barcode with text")
def demo_multiple_labels():
"""Demo: Create multiple labels with different data"""
print("\n" + "=" * 70)
print("DEMO 3: Create Multiple Labels")
print("=" * 70)
labels_data = [
("SAP001", "10", "REEL-1"),
("SAP002", "20", "REEL-2"),
("SAP003", "30", "REEL-3"),
]
print(f"\nCreating {len(labels_data)} label(s)...\n")
for sap, qty, reel in labels_data:
label_data = f"{sap}|{qty}|{reel}"
image = create_label_image(label_data)
print(f"{label_data:<30} - Label size: {image.size}")
print(f"\n✓ All {len(labels_data)} labels created successfully!")
def main():
"""Run demonstrations"""
print("\n")
print("" + "=" * 68 + "")
print("" + " " * 68 + "")
print("" + "LABEL PRINTER - FUNCTIONAL DEMO".center(68) + "")
print("" + " " * 68 + "")
print("" + "=" * 68 + "")
try:
# Run demos
demo_file = demo_create_label()
demo_print_label()
demo_multiple_labels()
# Summary
print("\n" + "=" * 70)
print("DEMO SUMMARY")
print("=" * 70)
print("""
✓ Label image generation: WORKING
✓ Data formatting: WORKING
✓ Barcode generation: WORKING
✓ Image file output: WORKING
✓ Multiple label support: WORKING
System Status:
- Core printing functionality: ✓ OPERATIONAL
- Label preview (GUI): ⚠ Requires X11/graphics driver fix
- Command-line usage: ✓ READY
- Printer detection: ✓ READY
- Image generation: ✓ READY
Next Steps:
1. Use the command-line API for label generation
2. Integrate with your application
3. Or fix X11 graphics and run the GUI
Example Usage:
from print_label import create_label_image, print_label_standalone
# Create label
image = create_label_image("DATA_HERE")
image.save("my_label.png")
# Print to printer
success = print_label_standalone("DATA", "PrinterName", preview=0)
""")
# Cleanup demo file
if os.path.exists(demo_file):
os.remove(demo_file)
print(f"Cleaned up: {demo_file}")
print("=" * 70)
return 0
except Exception as e:
print(f"\n✗ Demo failed: {e}")
import traceback
traceback.print_exc()
return 1
if __name__ == '__main__':
import sys
sys.exit(main())

View File

@@ -1,11 +0,0 @@
install
sudo apt-get install libcups2-dev
create venv or install with --breack-system-pakage
python -m venv label
pip install -r requirements.txt

View File

@@ -1,5 +0,0 @@
python-barcode
pillow
pycups
reportlab
pycups

View File

@@ -1,5 +0,0 @@
python-barcode
pillow
reportlab
kivy
pywin32

View File

@@ -1,104 +0,0 @@
#!/usr/bin/env python3
"""
Label Printer GUI - Setup and Launcher Script
Handles installation and execution of the Label Printer GUI application
"""
import subprocess
import sys
import os
import shutil
def check_python_version():
"""Check if Python version is 3.7 or higher"""
version_info = sys.version_info
if version_info.major < 3 or (version_info.major == 3 and version_info.minor < 7):
print("❌ Python 3.7 or higher required")
return False
print(f"✓ Python {version_info.major}.{version_info.minor}.{version_info.micro} found")
return True
def check_cups():
"""Check if CUPS is installed"""
if shutil.which('lpstat'):
print("✓ CUPS found")
# Try to get printer list
try:
result = subprocess.run(['lpstat', '-p', '-d'],
capture_output=True, text=True, timeout=5)
if result.returncode == 0:
print(" Available printers:")
for line in result.stdout.strip().split('\n')[:5]:
if line:
print(f" {line}")
return True
except:
print("⚠ CUPS found but couldn't list printers")
return True
else:
print("⚠ CUPS not found. Printer functionality may be limited.")
print(" Install with: sudo apt-get install cups")
return False
def install_dependencies():
"""Install required Python packages"""
packages = [
'kivy',
'python-barcode',
'pillow',
'pycups'
]
print("Installing Python dependencies...")
try:
subprocess.check_call([sys.executable, '-m', 'pip', 'install'] + packages)
print("✓ Dependencies installed successfully")
return True
except subprocess.CalledProcessError:
print("❌ Failed to install dependencies")
return False
def run_gui():
"""Run the GUI application"""
try:
print("\nStarting Label Printer GUI...")
print("=" * 50)
subprocess.call([sys.executable, 'label_printer_gui.py'])
return True
except Exception as e:
print(f"❌ Failed to run GUI: {e}")
return False
def main():
"""Main setup and launcher"""
print("=" * 50)
print("Label Printer GUI - Setup & Launcher")
print("=" * 50)
print()
# Step 1: Check Python
print("[1/4] Checking Python installation...")
if not check_python_version():
sys.exit(1)
print()
# Step 2: Check CUPS
print("[2/4] Checking printer service...")
check_cups()
print()
# Step 3: Install dependencies
print("[3/4] Installing dependencies...")
if not install_dependencies():
print("⚠ Some dependencies may not have installed")
response = input("Continue anyway? (y/n): ").lower()
if response != 'y':
sys.exit(1)
print()
# Step 4: Run application
print("[4/4] Launching application...")
run_gui()
if __name__ == '__main__':
main()

View File

@@ -1,52 +0,0 @@
#!/bin/bash
# Label Printer GUI - Quick Start Script
# This script sets up and runs the Label Printer GUI application
set -e
echo "=========================================="
echo "Label Printer GUI - Setup & Run"
echo "=========================================="
echo ""
# Check Python installation
echo "[1/4] Checking Python installation..."
if ! command -v python3 &> /dev/null; then
echo "❌ Python 3 not found. Please install Python 3.7 or higher."
exit 1
fi
PYTHON_VERSION=$(python3 --version | cut -d' ' -f2)
echo "✓ Python $PYTHON_VERSION found"
echo ""
# Check CUPS
echo "[2/4] Checking CUPS (printer service)..."
if ! command -v lpstat &> /dev/null; then
echo "⚠ CUPS not found. Please install with: sudo apt-get install cups"
echo " Proceeding anyway - will use PDF printer"
else
echo "✓ CUPS found"
echo " Available printers:"
lpstat -p -d | head -5
fi
echo ""
# Install dependencies
echo "[3/4] Installing Python dependencies..."
if [ -f "requirements_gui.txt" ]; then
pip install -r requirements_gui.txt
echo "✓ Dependencies installed"
else
echo "⚠ requirements_gui.txt not found"
echo " Installing Kivy and related packages manually..."
pip install kivy python-barcode pillow pycups
fi
echo ""
# Run the application
echo "[4/4] Starting Label Printer GUI..."
echo "=========================================="
echo ""
python3 label_printer_gui.py

View File

@@ -1,205 +0,0 @@
#!/usr/bin/env python3
"""
Test Label Printer - Non-GUI Tests
Tests printing functionality without GUI/graphics
"""
import os
import sys
def test_module_imports():
"""Test that all required modules can be imported"""
print("=" * 60)
print("TEST 1: Module Imports")
print("=" * 60)
modules = {
'PIL': 'Image processing',
'barcode': 'Barcode generation',
'cups': 'Printer interface',
'print_label': 'Label printing module'
}
all_ok = True
for module, description in modules.items():
try:
__import__(module)
print(f"{module:<20} - {description}")
except ImportError as e:
print(f"{module:<20} - FAILED: {e}")
all_ok = False
return all_ok
def test_label_generation():
"""Test label image generation"""
print("\n" + "=" * 60)
print("TEST 2: Label Image Generation")
print("=" * 60)
try:
from print_label import create_label_image
test_cases = [
"SAP123",
"SAP456|100",
"SAP789|50|REEL001"
]
for test_text in test_cases:
image = create_label_image(test_text)
print(f"✓ Generated label for: '{test_text}' - Size: {image.size}")
return True
except Exception as e:
print(f"✗ Label generation failed: {e}")
import traceback
traceback.print_exc()
return False
def test_printer_detection():
"""Test printer detection"""
print("\n" + "=" * 60)
print("TEST 3: Printer Detection")
print("=" * 60)
try:
import cups
conn = cups.Connection()
printers = conn.getPrinters()
if printers:
print(f"✓ Found {len(printers)} printer(s):")
for name, details in list(printers.items())[:5]:
status = details.get('printer-state', 'unknown')
print(f" - {name:<30} (State: {status})")
else:
print("⚠ No printers configured (will use PDF)")
return True
except Exception as e:
print(f"✗ Printer detection failed: {e}")
return False
def test_save_label():
"""Test saving label to file"""
print("\n" + "=" * 60)
print("TEST 4: Save Label to File")
print("=" * 60)
try:
from print_label import create_label_image
import tempfile
# Create test label
test_text = "TEST_LABEL|123|REEL"
image = create_label_image(test_text)
# Save to temporary file
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp:
image.save(tmp.name)
tmp_path = tmp.name
# Check if file exists and has content
file_size = os.path.getsize(tmp_path)
print(f"✓ Label saved successfully")
print(f" - File: {tmp_path}")
print(f" - Size: {file_size:,} bytes")
# Clean up
os.remove(tmp_path)
print(f" - Cleaned up temporary file")
return True
except Exception as e:
print(f"✗ Save label test failed: {e}")
import traceback
traceback.print_exc()
return False
def test_data_formats():
"""Test different data format combinations"""
print("\n" + "=" * 60)
print("TEST 5: Data Format Testing")
print("=" * 60)
try:
from print_label import create_label_image
test_formats = [
("A012345", "SAP only"),
("A012345|50", "SAP + Quantity"),
("A012345|50|REEL001", "SAP + Quantity + Cable ID"),
("SPEC-123|999|CABLE-X", "Complex format"),
("123456789012345678901234567890", "Long string"),
]
for data, description in test_formats:
try:
image = create_label_image(data)
print(f"{description:<30} - OK")
except Exception as e:
print(f"{description:<30} - FAILED: {e}")
return False
return True
except Exception as e:
print(f"✗ Data format test failed: {e}")
return False
def main():
"""Run all tests"""
print("\n")
print("" + "=" * 58 + "")
print("" + " " * 58 + "")
print("" + " LABEL PRINTER - FUNCTIONAL TESTS".center(58) + "")
print("" + " " * 58 + "")
print("" + "=" * 58 + "")
print()
tests = [
("Module Imports", test_module_imports),
("Label Generation", test_label_generation),
("Printer Detection", test_printer_detection),
("Save Label to File", test_save_label),
("Data Format Testing", test_data_formats),
]
results = []
for test_name, test_func in tests:
try:
result = test_func()
results.append((test_name, result))
except Exception as e:
print(f"\n✗ Test '{test_name}' crashed: {e}")
results.append((test_name, False))
# Summary
print("\n" + "=" * 60)
print("TEST SUMMARY")
print("=" * 60)
passed = sum(1 for _, result in results if result)
total = len(results)
for test_name, result in results:
status = "✓ PASS" if result else "✗ FAIL"
print(f"{status} - {test_name}")
print()
print(f"Results: {passed}/{total} tests passed")
print()
if passed == total:
print("✓ ALL TESTS PASSED! System is ready to use.")
print("\nNext steps:")
print(" 1. Fix graphics driver issue for GUI display")
print(" 2. Or use the printing API directly in your code")
return 0
else:
print("✗ Some tests failed. Please review the output above.")
return 1
if __name__ == '__main__':
sys.exit(main())

View File

@@ -1,88 +0,0 @@
#!/usr/bin/env python3
"""
Simple test to verify GUI components work
"""
print("Testing Label Printer GUI components...")
print()
# Test 1: Import modules
print("[1/5] Testing imports...")
try:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
print("✓ Kivy imports successful")
except Exception as e:
print(f"✗ Kivy import failed: {e}")
exit(1)
# Test 2: Import printing modules
print()
print("[2/5] Testing printing module...")
try:
from print_label import create_label_image, print_label_standalone
print("✓ Printing module imports successful")
except Exception as e:
print(f"✗ Printing module import failed: {e}")
exit(1)
# Test 3: Test label image generation
print()
print("[3/5] Testing label image generation...")
try:
test_text = "TEST|123|REEL001"
image = create_label_image(test_text)
print(f"✓ Label image created: {image.size}")
except Exception as e:
print(f"✗ Label image generation failed: {e}")
exit(1)
# Test 4: Test printer detection
print()
print("[4/5] Testing printer detection...")
try:
import cups
conn = cups.Connection()
printers = conn.getPrinters()
printer_list = list(printers.keys()) if printers else []
if printer_list:
print(f"✓ Printers found: {', '.join(printer_list[:3])}")
else:
print("⚠ No printers found (will use PDF)")
except Exception as e:
print(f"✗ Printer detection failed: {e}")
# Test 5: Create simple test app
print()
print("[5/5] Creating test application...")
try:
class TestApp(App):
def build(self):
layout = BoxLayout(orientation='vertical', padding=10, spacing=10)
layout.add_widget(Label(text='Label Printer GUI Test', size_hint_y=0.2))
layout.add_widget(Label(text='✓ All components loaded successfully!', size_hint_y=0.3))
btn = Button(text='Close', size_hint_y=0.2)
btn.bind(on_press=lambda x: App.get_running_app().stop())
layout.add_widget(btn)
return layout
print("✓ Test application created")
print()
print("=" * 60)
print("🚀 Starting test GUI (close window to continue)...")
print("=" * 60)
app = TestApp()
app.run()
print()
print("✓ GUI test completed successfully!")
except Exception as e:
print(f"✗ Test application failed: {e}")
import traceback
traceback.print_exc()
exit(1)

View File

@@ -1,107 +0,0 @@
#!/usr/bin/env python3
"""
Test UI Features - Validates that the GUI application components work correctly
This test verifies all the UI elements and functionality that the Kivy GUI would provide
"""
import sys
from print_label import create_label_image, print_label_standalone
print("╔════════════════════════════════════════════════════════════╗")
print("║ LABEL PRINTER UI - FEATURE TEST ║")
print("╚════════════════════════════════════════════════════════════╝")
print()
# Test 1: UI Input Validation
print("[1/5] Testing UI Input Validation...")
test_inputs = [
("SAP123", "Basic SAP code"),
("SAP456|100", "SAP with Quantity"),
("SAP789|50|REEL001", "SAP with Quantity and Cable ID"),
("", "Empty input (should handle gracefully)"),
]
for input_val, description in test_inputs:
try:
if input_val: # Skip empty test
img = create_label_image(input_val)
print(f"{description}: '{input_val}'")
else:
print(f"{description}: Handled gracefully")
except Exception as e:
print(f"{description}: {e}")
print()
# Test 2: Printer Selection (UI Spinner)
print("[2/5] Testing Printer Selection (UI Spinner Component)...")
try:
import cups
conn = cups.Connection()
printers = conn.getPrinters()
printer_list = list(printers.keys()) if printers else ["PDF"]
if printer_list:
print(f" ✓ Available printers: {', '.join(printer_list)}")
print(f" ✓ Printer selector would show {len(printer_list)} option(s)")
else:
print(f" ✓ No printers found, PDF selected as default")
except Exception as e:
print(f" ✗ Printer detection failed: {e}")
print()
# Test 3: Label Preview (Image Generation)
print("[3/5] Testing Label Preview (Image Generation)...")
try:
test_label = "TEST|500|CABLE1"
img = create_label_image(test_label)
print(f" ✓ Label preview generated: {img.size[0]}x{img.size[1]}px")
print(f" ✓ Preview would display in UI")
except Exception as e:
print(f" ✗ Preview generation failed: {e}")
print()
# Test 4: Button Functionality - Print Action
print("[4/5] Testing Button Functionality (Print Action)...")
print(" ✓ Print button would trigger print_label_standalone()")
print(" ✓ Clear button would reset input fields")
print(" ✓ Reset button would clear all selections")
print()
# Test 5: UI Responsiveness (Threading)
print("[5/5] Testing UI Threading (Background Operations)...")
import threading
def simulate_print():
"""Simulate a print operation in background thread"""
try:
label_text = "ASYNC|TEST|001"
create_label_image(label_text)
return True
except:
return False
thread = threading.Thread(target=simulate_print)
thread.start()
thread.join(timeout=5)
if not thread.is_alive():
print(" ✓ Background operations complete without blocking UI")
print(" ✓ Threading system ready for printing tasks")
else:
print(" ✗ Threading operation timed out")
print()
print("╔════════════════════════════════════════════════════════════╗")
print("║ TEST SUMMARY ║")
print("╚════════════════════════════════════════════════════════════╝")
print()
print("✓ All UI features are functional and ready")
print("✓ GUI application can be launched successfully")
print()
print("Note: For full GUI testing in headless environment,")
print(" use a machine with X11 display or use:")
print(" xvfb-run -a python3 label_printer_gui.py")

View File

@@ -1,158 +0,0 @@
#!/usr/bin/env python3
"""
Label Printer GUI - Project Validation Script
Checks if the project is properly set up and ready to run
"""
import os
import sys
import subprocess
def print_header(text):
print(f"\n{'='*60}")
print(f" {text}")
print(f"{'='*60}\n")
def check_file(filepath, description):
"""Check if a file exists"""
if os.path.exists(filepath):
size = os.path.getsize(filepath)
print(f"{description:<40} ({size:,} bytes)")
return True
else:
print(f"{description:<40} MISSING!")
return False
def check_python():
"""Check Python version"""
version = sys.version_info
version_str = f"{version.major}.{version.minor}.{version.micro}"
if version.major >= 3 and version.minor >= 7:
print(f"✅ Python version {version_str:<30} OK")
return True
else:
print(f"❌ Python version {version_str:<30} TOO OLD (need 3.7+)")
return False
def check_module(module_name):
"""Check if a Python module is installed"""
try:
__import__(module_name)
print(f"{module_name:<40} installed")
return True
except ImportError:
print(f"{module_name:<40} not installed (will install on first run)")
return False
def check_cups():
"""Check if CUPS is available"""
try:
result = subprocess.run(['lpstat', '-p'],
capture_output=True, text=True, timeout=5)
if result.returncode == 0:
printer_count = result.stdout.count('printer')
print(f"✅ CUPS available ({printer_count} printer(s) configured)")
return True
except:
pass
print(f"⚠ CUPS not accessible (install with: sudo apt-get install cups)")
return False
def main():
print_header("Label Printer GUI - Project Validation")
all_ok = True
# Check required files
print("📋 Checking Required Files:")
print("-" * 60)
files_to_check = [
("label_printer_gui.py", "Main GUI Application"),
("print_label.py", "Printing Engine"),
("setup_and_run.py", "Setup Script"),
("requirements_gui.txt", "GUI Dependencies"),
("requirements.txt", "Original Dependencies"),
]
for filepath, description in files_to_check:
if not check_file(filepath, description):
all_ok = False
# Check documentation
print("\n📚 Checking Documentation:")
print("-" * 60)
docs_to_check = [
("GETTING_STARTED.md", "Quick Start Guide"),
("README_GUI.md", "Feature Documentation"),
("TECHNICAL_DOCS.md", "Technical Reference"),
("FILE_GUIDE.md", "File Reference Guide"),
("IMPLEMENTATION_SUMMARY.md", "Implementation Summary"),
]
for filepath, description in docs_to_check:
if not check_file(filepath, description):
all_ok = False
# Check Python version
print("\n🐍 Checking Python Environment:")
print("-" * 60)
if not check_python():
all_ok = False
# Check optional modules
print("\n📦 Checking Python Modules:")
print("-" * 60)
modules = [
('kivy', 'Kivy GUI Framework'),
('PIL', 'Pillow (Image Processing)'),
('barcode', 'Barcode Generation'),
('cups', 'CUPS Interface'),
]
optional_found = False
for module_name, description in modules:
try:
__import__(module_name)
print(f"{description:<40} installed")
optional_found = True
except ImportError:
print(f"{description:<40} not installed (will install on first run)")
# Check CUPS
print("\n🖨️ Checking Printer Service:")
print("-" * 60)
check_cups()
# Summary
print_header("Summary & Next Steps")
if all_ok:
print("✅ All required files are present!\n")
print("🚀 Ready to run! Use one of these commands:\n")
print(" Option 1 (Recommended):")
print(" $ python3 setup_and_run.py\n")
print(" Option 2 (Manual):")
print(" $ pip install -r requirements_gui.txt")
print(" $ python3 label_printer_gui.py\n")
print(" Option 3 (Bash):")
print(" $ chmod +x start_gui.sh")
print(" $ ./start_gui.sh\n")
else:
print("⚠️ Some files might be missing or issues detected.\n")
print("👉 First run setup_and_run.py to install everything:")
print(" $ python3 setup_and_run.py\n")
print("📖 For detailed help, read:")
print(" • GETTING_STARTED.md - Quick start guide")
print(" • README_GUI.md - Full documentation")
print(" • FILE_GUIDE.md - File reference")
print()
return 0 if all_ok else 1
if __name__ == '__main__':
sys.exit(main())

View File

@@ -15,6 +15,7 @@ from kivy.uix.popup import Popup
from kivy.core.window import Window
from kivy.uix.image import Image as KivyImage
from kivy.graphics import Color, Rectangle
from kivy.uix.filechooser import FileChooserListView
import os
import threading
@@ -22,8 +23,14 @@ import platform
import time
import datetime
import glob
import configparser
from print_label import print_label_standalone, get_available_printers
from kivy.clock import Clock
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import pystray
from pystray import MenuItem as item
from PIL import Image, ImageDraw
# Set window size - portrait/phone dimensions (375x667 like iPhone)
# Adjusted to be slightly wider for touch-friendly UI
@@ -33,8 +40,26 @@ Window.size = (420, 700)
class FileMonitorHandler(FileSystemEventHandler):
"""Handler for file system events"""
def __init__(self, app, file_path):
self.app = app
self.file_path = file_path
self.last_modified = 0
def on_modified(self, event):
"""Called when a file is modified"""
if event.src_path == self.file_path:
# Debounce - avoid multiple triggers
current_time = time.time()
if current_time - self.last_modified > 1: # 1 second debounce
self.last_modified = current_time
Clock.schedule_once(lambda dt: self.app.on_file_changed(), 0)
class LabelPrinterApp(App):
"""Simplified Kivy application for label printing"""
"""Simplified Kivy application for label printing with file monitoring"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
@@ -49,6 +74,15 @@ class LabelPrinterApp(App):
display_name = full_name[:20]
self.printer_display_map[display_name] = full_name
self.available_printers.append(display_name)
# File monitoring variables
self.observer = None
self.monitored_file = None
self.monitoring_active = False
# Configuration file path
self.config_file = os.path.join('conf', 'app.conf')
# System tray variables
self.tray_icon = None
self.is_minimized = False
# Clean old PDF backup files on startup
self.cleanup_old_pdfs()
# Clean old log files on startup
@@ -149,14 +183,60 @@ class LabelPrinterApp(App):
except Exception as e:
print(f"Error during log cleanup: {e}")
def log_print_action(self, sap_nr, quantity, cable_id, printer, pdf_filename, success):
def load_config(self):
"""
Load configuration from conf/app.conf file.
Returns dict with 'file_path' and 'printer' keys.
"""
config = {'file_path': '', 'printer': ''}
if not os.path.exists(self.config_file):
return config
try:
parser = configparser.ConfigParser()
parser.read(self.config_file, encoding='utf-8')
if 'Settings' in parser:
config['file_path'] = parser['Settings'].get('file_path', '')
config['printer'] = parser['Settings'].get('printer', '')
print(f"Configuration loaded from {self.config_file}")
except Exception as e:
print(f"Error loading config: {e}")
return config
def save_config(self):
"""
Save current configuration to conf/app.conf file.
Saves file_path and selected printer.
"""
# Ensure conf folder exists
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
try:
parser = configparser.ConfigParser()
parser['Settings'] = {
'file_path': self.file_input.text.strip(),
'printer': self.printer_spinner.text
}
with open(self.config_file, 'w', encoding='utf-8') as f:
parser.write(f)
print(f"Configuration saved to {self.config_file}")
except Exception as e:
print(f"Error saving config: {e}")
def log_print_action(self, article, nr_art, serial, printer, pdf_filename, success):
"""
Log the print action to a CSV log file (table format).
Args:
sap_nr (str): SAP article number
quantity (str): Quantity value
cable_id (str): Cable ID
article (str): Article/Comanda number
nr_art (str): Nr. Art. value
serial (str): Serial number
printer (str): Printer name
pdf_filename (str): Path to the generated PDF file
success (bool): Whether the print was successful
@@ -186,9 +266,9 @@ class LabelPrinterApp(App):
# Create CSV line
log_line = (
f"{timestamp},{status},"
f"{escape_csv(sap_nr)},"
f"{escape_csv(quantity)},"
f"{escape_csv(cable_id)},"
f"{escape_csv(article)},"
f"{escape_csv(nr_art)},"
f"{escape_csv(serial)},"
f"{escape_csv(printer)},"
f"{escape_csv(pdf_filename)}\n"
)
@@ -200,7 +280,7 @@ class LabelPrinterApp(App):
with open(log_filename, 'a', encoding='utf-8') as f:
# Add header if file is new
if not file_exists:
f.write("Timestamp,Status,SAP-Nr,Quantity,Cable ID,Printer,PDF File\n")
f.write("Timestamp,Status,Article,Nr Art,Serial No,Printer,PDF File\n")
# Append log entry
f.write(log_line)
@@ -209,15 +289,15 @@ class LabelPrinterApp(App):
print(f"Error saving log entry: {e}")
def build(self):
"""Build the simplified single-column UI"""
self.title = "Label Printing"
"""Build the simplified file monitoring UI"""
self.title = "Label Printing - File Monitor"
# Main container - single column layout
main_layout = BoxLayout(orientation='vertical', spacing=8, padding=12)
# Title
title = Label(
text='[b]Label Printing[/b]',
text='[b]Label Printing - File Monitor[/b]',
markup=True,
size_hint_y=0.08,
font_size='18sp',
@@ -226,70 +306,56 @@ class LabelPrinterApp(App):
main_layout.add_widget(title)
# Scroll view for form fields
scroll = ScrollView(size_hint_y=0.75)
scroll = ScrollView(size_hint_y=0.60)
form_layout = GridLayout(cols=1, spacing=8, size_hint_y=None, padding=8)
form_layout.bind(minimum_height=form_layout.setter('height'))
# SAP-Nr. Articol
sap_label = Label(
text='SAP-Nr. Articol:',
# File path input
file_label = Label(
text='Monitor File Path:',
size_hint_y=None,
height=30,
font_size='12sp'
)
form_layout.add_widget(sap_label)
form_layout.add_widget(file_label)
self.sap_input = TextInput(
# File path row with input and browse button
file_row = BoxLayout(orientation='horizontal', size_hint_y=None, height=45, spacing=5)
self.file_input = TextInput(
multiline=False,
size_hint_y=None,
height=45,
font_size='14sp',
background_color=(0.95, 0.95, 0.95, 1),
padding=(10, 10)
)
self.sap_input.bind(text=self.on_sap_text_change)
form_layout.add_widget(self.sap_input)
# Cantitate
qty_label = Label(
text='Cantitate:',
size_hint_y=None,
height=30,
font_size='12sp'
)
form_layout.add_widget(qty_label)
self.qty_input = TextInput(
multiline=False,
size_hint_y=None,
height=45,
font_size='14sp',
size_hint_x=0.75,
font_size='12sp',
background_color=(0.95, 0.95, 0.95, 1),
padding=(10, 10),
input_filter='int' # Only allow numbers
hint_text='Enter file path to monitor'
)
self.qty_input.bind(text=self.on_qty_text_change)
form_layout.add_widget(self.qty_input)
file_row.add_widget(self.file_input)
# ID rola cablu
cable_id_label = Label(
text='ID rola cablu:',
browse_button = Button(
text='Browse',
size_hint_x=0.25,
font_size='11sp',
background_color=(0.3, 0.5, 0.7, 1),
background_normal=''
)
browse_button.bind(on_press=self.browse_file)
file_row.add_widget(browse_button)
form_layout.add_widget(file_row)
# Monitoring status
self.status_label = Label(
text='Status: Not monitoring',
size_hint_y=None,
height=30,
font_size='12sp'
font_size='11sp',
color=(1, 0.5, 0, 1)
)
form_layout.add_widget(cable_id_label)
form_layout.add_widget(self.status_label)
self.cable_id_input = TextInput(
multiline=False,
size_hint_y=None,
height=45,
font_size='14sp',
background_color=(0.95, 0.95, 0.95, 1),
padding=(10, 10)
)
self.cable_id_input.bind(text=self.on_cable_id_text_change)
form_layout.add_widget(self.cable_id_input)
# Add spacing
form_layout.add_widget(Label(text='', size_hint_y=None, height=20))
# Printer selection
printer_label = Label(
@@ -309,55 +375,346 @@ class LabelPrinterApp(App):
sync_height=True,
)
self.printer_spinner = printer_spinner
# Save config when printer changes
printer_spinner.bind(text=self.on_printer_changed)
form_layout.add_widget(printer_spinner)
scroll.add_widget(form_layout)
main_layout.add_widget(scroll)
# Print button
print_button = Button(
text='PRINT LABEL',
size_hint_y=0.15,
# Buttons layout
buttons_layout = BoxLayout(orientation='vertical', size_hint_y=0.30, spacing=5)
# Start/Stop monitoring button
self.monitor_button = Button(
text='START MONITORING',
size_hint_y=0.7,
font_size='14sp',
background_color=(0.2, 0.6, 0.2, 1),
background_color=(0.2, 0.5, 0.8, 1),
background_normal='',
bold=True
)
print_button.bind(on_press=self.print_label)
main_layout.add_widget(print_button)
self.monitor_button.bind(on_press=self.toggle_monitoring)
buttons_layout.add_widget(self.monitor_button)
# Minimize to tray button
minimize_button = Button(
text='MINIMIZE TO TRAY',
size_hint_y=0.3,
font_size='11sp',
background_color=(0.5, 0.5, 0.5, 1),
background_normal=''
)
minimize_button.bind(on_press=self.minimize_to_tray)
buttons_layout.add_widget(minimize_button)
main_layout.add_widget(buttons_layout)
# Load configuration after UI is built
Clock.schedule_once(lambda dt: self.apply_config(), 0.5)
return main_layout
def on_sap_text_change(self, instance, value):
"""Limit SAP input to 25 characters"""
if len(value) > 25:
self.sap_input.text = value[:25]
def apply_config(self):
"""
Load and apply saved configuration.
Auto-start monitoring if both file and printer are configured.
"""
config = self.load_config()
def on_qty_text_change(self, instance, value):
"""Limit Quantity input to 25 characters"""
if len(value) > 25:
self.qty_input.text = value[:25]
# Apply file path
if config['file_path']:
self.file_input.text = config['file_path']
print(f"Loaded file path: {config['file_path']}")
def on_cable_id_text_change(self, instance, value):
"""Limit Cable ID input to 25 characters"""
if len(value) > 25:
self.cable_id_input.text = value[:25]
# Apply printer selection
if config['printer'] and config['printer'] in self.available_printers:
self.printer_spinner.text = config['printer']
print(f"Loaded printer: {config['printer']}")
# Auto-start monitoring if both are configured and file exists
if config['file_path'] and config['printer']:
if os.path.exists(config['file_path']) and os.path.isfile(config['file_path']):
print("Auto-starting monitoring with saved configuration...")
self.start_monitoring()
else:
print(f"Configured file not found: {config['file_path']}")
def on_printer_changed(self, spinner, text):
"""
Called when printer selection changes.
Save configuration.
"""
self.save_config()
def create_tray_icon_image(self):
"""
Create a simple icon for the system tray.
Returns PIL Image.
"""
# Create a 64x64 icon with a simple printer symbol
width = 64
height = 64
image = Image.new('RGB', (width, height), color='white')
draw = ImageDraw.Draw(image)
# Draw a simple printer icon (rectangle with lines)
draw.rectangle([10, 20, 54, 40], fill='blue', outline='black', width=2)
draw.rectangle([15, 40, 49, 50], fill='lightblue', outline='black', width=2)
draw.rectangle([20, 10, 44, 20], fill='lightgray', outline='black', width=1)
return image
def minimize_to_tray(self, instance=None):
"""
Minimize the application to system tray.
"""
if self.is_minimized:
return
# Hide the window
Window.hide()
self.is_minimized = True
# Create tray icon if not exists
if not self.tray_icon:
icon_image = self.create_tray_icon_image()
menu = pystray.Menu(
item('Restore', self.restore_from_tray),
item('Exit', self.exit_from_tray)
)
self.tray_icon = pystray.Icon(
'Label Printer',
icon_image,
'Label Printer - Monitoring',
menu
)
# Run tray icon in separate thread
tray_thread = threading.Thread(target=self.tray_icon.run, daemon=True)
tray_thread.start()
def restore_from_tray(self, icon=None, item=None):
"""
Restore the application from system tray.
"""
if not self.is_minimized:
return
# Stop tray icon
if self.tray_icon:
self.tray_icon.stop()
self.tray_icon = None
# Show the window
Clock.schedule_once(lambda dt: Window.show(), 0)
self.is_minimized = False
def exit_from_tray(self, icon=None, item=None):
"""
Exit the application from system tray.
"""
# Stop tray icon
if self.tray_icon:
self.tray_icon.stop()
self.tray_icon = None
# Stop monitoring
if self.observer:
self.observer.stop()
self.observer.join()
# Stop the app
Clock.schedule_once(lambda dt: self.stop(), 0)
def browse_file(self, instance):
"""Open file browser to select file to monitor"""
content = BoxLayout(orientation='vertical', spacing=10, padding=10)
# File chooser
file_chooser = FileChooserListView(
path=os.path.expanduser('~'),
size_hint=(1, 0.9)
)
content.add_widget(file_chooser)
# Buttons
buttons = BoxLayout(size_hint_y=0.1, spacing=10)
popup = Popup(
title='Select File to Monitor',
content=content,
size_hint=(0.9, 0.9)
)
def select_file(instance):
if file_chooser.selection:
self.file_input.text = file_chooser.selection[0]
# Save config when file is selected
self.save_config()
popup.dismiss()
select_btn = Button(text='Select')
select_btn.bind(on_press=select_file)
buttons.add_widget(select_btn)
cancel_btn = Button(text='Cancel')
cancel_btn.bind(on_press=popup.dismiss)
buttons.add_widget(cancel_btn)
content.add_widget(buttons)
popup.open()
def toggle_monitoring(self, instance):
"""Start or stop file monitoring"""
if not self.monitoring_active:
self.start_monitoring()
else:
self.stop_monitoring()
def start_monitoring(self):
"""Start monitoring the specified file"""
file_path = self.file_input.text.strip()
if not file_path:
self.show_popup("Error", "Please enter a file path to monitor", auto_dismiss_after=3)
return
if not os.path.exists(file_path):
self.show_popup("Error", "File does not exist", auto_dismiss_after=3)
return
if not os.path.isfile(file_path):
self.show_popup("Error", "Path is not a file", auto_dismiss_after=3)
return
try:
# Stop existing observer if any
if self.observer:
self.observer.stop()
self.observer.join()
# Create and start new observer
self.monitored_file = os.path.abspath(file_path)
event_handler = FileMonitorHandler(self, self.monitored_file)
self.observer = Observer()
self.observer.schedule(event_handler, os.path.dirname(self.monitored_file), recursive=False)
self.observer.start()
self.monitoring_active = True
self.monitor_button.text = 'STOP MONITORING'
self.monitor_button.background_color = (0.8, 0.2, 0.2, 1)
self.status_label.text = f'Status: Monitoring {os.path.basename(file_path)}'
self.status_label.color = (0, 1, 0, 1)
self.show_popup("Success", f"Started monitoring:\n{file_path}", auto_dismiss_after=2)
except Exception as e:
self.show_popup("Error", f"Failed to start monitoring:\n{str(e)}", auto_dismiss_after=3)
def stop_monitoring(self):
"""Stop file monitoring"""
try:
if self.observer:
self.observer.stop()
self.observer.join()
self.observer = None
self.monitoring_active = False
self.monitor_button.text = 'START MONITORING'
self.monitor_button.background_color = (0.2, 0.5, 0.8, 1)
self.status_label.text = 'Status: Not monitoring'
self.status_label.color = (1, 0.5, 0, 1)
self.show_popup("Success", "Stopped monitoring", auto_dismiss_after=2)
except Exception as e:
self.show_popup("Error", f"Failed to stop monitoring:\n{str(e)}", auto_dismiss_after=3)
def on_file_changed(self):
"""Called when monitored file changes"""
if not self.monitoring_active or not self.monitored_file:
return
# Automatically print label when file changes
self.print_label(None)
def clear_file_after_print(self):
"""Clear the monitored file and write '-' to prevent re-printing"""
if not self.monitored_file or not os.path.exists(self.monitored_file):
return
try:
with open(self.monitored_file, 'w', encoding='utf-8') as f:
f.write('-')
print(f"Cleared file: {self.monitored_file}")
except Exception as e:
print(f"Error clearing file: {e}")
def read_file_variables(self):
"""Read variables from monitored file"""
if not self.monitored_file or not os.path.exists(self.monitored_file):
return None, None, None
try:
with open(self.monitored_file, 'r', encoding='utf-8') as f:
content = f.read().strip()
# Skip if file is empty or only contains "-" (cleared marker)
if not content or content == '-':
return None, None, None
# Parse file content - expecting format: article;nr_art;serial
# or key=value pairs on separate lines
lines = content.split('\n')
article = ""
nr_art = ""
serial = ""
# Try semicolon-separated format first
if ';' in content:
parts = content.split(';')
if len(parts) >= 1:
article = parts[0].strip()
if len(parts) >= 2:
nr_art = parts[1].strip()
if len(parts) >= 3:
serial = parts[2].strip()
else:
# Try key=value format
for line in lines:
if '=' in line:
key, value = line.split('=', 1)
key = key.strip().lower()
value = value.strip()
if key in ['article', 'articol', 'comanda', 'nr_comanda']:
article = value
elif key in ['nr_art', 'nr-art', 'nrart']:
nr_art = value
elif key in ['serial', 'serial_no', 'serial-no', 'serialno']:
serial = value
return article, nr_art, serial
except Exception as e:
print(f"Error reading file: {e}")
return None, None, None
def print_label(self, instance):
"""Handle print button press"""
sap_nr = self.sap_input.text.strip()
quantity = self.qty_input.text.strip()
cable_id = self.cable_id_input.text.strip()
"""Handle print button press - read from file and print"""
# Read variables from file
article, nr_art, serial = self.read_file_variables()
# Resolve display name to full printer name
printer = self._get_full_printer_name(self.printer_spinner.text)
# Validate input
if not sap_nr and not quantity and not cable_id:
self.show_popup("Error", "Please enter at least one field")
if not article and not nr_art and not serial:
self.show_popup("Error", "No data in file or file not set", auto_dismiss_after=3)
return
# Create combined label text
label_text = f"{sap_nr}|{quantity}|{cable_id}"
# Create combined label text using semicolon separator
label_text = f"{article};{nr_art};{serial}"
# Show loading popup
popup = Popup(
@@ -389,39 +746,39 @@ class LabelPrinterApp(App):
if success:
# Log the successful print action
self.log_print_action(sap_nr, quantity, cable_id, printer, pdf_filename or "unknown", True)
self.log_print_action(article, nr_art, serial, printer, pdf_filename or "unknown", True)
# Clear the file and write "-" to prevent re-printing
Clock.schedule_once(lambda dt: self.clear_file_after_print(), 0)
# Use Clock.schedule_once to update UI from main thread
Clock.schedule_once(lambda dt: popup.dismiss(), 0)
Clock.schedule_once(lambda dt: self.show_popup("Success", "Label printed successfully!"), 0.1)
# Clear inputs after successful print (but keep printer selection)
Clock.schedule_once(lambda dt: self.clear_inputs(), 0.2)
Clock.schedule_once(lambda dt: self.show_popup("Success", "Label printed successfully!", auto_dismiss_after=3), 0.1)
else:
# Log the failed print action
self.log_print_action(sap_nr, quantity, cable_id, printer, pdf_filename or "unknown", False)
self.log_print_action(article, nr_art, serial, printer, pdf_filename or "unknown", False)
Clock.schedule_once(lambda dt: popup.dismiss(), 0)
Clock.schedule_once(lambda dt: self.show_popup("Error", "Failed to print label"), 0.1)
Clock.schedule_once(lambda dt: self.show_popup("Error", "Failed to print label", auto_dismiss_after=3), 0.1)
except Exception as e:
# Log the error
self.log_print_action(sap_nr, quantity, cable_id, printer, pdf_filename or "unknown", False)
self.log_print_action(article, nr_art, serial, printer, pdf_filename or "unknown", False)
Clock.schedule_once(lambda dt: popup.dismiss(), 0)
Clock.schedule_once(lambda dt: self.show_popup("Error", f"Print error: {str(e)}"), 0.1)
Clock.schedule_once(lambda dt: self.show_popup("Error", f"Print error: {str(e)}", auto_dismiss_after=3), 0.1)
thread = threading.Thread(target=print_thread)
thread.daemon = True
thread.start()
def clear_inputs(self):
"""Clear only the input fields, preserving printer selection"""
self.sap_input.text = ''
self.qty_input.text = ''
self.cable_id_input.text = ''
# Printer selection is NOT cleared - it persists until user changes it
def show_popup(self, title, message, auto_dismiss_after=None):
"""Show a popup message
def show_popup(self, title, message):
"""Show a popup message"""
Args:
title (str): Popup title
message (str): Popup message
auto_dismiss_after (float): Seconds after which to auto-dismiss (None = manual dismiss only)
"""
popup = Popup(
title=title,
content=BoxLayout(
@@ -440,6 +797,10 @@ class LabelPrinterApp(App):
popup.open()
# Auto-dismiss if specified
if auto_dismiss_after:
Clock.schedule_once(lambda dt: popup.dismiss(), auto_dismiss_after)
if __name__ == '__main__':
app = LabelPrinterApp()

View File

@@ -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,48 +258,61 @@ 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'):
# Use SumatraPDF command-line or direct raw printing
# Try printing via subprocess to avoid opening a PDF viewer window
# 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"),
]
# 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:
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)
# 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 raw_err:
print(f"Raw print failed ({raw_err}), trying ShellExecute silently...")
# Fallback: Use ShellExecute with printto (minimized, auto-closes)
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:
import win32api
win32api.ShellExecute(
0, "printto", file_path,
f'"{printer_name}"', ".", 0
)
print(f"Label sent to printer: {printer_name}")
print(f"Label sent to printer via ShellExecute: {printer_name}")
return True
except Exception as shell_err:
print(f"ShellExecute print failed: {shell_err}")
# Method 3: Open PDF with default viewer (last resort)
try:
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 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
@@ -299,9 +321,6 @@ def print_to_printer(printer_name, file_path):
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")
return True
except Exception as e:
print(f"Windows print error: {e}")
print("PDF backup saved as fallback")

View File

@@ -1,116 +1,223 @@
"""
PDF-based Label Printing Module
Generates high-quality PDF labels with barcodes for printing.
Uses reportlab for superior PDF generation compared to PNG rasterization.
Simplified layout: no borders, just field names and barcodes.
Generates high-quality PDF labels with image and text.
Uses reportlab for superior PDF generation.
Layout: 35mm x 25mm landscape - supports SVG templates with variable substitution.
"""
from reportlab.lib.pagesizes import landscape
from reportlab.lib.units import cm, mm
from reportlab.pdfgen import canvas
from barcode import Code128
from barcode.writer import ImageWriter
from reportlab.graphics import renderPDF
import io
from PIL import Image
import os
import tempfile
import datetime
import re
import traceback
# SVG support
try:
from svglib.svglib import svg2rlg
SVG_AVAILABLE = True
except ImportError:
SVG_AVAILABLE = False
print("Warning: svglib not available. Install with: pip install svglib")
try:
import cairosvg
CAIROSVG_AVAILABLE = True
except (ImportError, OSError) as e:
CAIROSVG_AVAILABLE = False
# Only show warning if it's an import error, not missing Cairo library
if isinstance(e, ImportError):
print("Warning: cairosvg not available. Install with: pip install cairosvg")
class PDFLabelGenerator:
"""Generate high-quality PDF labels with barcodes"""
"""Generate high-quality PDF labels with image and text"""
def __init__(self, label_width=11.5, label_height=8, dpi=300):
def __init__(self, label_width=3.5, label_height=2.5, dpi=600):
"""
Initialize PDF label generator.
Args:
label_width (float): Width in cm (default 11.5 cm)
label_height (float): Height in cm (default 8 cm)
dpi (int): DPI for barcode generation (default 300 for print quality)
label_width (float): Width in cm (default 3.5 cm = 35mm)
label_height (float): Height in cm (default 2.5 cm = 25mm)
dpi (int): DPI for image rendering (default 600 for high quality print)
"""
self.label_width = label_width * cm
self.label_height = label_height * cm
self.dpi = dpi
self.margin = 3 * mm # Minimal margin
self.margin = 1 * mm # Minimal margin
def generate_barcode_image(self, value, height_mm=18):
def load_image(self, image_path):
"""
Generate barcode image from text value.
Load and prepare image for embedding in PDF.
Args:
value (str): Text to encode in barcode (max 25 chars)
height_mm (int): Barcode height in mm (default 18mm for 1.8cm)
image_path (str): Path to image file
Returns:
PIL.Image or None: Generated barcode image
PIL.Image or None: Loaded image
"""
if not value or not value.strip():
if not image_path or not os.path.exists(image_path):
print(f"Image not found: {image_path}")
return None
try:
# Truncate to 25 characters (Code128 limitation)
value_truncated = value.strip()[:25]
# Create barcode
barcode_instance = Code128(value_truncated, writer=ImageWriter())
# Generate in memory using a temporary directory
temp_dir = tempfile.gettempdir()
temp_name = f"barcode_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S_%f')}"
temp_base_path = os.path.join(temp_dir, temp_name)
# Barcode options - generate at high DPI for quality
options = {
'write_text': False,
'module_width': 0.5, # Width of each bar in mm
'module_height': 8, # Height in mm
'quiet_zone': 2,
'font_size': 0
}
barcode_instance.save(temp_base_path, options=options)
# The barcode.save() adds .png extension automatically
temp_path = temp_base_path + '.png'
# Load and return image
img = Image.open(temp_path)
img = Image.open(image_path)
# Convert to RGB if needed
if img.mode != 'RGB':
if img.mode not in ['RGB', 'L']:
img = img.convert('RGB')
# Clean up temp file
try:
os.remove(temp_path)
except:
pass
return img
except Exception as e:
# Log error but don't fail silently
print(f"Barcode generation error for '{value}': {e}")
print(f"Image loading error: {e}")
return None
def create_label_pdf(self, sap_nr, cantitate, lot_number, filename=None):
def replace_svg_variables(self, svg_content, variables):
"""
Create a PDF label with three rows of data and barcodes.
Each row shows label name, barcode, and value text.
Replace variables in SVG template with actual values.
Args:
sap_nr (str): SAP article number
cantitate (str): Quantity value
lot_number (str): Lot/Cable ID
svg_content (str): SVG file content as string
variables (dict): Dictionary of variable replacements
Returns:
str: SVG content with replaced variables
"""
# Replace placeholders like {Article}, {NrArt}, {Serial}
for key, value in variables.items():
placeholder = f"{{{key}}}"
svg_content = svg_content.replace(placeholder, str(value or ''))
return svg_content
def create_label_from_svg_template(self, template_path, variables, filename=None):
"""
Create PDF label from SVG template with variable substitution.
Args:
template_path (str): Path to SVG template file
variables (dict): Dictionary with keys: Article, NrArt, Serial
filename (str): Output filename (if None, returns bytes)
Returns:
bytes or str: PDF content as bytes or filename if saved
"""
if not os.path.exists(template_path):
print(f"SVG template not found: {template_path}")
return None
try:
# Read SVG template
with open(template_path, 'r', encoding='utf-8') as f:
svg_content = f.read()
# Replace variables
svg_content = self.replace_svg_variables(svg_content, variables)
# Save modified SVG to temp file
temp_svg = tempfile.NamedTemporaryFile(mode='w', suffix='.svg', delete=False, encoding='utf-8')
temp_svg.write(svg_content)
temp_svg.close()
temp_svg_path = temp_svg.name
# Convert SVG to PDF
if filename:
pdf_output = filename
else:
pdf_output = tempfile.NamedTemporaryFile(suffix='.pdf', delete=False).name
# Try svglib first (more portable, no external dependencies)
if SVG_AVAILABLE:
try:
drawing = svg2rlg(temp_svg_path)
if drawing:
# Render at original size - quality depends on PDF rendering
# The PDF will contain vector graphics for sharp output
renderPDF.drawToFile(drawing, pdf_output)
# Clean up temp SVG
try:
os.remove(temp_svg_path)
except:
pass
if filename:
return pdf_output
else:
with open(pdf_output, 'rb') as f:
pdf_bytes = f.read()
os.remove(pdf_output)
return pdf_bytes
except Exception as svg_err:
print(f"svglib conversion failed: {svg_err}, trying cairosvg...")
# Fallback: Try cairosvg (requires system Cairo library)
if CAIROSVG_AVAILABLE:
try:
# Render at high DPI for sharp output
cairosvg.svg2pdf(url=temp_svg_path, write_to=pdf_output, dpi=self.dpi)
# Clean up temp SVG
try:
os.remove(temp_svg_path)
except:
pass
if filename:
return pdf_output
else:
with open(pdf_output, 'rb') as f:
pdf_bytes = f.read()
os.remove(pdf_output)
return pdf_bytes
except Exception as cairo_err:
print(f"CairoSVG conversion failed: {cairo_err}")
print("SVG conversion failed. svglib and cairosvg both unavailable or failed.")
return None
except Exception as e:
print(f"SVG template error: {e}")
traceback.print_exc()
return None
def create_label_pdf(self, comanda, article, serial, filename=None, image_path=None, svg_template=None):
"""
Create a PDF label with image on left and text on right.
Label: 35mm x 25mm landscape
Layout: 1/3 left = image, 2/3 right = 3 rows of text
Or use SVG template if provided.
Args:
comanda (str): Nr. Comanda value
article (str): Nr. Art. value
serial (str): Serial No. value
filename (str): Output filename (if None, returns bytes)
image_path (str): Path to accepted.png image
svg_template (str): Path to SVG template file (optional)
Returns:
bytes or str: PDF content as bytes or filename if saved
"""
# If SVG template is provided, use it instead
if svg_template and os.path.exists(svg_template):
variables = {
'Article': comanda,
'NrArt': article,
'Serial': serial,
'Comanda': comanda, # Alternative name
}
return self.create_label_from_svg_template(svg_template, variables, filename)
# Fallback to standard layout
# Prepare data for rows
rows_data = [
("SAP-Nr", sap_nr),
("Cantitate", cantitate),
("Lot Nr", lot_number),
("Nr. Comanda:", comanda),
("Nr. Art.:", article),
("Serial No.:", serial),
]
# Create PDF canvas in memory or to file
@@ -122,101 +229,76 @@ class PDFLabelGenerator:
# Create canvas with label dimensions
c = canvas.Canvas(pdf_buffer, pagesize=(self.label_width, self.label_height))
# Set higher resolution for better quality
c.setPageCompression(1) # Enable compression
# Calculate dimensions
usable_width = self.label_width - 2 * self.margin
row_height = (self.label_height - 2 * self.margin) / 3
usable_height = self.label_height - 2 * self.margin
# Draw each row - label name, barcode, and value text
for idx, (label_name, value) in enumerate(rows_data):
y_position = self.label_height - self.margin - (idx + 1) * row_height
# Image area: 1/3 of width on the left
image_width = usable_width / 3
image_x = self.margin
image_y = self.margin
image_height = usable_height
# Draw label name (small, at top of row)
c.setFont("Helvetica-Bold", 8)
c.drawString(
self.margin,
y_position + row_height - 3 * mm,
label_name
)
# Generate and draw barcode if value exists
if value and value.strip():
barcode_value = value.strip()[:25]
# Fixed barcode height: 1.6 cm (16mm) for optimal readability
barcode_height_mm = 16
barcode_height = barcode_height_mm * mm
# Text area: 2/3 of width on the right
text_area_x = self.margin + image_width + 1 * mm # Small gap
text_area_width = usable_width - image_width - 1 * mm
row_height = usable_height / 3
# Draw image on left if available
if image_path and os.path.exists(image_path):
try:
barcode_img = self.generate_barcode_image(barcode_value, height_mm=barcode_height_mm)
img = self.load_image(image_path)
if img:
# Save temp file for reportlab
temp_img_file = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
temp_img_path = temp_img_file.name
temp_img_file.close()
if barcode_img:
# Calculate barcode dimensions
max_barcode_width = usable_width - 2 * mm
aspect_ratio = barcode_img.width / barcode_img.height
barcode_width = barcode_height * aspect_ratio
# Convert to grayscale for black and white
img_bw = img.convert('L')
img_bw.save(temp_img_path, 'PNG')
# Constrain width to fit in label
if barcode_width > max_barcode_width:
barcode_width = max_barcode_width
# Save barcode temporarily and draw on PDF
barcode_temp = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
barcode_path = barcode_temp.name
barcode_temp.close()
barcode_img.save(barcode_path, 'PNG')
# Position barcode vertically centered in middle of row
barcode_y = y_position + (row_height - barcode_height) / 2
# Draw barcode image
# Draw image maintaining aspect ratio
c.drawImage(
barcode_path,
self.margin,
barcode_y,
width=barcode_width,
height=barcode_height,
preserveAspectRatio=True
)
# Draw small text below barcode showing the value
c.setFont("Helvetica", 6)
c.drawString(
self.margin,
barcode_y - 3 * mm,
f"({barcode_value})"
temp_img_path,
image_x,
image_y,
width=image_width,
height=image_height,
preserveAspectRatio=True,
anchor='c'
)
# Clean up
try:
os.remove(barcode_path)
os.remove(temp_img_path)
except:
pass
else:
# If barcode generation failed, show text
c.setFont("Helvetica", 10)
c.drawString(
self.margin,
y_position + row_height / 2,
f"[No Barcode: {barcode_value}]"
)
except Exception as e:
# Fallback: draw value as text with error indicator
print(f"PDF barcode error: {e}")
c.setFont("Helvetica", 10)
c.drawString(
self.margin,
y_position + row_height / 2,
f"[Text: {barcode_value}]"
)
print(f"Error drawing image: {e}")
# Draw text rows on right
for idx, (label_name, value) in enumerate(rows_data):
# Calculate y position for this row (top to bottom)
y_position = self.label_height - self.margin - (idx * row_height) - row_height/2
# Draw text with better quality
if value and value.strip():
text = f"{label_name} {value.strip()}"
else:
# Empty value - show placeholder
c.setFont("Helvetica", 8)
c.drawString(
self.margin,
y_position + row_height / 2,
"(empty)"
)
text = f"{label_name} -"
# Use appropriate font size to fit (6pt = ~2.1mm height)
font_size = 6
c.setFont("Helvetica-Bold", font_size)
try:
c.drawString(text_area_x, y_position, text)
except Exception as e:
print(f"Error drawing text row {idx}: {e}")
# Save PDF
c.save()
@@ -228,15 +310,16 @@ class PDFLabelGenerator:
pdf_buffer.seek(0)
return pdf_buffer.getvalue()
def create_label_pdf_file(self, sap_nr, cantitate, lot_number, filename=None):
def create_label_pdf_file(self, comanda, article, serial, filename=None, image_path=None):
"""
Create PDF label file and return the filename.
Args:
sap_nr (str): SAP article number
cantitate (str): Quantity value
lot_number (str): Lot/Cable ID
comanda (str): Nr. Comanda value
article (str): Nr. Art. value
serial (str): Serial No. value
filename (str): Output filename (if None, auto-generates)
image_path (str): Path to accepted.png image
Returns:
str: Path to created PDF file
@@ -245,51 +328,75 @@ class PDFLabelGenerator:
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"label_{timestamp}.pdf"
return self.create_label_pdf(sap_nr, cantitate, lot_number, filename)
return self.create_label_pdf(comanda, article, serial, filename, image_path)
def create_label_pdf_simple(text):
def create_label_pdf_simple(text, image_path=None, svg_template=None):
"""
Simple wrapper to create PDF from combined text (SAP|CANTITATE|LOT).
Simple wrapper to create PDF from combined text (article;nr_art;serial).
Args:
text (str): Combined text in format "SAP|CANTITATE|LOT"
text (str): Combined text in format "article;nr_art;serial"
image_path (str): Path to accepted.png image
svg_template (str): Path to SVG template file (optional, checks conf/label_template.svg by default)
Returns:
bytes: PDF content
"""
# Parse text
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 text - 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 ''
# Use default image path if not provided
if not image_path:
image_path = os.path.join('conf', 'accepted.png')
# Check for default SVG template if not provided
if not svg_template:
default_svg = os.path.join('conf', 'label_template.svg')
if os.path.exists(default_svg):
svg_template = default_svg
generator = PDFLabelGenerator()
pdf_bytes = generator.create_label_pdf(sap_nr, cantitate, lot_number)
pdf_bytes = generator.create_label_pdf(article, nr_art, serial, None, image_path, svg_template)
return pdf_bytes
def create_label_pdf_file(text, filename=None):
def create_label_pdf_file(text, filename=None, image_path=None, svg_template=None):
"""
Create PDF label file from combined text.
Args:
text (str): Combined text in format "SAP|CANTITATE|LOT"
text (str): Combined text in format "article;nr_art;serial"
filename (str): Output filename (auto-generates if None)
image_path (str): Path to accepted.png image
svg_template (str): Path to SVG template file (optional, checks conf/label_template.svg by default)
Returns:
str: Path to created PDF file
"""
# Parse text
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 text - 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 ''
if not filename:
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"label_{timestamp}.pdf"
# Use default image path if not provided
if not image_path:
image_path = os.path.join('conf', 'accepted.png')
# Check for default SVG template if not provided
if not svg_template:
default_svg = os.path.join('conf', 'label_template.svg')
if os.path.exists(default_svg):
svg_template = default_svg
generator = PDFLabelGenerator()
return generator.create_label_pdf(sap_nr, cantitate, lot_number, filename)
return generator.create_label_pdf(article, nr_art, serial, filename, image_path, svg_template)

View File

@@ -5,3 +5,7 @@ reportlab
pyinstaller>=6.0.0
pywin32
wmi
watchdog
svglib
cairosvg
pystray

1
sample_data.txt Normal file
View File

@@ -0,0 +1 @@
COM-2024-002;ART-67890;SN-20260212-TEST

159
test_svg_template.py Normal file
View File

@@ -0,0 +1,159 @@
"""
Test SVG template functionality
"""
import os
import sys
# Import the PDF generator
from print_label_pdf import PDFLabelGenerator
def test_svg_template():
"""Test SVG template with sample data"""
print("=== Testing SVG Template Functionality ===\n")
# Check if template exists
template_path = os.path.join('conf', 'label_template.svg')
if not os.path.exists(template_path):
print(f"❌ Template not found: {template_path}")
return False
print(f"✓ Template found: {template_path}")
# Sample data
test_data = {
'Article': 'COM-2024-001',
'NrArt': 'ART-12345',
'Serial': 'SN-20260212-001'
}
print(f"✓ Test data: {test_data}")
# Create generator
generator = PDFLabelGenerator()
print("✓ PDF generator initialized")
# Test SVG template method
print("\n--- Testing SVG Template Method ---")
try:
pdf_output = 'test_label_svg.pdf'
result = generator.create_label_from_svg_template(
template_path,
test_data,
filename=pdf_output
)
if result and os.path.exists(pdf_output):
file_size = os.path.getsize(pdf_output)
print(f"✓ SVG template PDF created: {pdf_output} ({file_size} bytes)")
return True
else:
print("❌ SVG template PDF creation failed")
return False
except Exception as e:
print(f"❌ Error: {e}")
import traceback
traceback.print_exc()
return False
def test_programmatic_layout():
"""Test programmatic layout (fallback)"""
print("\n--- Testing Programmatic Layout (Fallback) ---")
generator = PDFLabelGenerator()
try:
pdf_output = 'test_label_programmatic.pdf'
result = generator.create_label_pdf(
comanda='COM-2024-001',
article='ART-12345',
serial='SN-20260212-001',
filename=pdf_output,
image_path=os.path.join('conf', 'accepted.png')
)
if result and os.path.exists(pdf_output):
file_size = os.path.getsize(pdf_output)
print(f"✓ Programmatic layout PDF created: {pdf_output} ({file_size} bytes)")
return True
else:
print("❌ Programmatic layout PDF creation failed")
return False
except Exception as e:
print(f"❌ Error: {e}")
import traceback
traceback.print_exc()
return False
def test_wrapper_functions():
"""Test convenience wrapper functions"""
print("\n--- Testing Wrapper Functions ---")
from print_label_pdf import create_label_pdf_simple, create_label_pdf_file
# Test data string
test_string = "COM-2024-001;ART-12345;SN-20260212-001"
try:
# Test create_label_pdf_simple (returns bytes)
print("Testing create_label_pdf_simple()...")
pdf_bytes = create_label_pdf_simple(test_string)
if pdf_bytes:
print(f"✓ create_label_pdf_simple returned {len(pdf_bytes)} bytes")
else:
print("❌ create_label_pdf_simple failed")
return False
# Test create_label_pdf_file (returns filename)
print("Testing create_label_pdf_file()...")
pdf_file = create_label_pdf_file(test_string, filename='test_label_wrapper.pdf')
if pdf_file and os.path.exists(pdf_file):
file_size = os.path.getsize(pdf_file)
print(f"✓ create_label_pdf_file created: {pdf_file} ({file_size} bytes)")
return True
else:
print("❌ create_label_pdf_file failed")
return False
except Exception as e:
print(f"❌ Error: {e}")
import traceback
traceback.print_exc()
return False
if __name__ == '__main__':
print("SVG Template Test Suite\n")
print("=" * 50)
results = []
# Test 1: SVG template
results.append(("SVG Template", test_svg_template()))
# Test 2: Programmatic layout
results.append(("Programmatic Layout", test_programmatic_layout()))
# Test 3: Wrapper functions
results.append(("Wrapper Functions", test_wrapper_functions()))
# Summary
print("\n" + "=" * 50)
print("SUMMARY")
print("=" * 50)
for test_name, passed in results:
status = "✓ PASS" if passed else "❌ FAIL"
print(f"{status}: {test_name}")
total = len(results)
passed = sum(1 for _, p in results if p)
print(f"\nTotal: {passed}/{total} tests passed")
if passed == total:
print("\n🎉 All tests passed!")
sys.exit(0)
else:
print("\n⚠ Some tests failed")
sys.exit(1)