Fix printing via a Brother QL

This commit is contained in:
n07070
2026-11-12 15:34:03 +01:00
parent 704b7b83cd
commit 99bf70d3f7
2 changed files with 51 additions and 81 deletions

View File

@@ -20,10 +20,11 @@ import numpy as np
# Importing the modules needed for each supported printer Type
import escpos.printer
from brother_ql.models import ModelsManager
from brother_ql.backends import backend_factory
from brother_ql.backends import backend_factory, guess_backend
from brother_ql.raster import BrotherQLRaster
from brother_ql.conversion import convert
from brother_ql.backends.helpers import send
from brother_ql import create_label
class PrinterType(Enum):
@@ -444,6 +445,7 @@ class BrotherPrinter(Printer):
vendor_id=vendor_id,
product_id=self.device_id,
serial_number=serial_number,
label_type="62",
)
self.app.logger.debug("Created a Brother printer !")
self.ready = True
@@ -462,86 +464,49 @@ class BrotherPrinter(Printer):
"""
Print a raster image via a Brother QL printer
"""
# TODO : make this label type go in the configuration
label_type = "62"
rotate = 0
dither = False
data = _process_image(self, path=data, max_width=720, max_height=720)
self.app.logger.debug("Printing image %s", data)
self.ready = False
try:
# Prepare the image for printing
qlr = BrotherQLRaster(self.printer_info["model"])
instructions = convert(
qlr=qlr,
images=[data],
label=label_type,
rotate=rotate,
threshold=70,
dither=dither,
compress=True,
red=False,
dpi_600=False,
hq=False,
cut=True,
)
# Debug logging
if os.getenv("FLASK_DEBUG"):
self.app.logger.debug(f"""
Print parameters:
- Label type: {label_type}
- Rotate: {rotate}
- Dither: {dither}
- Model: {self.printer_info['model']}
- Backend: {self.printer_info['backend']}
- Identifier: {self.printer_info['identifier']}
""")
# Try to print using Python API
# send() = status = {
# 'instructions_sent': True, # The instructions were sent to the printer.
# 'outcome': 'unknown', # String description of the outcome of the sending operation like: 'unknown', 'sent', 'printed', 'error'
# 'printer_state': None, # If the selected backend supports reading back the printer state, this key will contain it.
# 'did_print': False, # If True, a print was produced. It defaults to False if the outcome is uncertain (due to a backend without read-back capability).
# 'ready_for_next_job': False, # If True, the printer is ready to receive the next instructions. It defaults to False if the state is unknown.
# }
status = send(
instructions=instructions,
printer_identifier=self.printer_info["identifier"],
backend_identifier="pyusb",
)
self.app.logger.debug("Status: " + str(status))
if (
not status["did_print"]
or status["outcome"] == "error"
or status["outcome"] == "unknown"
):
raise RuntimeError("Failed to print using Python API")
# if status["printer_state"]:
# self.ready = bool(status["printer_state"])
# self.app.logger.debug("Printer is borky : " + str(self.ready))
# else:
# self.ready = True
except usb.core.USBError as e:
# Treat timeout errors as successful since they often occur after print completion
if e.errno == 110: # Operation timed out
self.app.logger.debug(
"USB timeout occurred - this is normal and the print likely completed"
)
self.app.logger.debug("Print completed (timeout is normal)")
self.ready = True
self.app.logger.debug(f"USBError encountered: {e}")
raise RuntimeError from e
selected_backend = guess_backend(self.printer_info.identifier)
BACKEND_CLASS = backend_factory(selected_backend)['backend_class']
BACKEND_STRING_DESCR = self.printer_info.identifier
except Exception as e:
self.app.logger.debug(f"Unexpected error during printing: {str(e)}")
raise RuntimeError from e
self.app.logger.error("Couldn't guess the backend to use from the printer string descriptor")
try:
im = Image.open(data)
qlr = BrotherQLRaster(self.printer_info.model)
create_label(qlr, im, self.printer_info.label_type, threshold=70, cut=False, rotate=0)
# noinspection PyCallingNonCallable
be = BACKEND_CLASS(BACKEND_STRING_DESCR)
be.write(qlr.data)
be.dispose()
del be
except Exception as e:
raise e
def _cut(self):
self.ready = False
try:
selected_backend = guess_backend(self.printer_info.identifier)
BACKEND_CLASS = backend_factory(selected_backend)['backend_class']
BACKEND_STRING_DESCR = self.printer_info.identifier
except Exception as e:
self.app.logger.error("Couldn't guess the backend to use from the printer string descriptor")
data = "src/static/images/1x1.png"
try:
im = Image.open(data)
qlr = BrotherQLRaster(self.printer_info.model)
create_label(qlr, im, self.printer_info.label_type, threshold=70, cut=True, rotate=0)
# noinspection PyCallingNonCallable
be = BACKEND_CLASS(BACKEND_STRING_DESCR)
be.write(qlr.data)
be.dispose()
del be
except Exception as e:
raise e
def print_task(self, task_type, data):
"""Execute actual print based on task type"""
@@ -551,9 +516,10 @@ class BrotherPrinter(Printer):
match (task_type.value):
case "image":
self._print_img(data["img"])
self.ready = True
case "cut":
# The cut happens by default on Brother QL printers.
pass
self._cut()
self.ready = True
case "text":
self._print_txt(data["txt"], signature=data["sign"])
self.ready = True