Skip to content

Print text and image labels on Brother P-touch printers via USB or network

License

Notifications You must be signed in to change notification settings

nbuchwitz/ptouch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ptouch

Tests Linting Documentation Status

A Python library for Brother P-touch label printers.

Features

  • Support for Brother P-touch label printers (PT-E550W, PT-P750W, PT-P900, PT-P900W, PT-P910BT, PT-P950NW)
  • Network (TCP/IP) and USB connections
  • Text labels with customizable fonts and alignment
  • Image label printing
  • Multi-label printing with half-cut support (saves tape)
  • Heat shrink tube support (HSe 2:1 and 3:1 series on PT-E550W/P750W/P900/P900W/P950NW)
  • High resolution mode support
  • TIFF compression for efficient data transfer

Installation

pip install ptouch

Dependencies

  • Python 3.11+
  • Pillow
  • packbits

For USB support:

  • pyusb

Documentation

Comprehensive documentation is available at ptouch.readthedocs.io including:

Supported Devices

Printers

Printer Resolution High-Res Pins Max Tape Width Class
PT-E550W 180 DPI 360 DPI 128 24mm PTE550W
PT-P750W 180 DPI 360 DPI 128 24mm PTP750W
PT-P900 360 DPI 720 DPI 560 36mm PTP900
PT-P900W 360 DPI 720 DPI 560 36mm PTP900W
PT-P910BT 360 DPI 720 DPI 560 36mm PTP910BT
PT-P950NW 360 DPI 720 DPI 560 36mm PTP950NW

Tapes

Type Widths Class Notes
TZe (Laminated) 3.5mm, 6mm, 9mm, 12mm, 18mm, 24mm, 36mm Tape*mm All printers
HSe 2:1 (Heat Shrink) 5.8mm, 8.8mm, 11.7mm, 17.7mm, 23.6mm HeatShrinkTube*mm E550W/P750W/P900/P900W/P950NW
HSe 3:1 (Heat Shrink) 5.2mm, 9.0mm, 11.2mm, 21.0mm, 31.0mm HeatShrinkTube3_1_*mm E550W/P750W: up to 21mm; P900: all

Adding Support for New Devices

Adding a New Printer

To add support for a new P-touch printer, create a subclass of LabelPrinter in ptouch/printers.py:

from ptouch.printer import LabelPrinter, TapeConfig
from ptouch.tape import Tape12mm, Tape24mm  # etc.

class PTP710BT(LabelPrinter):
    """Brother PT-P710BT label printer."""

    # USB product ID (required for USB connections)
    USB_PRODUCT_ID = 0x20XX   # Replace with actual product ID

    # Print head specifications (from Brother raster command reference)
    TOTAL_PINS = 128          # Total pins in print head
    BYTES_PER_LINE = 16       # TOTAL_PINS / 8
    RESOLUTION_DPI = 180      # Base resolution
    RESOLUTION_DPI_HIGH = 360 # High resolution (0 if not supported)

    # Capability flags - what the printer supports
    SUPPORTS_AUTO_CUT = True
    SUPPORTS_HALF_CUT = True
    SUPPORTS_PAGE_NUMBER_CUTS = True

    # Default values for each feature (used when not specified at print time)
    DEFAULT_USE_COMPRESSION = True
    DEFAULT_AUTO_CUT = True
    DEFAULT_HALF_CUT = True
    DEFAULT_HIGH_RESOLUTION = False
    DEFAULT_PAGE_NUMBER_CUTS = False

    # Pin configuration for each tape width
    # Values from Brother raster command reference PDF
    PIN_CONFIGS = {
        Tape12mm: TapeConfig(left_pins=29, print_pins=70, right_pins=29),
        Tape24mm: TapeConfig(left_pins=0, print_pins=128, right_pins=0),
        # Add more tape sizes as needed
    }

The pin configuration values (left_pins, print_pins, right_pins) can be found in the Brother raster command reference documentation for your printer model.

Adding a New Tape Type

To add a new tape type, create a subclass of Tape in ptouch/tape.py:

from ptouch.tape import Tape

class Tape48mm(Tape):
    """48mm tape."""
    width_mm = 48

Then add the corresponding TapeConfig entries to each printer class that supports the tape

Usage

Command Line

When the package is installed, the ptouch command is available (or use python -m ptouch when running from source):

# Print text label via network (uses PIL default font)
ptouch "Hello World" --host 192.168.1.100 --printer P900 --tape-width 36

# Print with custom font
ptouch "Hello World" --host 192.168.1.100 --printer P900 \
    --tape-width 36 --font /path/to/font.ttf

# Print multiple labels (half-cut between, full cut after last)
ptouch "Label 1" "Label 2" "Label 3" --host 192.168.1.100 \
    --printer P900 --tape-width 12

# Print multiple labels with full cuts between each
ptouch "Label 1" "Label 2" --full-cut --host 192.168.1.100 \
    --printer P900 --tape-width 12

# Print image label via USB
ptouch --image logo.png --usb --printer E550W --tape-width 12

# Print with fixed font size (disables auto-sizing)
ptouch "Test" --host 192.168.1.100 --printer P900 --tape-width 24 \
    --font-size 48 --high-resolution --align left top --margin 5

# Print 5 copies of a label
ptouch "Asset Tag" --copies 5 --host 192.168.1.100 \
    --printer P900 --tape-width 12

# Print label with fixed width (50mm)
ptouch "Short" --width 50 --host 192.168.1.100 \
    --printer P900 --tape-width 12

Python API

Text Labels

from ptouch import (
    ConnectionNetwork,
    PTP900,
    TextLabel,
    Tape36mm,
)

# Connect to printer
connection = ConnectionNetwork("192.168.1.100")
printer = PTP900(connection, high_resolution=True)

# Create and print text label
label = TextLabel(
    "Hello World",
    Tape36mm,
    font="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
    align=TextLabel.Align.CENTER,
)
printer.print(label)

# Or use a pre-loaded ImageFont (auto-sized by default)
from PIL import ImageFont
font = ImageFont.truetype("/path/to/font.ttf", size=48)
label = TextLabel("Custom Font", Tape36mm, font=font)

# Use ImageFont with its built-in size (disable auto-sizing)
label = TextLabel("Fixed Size", Tape36mm, font=font, auto_size=False)

# For quick testing, use the default font (requires Pillow 10.1+)
label = TextLabel("Quick Test", Tape36mm, font=ImageFont.load_default())

Image Labels

from PIL import Image
from ptouch import ConnectionNetwork, PTP900, Label, Tape36mm

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

image = Image.open("label.png")
label = Label(image, Tape36mm)
printer.print(label, margin_mm=3.0)

USB Connection

from ptouch import ConnectionUSB, PTE550W, TextLabel, Tape12mm

connection = ConnectionUSB()
printer = PTE550W(connection)

label = TextLabel(
    "USB Label",
    Tape12mm,
    font="/path/to/font.ttf",
)
printer.print(label)

Multi-Label Printing

Print multiple labels in a single job with half-cuts between labels to save tape:

from ptouch import ConnectionNetwork, PTP900, TextLabel, Tape12mm

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

labels = [
    TextLabel("Label 1", Tape12mm, font="/path/to/font.ttf"),
    TextLabel("Label 2", Tape12mm, font="/path/to/font.ttf"),
    TextLabel("Label 3", Tape12mm, font="/path/to/font.ttf"),
]

# Half-cuts between labels (default), full cut after last
printer.print_multi(labels)

# Or use full cuts between all labels
printer.print_multi(labels, half_cut=False)

Alignment Options

Text alignment can be combined using the | operator:

from ptouch import TextLabel

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

align = TextLabel.Align.LEFT | TextLabel.Align.TOP
align = TextLabel.Align.RIGHT | TextLabel.Align.BOTTOM
align = TextLabel.Align.CENTER  # centered both ways

Note: Align is also available as a backwards-compatible alias at package level.

CLI Options

usage: ptouch [-h] [--image FILE] (--host IP | --usb) --printer {E550W,P750W,P900,P900W,P950NW}
              --tape-width {3.5,6,9,12,18,24,36} [--font PATH] [--font-size PX]
              [--align H V] [--high-resolution] [--margin MM] [--no-compression]
              [--full-cut] [--copies N] [--width MM] [text ...]

positional arguments:
  text                  Text to print. Multiple strings create multiple labels
                        with half-cut between (required unless --image is used)

options:
  --image, -i FILE      Image file to print instead of text
  --host, -H IP         Printer IP address for network connection
  --usb                 Use USB connection
  --printer, -p         Printer model
  --tape-width, -t      Tape width in mm
  --font, -f PATH       Path to TrueType font file (uses PIL default if not specified)
  --font-size PX        Font size in pixels (disables auto-sizing to 80% of print height)
  --align, -a H V       Horizontal and vertical alignment (default: center center)
  --high-resolution     Enable high resolution mode
  --margin, -m MM       Margin in mm (default: 2mm)
  --no-compression      Disable TIFF compression
  --full-cut            Use full cuts between labels instead of half-cuts
  --copies, -c N        Number of copies to print (default: 1)
  --width, -w MM        Fixed label width in mm (default: auto-sized to content)

Error Handling

The library provides a hierarchy of exception classes for targeted error handling:

from ptouch import (
    PrinterConnectionError,     # Base exception for all connection errors
    PrinterNotFoundError,        # Printer device not found
    PrinterPermissionError,      # Permission denied (USB requires sudo/udev rules)
    PrinterNetworkError,         # Network connection/communication errors
    PrinterTimeoutError,         # Connection or operation timeout
    PrinterWriteError,           # Failed to write data to printer
)

try:
    printer.print(label)
except PrinterPermissionError:
    print("Permission denied. Try running with sudo or configure udev rules.")
except PrinterTimeoutError:
    print("Printer not responding. Check connection and power.")
except PrinterNotFoundError:
    print("Printer not found. Check if device is connected.")
except PrinterConnectionError:
    print("General connection error occurred.")

All specific exceptions inherit from PrinterConnectionError, allowing you to catch all connection-related errors with a single except clause, or handle specific error types individually for more targeted error handling.

License

LGPL-2.1-or-later - see LICENSE for details.

Author

Nicolai Buchwitz nb@tipi-net.de

About

Print text and image labels on Brother P-touch printers via USB or network

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages