User Guide

This guide covers common use cases and patterns for the ptouch library.

Text Labels

Basic Text Label

Create a simple text label with default settings:

from ptouch import ConnectionNetwork, PTP900, TextLabel, Tape36mm
from PIL import ImageFont

connection = ConnectionNetwork("192.168.1.100")
printer = PTP900(connection)

font = ImageFont.load_default()
label = TextLabel("Hello World", Tape36mm, font=font)
printer.print(label)

Custom Font and Size

Use TrueType fonts with custom sizes:

from PIL import ImageFont

# Load custom font with specific size
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 48)

# Auto-sizing is disabled when font has explicit size
label = TextLabel("Custom Font", Tape36mm, font=font, auto_size=False)

# Or let the library auto-size to 80% of tape height
label = TextLabel("Auto Sized", Tape36mm, font=font, auto_size=True)

Text Alignment

Control horizontal and vertical alignment:

# Horizontal: LEFT, HCENTER, RIGHT
# Vertical: TOP, VCENTER, BOTTOM
# Combined: CENTER = HCENTER | VCENTER

label = TextLabel(
    "Centered",
    Tape36mm,
    font=font,
    align=TextLabel.Align.CENTER  # Center both ways
)

label = TextLabel(
    "Top Left",
    Tape36mm,
    font=font,
    align=TextLabel.Align.LEFT | TextLabel.Align.TOP
)

label = TextLabel(
    "Bottom Right",
    Tape36mm,
    font=font,
    align=TextLabel.Align.RIGHT | TextLabel.Align.BOTTOM
)

Fixed Width Labels

Create labels with specific width:

# Create 50mm wide label (useful for consistent sizing)
label = TextLabel(
    "Short",
    Tape36mm,
    font=font,
    width_mm=50.0
)

Image Labels

Basic Image Label

Print images directly:

from PIL import Image
from ptouch import Label, Tape36mm

# Load image
image = Image.open("logo.png")

# Create label and print
label = Label(image, Tape36mm)
printer.print(label, margin_mm=3.0)

Creating Custom Images

Generate labels programmatically:

from PIL import Image, ImageDraw, ImageFont

# Create blank image (360 DPI for P900)
# 36mm tape = ~32mm printable = 454 pixels at 360 DPI
width = 800  # Adjust as needed
height = 454
img = Image.new("RGB", (width, height), "white")
draw = ImageDraw.Draw(img)

# Draw content
font = ImageFont.truetype("/path/to/font.ttf", 48)
draw.text((10, 200), "Custom Label", font=font, fill="black")
draw.rectangle([10, 10, 790, 444], outline="black", width=3)

# Print
label = Label(img, Tape36mm)
printer.print(label)

QR Code Labels

Create QR code labels:

import qrcode
from PIL import Image

# Generate QR code
qr = qrcode.QRCode(version=1, box_size=10, border=4)
qr.add_data("https://example.com")
qr.make(fit=True)

img = qr.make_image(fill_color="black", back_color="white")

# Print
label = Label(img.convert("RGB"), Tape36mm)
printer.print(label)

Multi-Label Printing

Printing Multiple Copies

Command line:

ptouch "Asset Tag" --copies 5 --host 192.168.1.100 \
    --printer P900 --tape-width 12

Python:

for i in range(5):
    label = TextLabel(f"Asset {i:03d}", Tape12mm, font=font)
    printer.print(label)

Connection Management

Network Connection

from ptouch import ConnectionNetwork

# Default port 9100
connection = ConnectionNetwork("192.168.1.100")

# Custom port
connection = ConnectionNetwork("192.168.1.100", port=9100)

USB Connection

from ptouch import ConnectionUSB

# Find first available Brother printer
connection = ConnectionUSB()

# Specify product ID (vendor defaults to Brother 0x04f9)
connection = ConnectionUSB(product_id=0x2086)

# Connect to specific device by serial number (useful with multiple printers)
connection = ConnectionUSB(product_id=0x2086, serial="A1B2C3D4E5")

# Specify all parameters
connection = ConnectionUSB(
    vendor_id=0x04f9,
    product_id=0x2086,
    serial="A1B2C3D4E5"
)

USB URI (CLI)

The CLI supports a URI format for specifying USB devices:

# Basic USB connection (auto-detect)
ptouch "Hello" --usb --printer P950NW --tape-width 12

# Specify product ID
ptouch "Hello" --usb usb://:0x2086 --printer P950NW --tape-width 12

# Specify serial number (for multiple printers)
ptouch "Hello" --usb usb://:0x2086/A1B2C3D4E5 --printer P950NW --tape-width 12

# Full URI with vendor
ptouch "Hello" --usb usb://0x04f9:0x2086/A1B2C3D4E5 --printer P950NW --tape-width 12

You can also parse USB URIs programmatically:

from ptouch import parse_usb_uri, ConnectionUSB

# Parse URI string
vendor_id, product_id, serial = parse_usb_uri("usb://:0x2086/A1B2C3D4E5")

# Create connection from parsed values
connection = ConnectionUSB(
    vendor_id=vendor_id,
    product_id=product_id,
    serial=serial
)

Error Handling

Exception Hierarchy

The library provides specific exception types:

from ptouch import (
    PrinterConnectionError,     # Base exception
    PrinterNotFoundError,        # Device not found
    PrinterPermissionError,      # Permission denied (USB)
    PrinterNetworkError,         # Network errors
    PrinterTimeoutError,         # Timeout errors
    PrinterWriteError,           # Write failures
)

Comprehensive Error Handling

try:
    printer.print(label)
    print("Label printed successfully")

except PrinterPermissionError:
    print("Permission denied")
    print("  Run with sudo or configure udev rules")
    print("  See: https://ptouch.readthedocs.io/en/latest/installation.html")

except PrinterTimeoutError:
    print("Printer not responding")
    print("  - Check if printer is powered on")
    print("  - Verify network connection")
    print("  - Check IP address is correct")

except PrinterNotFoundError:
    print("Printer not found")
    print("  - Check USB connection")
    print("  - Verify printer is powered on")
    print("  - Check product ID matches your model")

except PrinterNetworkError as e:
    print(f"Network error: {e}")
    print("  - Check network connectivity")
    print("  - Verify firewall settings")

except PrinterWriteError as e:
    print(f"Write error: {e}")
    print("  - Check USB cable")
    print("  - Try a different USB port")

except PrinterConnectionError as e:
    print(f"General connection error: {e}")

Accessing Original Errors

All exceptions preserve the original error:

try:
    printer.print(label)
except PrinterConnectionError as e:
    print(f"Error: {e}")
    if e.original_error:
        print(f"Original: {e.original_error}")

Next Steps