Printing 4-up tickets to hard copy printer

From Scribus Wiki
Jump to: navigation, search
This article is part of the Scripts series.

I needed to print about 400 tickets for a local Historical Society. There are 4 tickets on each page. Here's a sample of a single ticket.

Sample-ticket.png

Note: I purchased paper that was perforated exactly as I wanted from 'perforated paper dot com'. I have no relationship with them, aside from a single purchase, but they were great and really helped me avoid mistakes.

As you can see above, there are text boxes for the stub and the ticket proper. The stub is rotated 90 degrees. There are four smaller text boxes. Two are static and only contain the label 'No.". The other two are the ones in which we are most interested.

The text boxes are 'named' (highlighted in blue in the image above). Choose Tools->Properties, click on a text box, and choose the 'X,Y,Z' tab in the properties window to see the name field.

For the four tickets on the page, here is the naming scheme for the text boxes (num11 is set to the same number as num12; the same applies to all rows of the table):

Relative Position on page Stub Text Field Name Ticket Text Field Name
1 num11 num12
2 num21 num22
3 num31 num32
4 num41 num42

Note that this document only has one page! No need for multi-megabyte scribus files.

Using a Python script, I simply update the named fields with appropriate ticket numbers, and then hard-copy print the page. This is done in a loop, so (for example) to print tickets 001 through 800, the loop will execute 200 times, and print 200 hard-copy pages.

Note: I adapted the 'boilerplate.py' script for this use. My script appears below.

#!/usr/bin/env python2.4
# -*- coding: utf-8 -*-

import sys

try:
    # Please do not use 'from scribus import *' . If you must use a 'from import',
    # Do so _after_ the 'import scribus' and only import the names you need, such
    # as commonly used constants.
    import scribus
except ImportError,err:
    print "This Python script is written for the Scribus scripting interface."
    print "It can only be run from within Scribus."
    sys.exit(1)

#########################
# YOUR IMPORTS GO HERE  #
#########################
from scribus import Printer
from scribus import setText
from scribus import messageBox

def main(argv):
    """This is a documentation string. Write a description of what your code
    does here. You should generally put documentation strings ("docstrings")
    on all your Python functions."""
    #########################
    #  YOUR CODE GOES HERE  #
    #########################

    #
    #   This could use a GUI dialog box, but I simple edit the file and enter
    #   the two values here...

    startTicketNo=001
    endTicketNo=800

    #
    #   if you are printing a different number of tickets, you'll need to
    #   adjust the range() statement and include more/less calls to setText()
    #   to set the values of your named text fields.

    for idx in range(startTicketNo,endTicketNo,4):
        #
        #  Note: I wanted at least three positions to print, with leading
        #  zero-filled numbers.  If you want four positions, adjust
        #  the "00" string and the "-3" value to "000" and "-4".  The same
        #  logic applies to longer ticket numbers.
        #
        setText(unicode(("00" + `(idx)+0`)[-3:], 'iso-8859-1'), "num11")
        setText(unicode(("00" + `(idx)+0`)[-3:], 'iso-8859-1'), "num12")
        setText(unicode(("00" + `(idx)+1`)[-3:], 'iso-8859-1'), "num21")
        setText(unicode(("00" + `(idx)+1`)[-3:], 'iso-8859-1'), "num22")
        setText(unicode(("00" + `(idx)+2`)[-3:], 'iso-8859-1'), "num31")
        setText(unicode(("00" + `(idx)+2`)[-3:], 'iso-8859-1'), "num32")
        setText(unicode(("00" + `(idx)+3`)[-3:], 'iso-8859-1'), "num41")
        setText(unicode(("00" + `(idx)+3`)[-3:], 'iso-8859-1'), "num42")
        p = Printer()
        #   you will need to substitute the name of your printer here.
        p.printer = 'hp';
        p.Print()
        # debugging 
        # result = messageBox('Note', "Just printed tickets " + str(idx) + " through " + str(idx+3) )

def main_wrapper(argv):
    """The main_wrapper() function disables redrawing, sets a sensible generic
    status bar message, and optionally sets up the progress bar. It then runs
    the main() function. Once everything finishes it cleans up after the main()
    function, making sure everything is sane before the script terminates."""
    try:
    #result = messageBox('Monkeys!', 'Something went ook!', ICON_WARNING, BUTTON_YES|BUTTONOPT_DEFAULT, BUTTON_NO, BUTTON_IGNORE|BUTTONOPT_ESCAPE)
    scribus.statusMessage("Running script...")
    scribus.progressReset()
    main(argv)
    finally:
    # Exit neatly even if the script terminated with an exception,
    # so we leave the progress bar and status bar blank and make sure
    # drawing is enabled.
    if scribus.haveDoc():
        scribus.setRedraw(True)
    scribus.statusMessage("")
    scribus.progressReset()

# This code detects if the script is being run as a script, or imported as a module.
# It only runs main() if being run as a script. This permits you to import your script
# and control it manually for debugging.
if __name__ == '__main__':
    main_wrapper(sys.argv)


Notes:

  • This was tested with Scribus 1.2.4. I have 1.3.3, but I did not test with that version.
  • If you have an older version (before 1.3.3.10, I was told), someone posted the following to the Scribus mailing list. I thought it was valuable enough that it should be included here, given the great difficulty I had in finding the solution to the printing problem. I did not test this code.
p = Printer()
doPrint = getattr(p, "printNow", None)
if doPrint is None:
    doPrint = getattr(p, "print")
    doPrint()
  • From the mailing list: if you want to print directly to printer you must first find out what printers you have installed. Do this in the script console:
p = Printer();
print p.allPrinters;

It should print something like:
['Printer 1', 'Printer 2', 'File']