Weekend Project: Label Designer
I own a Brother QL-500 label printer. It's a cheap little machine that thermo prints self adhesive stickers. The printer is attached to my router which provides a simple print server on port 9100.
Of course the printer only comes with Windows software, but it's possible to run it with CUPS and use gLabels to create labels.
However I found that super cumbersome. Whenever I wanted to print a label I was fighting with CUPS not doing what I wanted. On some machines labels where cut off at the wrong places, on other machines the labels looked good, but more often then not the printer would just simply do nothing at all.
So I was very happy when I came across the Brother QL project by Philipp Klaus. He implemented the PTouch printer language in a pure Python library. That means you can send images directly to the printer – no printer drivers, no CUPS involved.
All that was missing was a tool to easily create the needed image to send to the printer. I wanted something web based that can run on our local Raspberry Pi. So that's what I build:
The BQL Label Printer software is available on Github.
This was actually a fun little exercise to build something useful without a whole lot of code. Python, JavaScript and CSS are each less than a hundred lines of code.
The way it works is rather simple. The GUI loads a label template which is simply a HTML file with a (few) inline styles that defines how the label texts should be arranged. Texts marked with a certain class can then be edited through a form. The resulting HTML is then converted into a PNG and sent to the backend which converts it into printer language and pushes it to the printer.
For the backend I used Flask. I had never used it before, but basically all I needed for this app was described in their Quickstart Guide. Very convenient.
Creating a PNG from a DOM node is surprisingly easy, using the DOM-to-Image library.
And all the basic styling (even though there is not much) is done by the very nice Sakura stylesheet.
So in the end I did not bother with a complicated build tool chain, but simply wrote the frontend bits in vanilla JavaScript and CSS. However for the JavaScript I decided to use ES6 stuff like fetch
, for…of
, const
, let
and promises
. So this really only works in modern browsers. In fact I never tried it in anything else than Chrome. YMMV.
Bonus Pics: