Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Placing graphics & text on printed page - jan06call.jpg (0/1)

7 views
Skip to first unread message

Michael Galvin

unread,
Jan 12, 2006, 12:16:02 PM1/12/06
to
I am trying to use Python to send to the printer a calender filled
with a mix of text and simple graphics. I want to draw on the printed
page something like a table with 6 rows and 7 columns to represent a
calendar. I want to place text precisely within those boxes on the
printed page. I am using Python 2.4 on Windows XP

I was in the past able to do this within Visual Basic using its
printer object. Visual Basic's printer object uses a coordinate
system to allow you to draw lines and to place text on the printed
page precisely. I have attached a file "jan06call.jpg" to this message
to illustrate what I am trying to do.

Does Python have a module which would help me do this?

To put it another way, can Python control the placement of text and
graphics precisely on the printed page?

I have scoured my Python programming texts, python.org, and this
usenet group without success. Mark Lutz's wonderful book "Programming
Python" has not one reference to the word "printer" in its index.
Surely, I must be overlooking something or thinking about this wrong.

Michael Galvin
Muskegon, MI

Michael Galvin

unread,
Jan 12, 2006, 12:55:06 PM1/12/06
to
To see an example of what I am trying to accomplish, look at this page
on my personal website:

http://mysite.verizon.net/michaelgalvin/jan06call.html

I now realize my attachement could not be posted on this usenet group.

Steve Holden

unread,
Jan 12, 2006, 1:19:38 PM1/12/06
to pytho...@python.org
Michael Galvin wrote:
> To see an example of what I am trying to accomplish, look at this page
> on my personal website:
>
> http://mysite.verizon.net/michaelgalvin/jan06call.html
>
> I now realize my attachement could not be posted on this usenet group.
>
I suspect your best option would be to use ReportLab's open source
package (www.reportlab.org) to generate PDF files.

You may, however, be able to get at the Windows device context through
wxPython (www.wxpython.org): if you download the demonstration you'll
see that on Windows they do send fairly arbitrary graphics to the
Windows printer queue.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Manlio Perillo

unread,
Jan 12, 2006, 1:43:25 PM1/12/06
to
Michael Galvin ha scritto:

> I am trying to use Python to send to the printer a calender filled
> with a mix of text and simple graphics. I want to draw on the printed
> page something like a table with 6 rows and 7 columns to represent a
> calendar. I want to place text precisely within those boxes on the
> printed page. I am using Python 2.4 on Windows XP
>
> I was in the past able to do this within Visual Basic using its
> printer object. Visual Basic's printer object uses a coordinate
> system to allow you to draw lines and to place text on the printed
> page precisely. I have attached a file "jan06call.jpg" to this message
> to illustrate what I am trying to do.
>
> Does Python have a module which would help me do this?
>

You can try to use pycairo for graphics, using postscript as a backend.
Then print the postscript file (with Ghostscript).

Or you can use a more high level tool.

Regards Manlio Perillo

Roger Upole

unread,
Jan 12, 2006, 6:29:47 PM1/12/06
to
Pywin32 wraps most of the GDI functions used to draw
lines and text directly on a printer device context.
Many of them are only implemented as methods of
MFC objects rather than exposed directly.

See \win32\Demos\print_desktop.py for some examples
of working directly with a printer DC.

hth
Roger

"Michael Galvin" <michae...@verizon.net> wrote in message news:aq5ds1lsop1m2gkfu...@4ax.com...

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----

Paul Boddie

unread,
Jan 12, 2006, 8:18:16 PM1/12/06
to
Steve Holden wrote:
> Michael Galvin wrote:
> > To see an example of what I am trying to accomplish, look at this page
> > on my personal website:
> >
> > http://mysite.verizon.net/michaelgalvin/jan06call.html
> >
> > I now realize my attachement could not be posted on this usenet group.
> >
> I suspect your best option would be to use ReportLab's open source
> package (www.reportlab.org) to generate PDF files.

One alternative, although I'm not convinced that it is actively
maintained any more, is the Piddle/Sping library [1]. As mentioned
elsewhere, the Cairo bindings would provide a similar developer
experience to that, and Cairo is increasingly fashionable.

> You may, however, be able to get at the Windows device context through
> wxPython (www.wxpython.org): if you download the demonstration you'll
> see that on Windows they do send fairly arbitrary graphics to the
> Windows printer queue.

PyQt [2] seems to support printing fairly conveniently. Consider this
very simple example:

from qt import *
import sys
qapp = QApplication(sys.argv)
printer = QPrinter(QPrinter.PrinterResolution)
printer.setPageSize(printer.A4)
printer.setOutputToFile(1)
printer.setOutputFileName("qtprint.ps")
painter = QPainter(printer)
painter.drawText(painter.window(), painter.AlignCenter, "Hello")
painter.end()

I haven't used printing in Qt [3] before, so apologies must go out if
I've made fundamental mistakes in the above code which did, admittedly,
produce output that resembled my expectations. Another route might be
to use a Tkinter canvas - at least in times of old, such canvases were
able to dump their contents as PostScript.

Paul

[1] http://piddle.sourceforge.net/
[2] http://www.riverbankcomputing.co.uk/pyqt/index.php
[3] http://doc.trolltech.com/3.3/graphics.html

Kevin

unread,
Jan 15, 2006, 9:32:37 AM1/15/06
to
One option is to create your page as an image file using PIL (which can
handle your text and drawing requirements, as well as any
pictures/graphics), then print it to a windows printer using my
ImagePrintWin module.

ImagePrintWin can print to any normal windows printer, and includes an
optional GUI for doing a "Printer Setup" type dialog (including preview).
It can even handle ICC profiles for your printer if you want color accuracy.

You can download ImagePrintWin (GPL'd) from my site at:

http://www.cazabon.com/python/downloads/ImagePrintWin.py


The pyCMS module for doing ICC is available also on my site at:

http://www.cazabon.com/pyCMS/

Kevin Cazabon.

"Michael Galvin" <michae...@verizon.net> wrote in message

news:qj1ds1d5msb9l6di4...@4ax.com...

eric.howland

unread,
Jan 28, 2006, 11:00:02 PM1/28/06
to

This does something like you want using piddle. It is designed to make
a pdf of a calendar on a sheet of paper that has times blocked out (the
add_data and print_action methods).

import sys, os, string, re, calendar, time, datetime, copy
from optparse import OptionParser
from piddlePDF import *

class output_pdf:

setup = { #constants to use for spacing
"upperleftx": 0.75*72,
"upperlefty": 1*72,
"rowoffset": 2.0 * 72,
"coloffset": 1.0 * 72,
"vert_margin": 25,
"horz_margin": 25,
}

canvas = PDFCanvas() # backend you want to test
def __init__(self, year, month, title ):
### global canvas
self.printcal( year, month, title)

def printcal(self, year, month, label):
""" prints the days, and times and outside boxes for each day.
sets up a dictionary with the x and y offset for each day.
"""
global calpos
calpos = {}

wkdaytxt = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat']
calendar.setfirstweekday(calendar.SUNDAY)

# use calendar to figure out days for dates (a list of lists)
month_cal= calendar.monthcalendar( year, month)
#figure out how many weeks and days
daywk1st, days= calendar.monthrange( year, month)

if len(month_cal) == 6: self.setup["rowoffset"] = 1.8*72

self.canvas.drawString(label,
10,
self.setup["upperlefty"]- 40,
Font(face="sansserif",size=16,bold=1),
color=green)


for row, wk in enumerate(month_cal):
topy = self.setup["upperlefty"]+ row*self.setup["rowoffset"]
self.canvas.drawString('00:00', 10, topy+4,
Font(face="sansserif",size=8,bold=1),
color=darkorange)
self.canvas.drawString('12:00', 10,
topy+4+(self.setup["rowoffset"]-self.setup["vert_margin"])*.5 ,
Font(face="sansserif",size=8,bold=1),
color=darkorange)
self.canvas.drawLine( self.setup["upperleftx"]-10,

topy+(self.setup["rowoffset"]-self.setup["vert_margin"])*.5,
self.setup["upperleftx"]+
7*self.setup["coloffset"],

topy+(self.setup["rowoffset"]-self.setup["vert_margin"])*.5,
color=darkorange, width=1 )
self.canvas.drawString('08:00', 10,
topy+4+(self.setup["rowoffset"]-self.setup["vert_margin"])*(8/24.0) ,
Font(face="sansserif",size=6,bold=1),
color=darkorange)
self.canvas.drawLine( self.setup["upperleftx"]-10,

topy+(self.setup["rowoffset"]-self.setup["vert_margin"])*(8/24.0),
self.setup["upperleftx"]+
7*self.setup["coloffset"],

topy+(self.setup["rowoffset"]-self.setup["vert_margin"])*(8/24.0),
color=darkorange, width=1 )
self.canvas.drawString('17:00', 10,
topy+4+(self.setup["rowoffset"]-self.setup["vert_margin"])*(17/24.0) ,
Font(face="sansserif",size=6,bold=1),
color=darkorange)
self.canvas.drawLine( self.setup["upperleftx"]-10,

topy+(self.setup["rowoffset"]-self.setup["vert_margin"])*(17/24.0),
self.setup["upperleftx"]+
7*self.setup["coloffset"],

topy+(self.setup["rowoffset"]-self.setup["vert_margin"])*(17/24.0),
color=darkorange, width=1 )
self.canvas.drawString('24:00', 10,
topy+4+(self.setup["rowoffset"]-self.setup["vert_margin"]) ,
Font(face="sansserif",size=8,bold=1),
color=darkorange)

for col, date in enumerate(wk):
topx = self.setup["upperleftx"]+
col*self.setup["coloffset"]
self.canvas.drawString(wkdaytxt[col],
topx,
self.setup["upperlefty"]*.7,
Font(face="sansserif",size=16,bold=1),
color=green)
topx = self.setup["upperleftx"]+
col*self.setup["coloffset"]
topy = self.setup["upperlefty"]+
row*self.setup["rowoffset"]
calpos[date] = (topx, topy)


for i in range(days):
topx, topy = calpos[i+1]

self.canvas.drawRect( topx, topy,

(topx+(self.setup["coloffset"]-self.setup["horz_margin"])),

(topy+(self.setup["rowoffset"]-self.setup["vert_margin"])),
edgeColor=black, edgeWidth=2,
fillColor=transparent)
self.canvas.drawString('%d'%(i+1), topx, topy-2 ,
Font(face="sansserif",size=12,bold=1),
color=red)

def date_str2value(self,intime):
tuple_names = ["tm_year", "tm_mon", "tm_mday", "tm_hour",
"tm_min", "tm_sec", "tm_wday", "tm_yday", "tm_isdst"]
t_tuple = time.localtime(intime)
t_dict = {}
for i, name in enumerate(tuple_names):
t_dict[name] = t_tuple[i]
floattime = (float(t_dict['tm_hour'])*60 +
float(t_dict['tm_min']))/float(24*60)

return t_dict, floattime

def print_action(self,year,month, action):
##action_list = re.split(r'\t', action)
##starttime = action_list[1]
##endtime = action_list[2]
client = action['destination']

s_dict, s_time = self.date_str2value(action['start_sec'])
e_dict, e_time = self.date_str2value(action['stop_sec'])
##print s_dict, s_time, ":-:", e_dict, e_time
if (s_dict['tm_mday'] == e_dict['tm_mday'] and
s_dict['tm_mon'] == int(month) and
s_dict['tm_year'] == int(year)):
topx, topy = calpos[s_dict['tm_mday']]
ypos_start = topy + (s_time *
(self.setup["rowoffset"]-self.setup["vert_margin"]))
ypos_end = topy + (e_time *
(self.setup["rowoffset"]-self.setup["vert_margin"]))
right_side = topx +
(self.setup["coloffset"]-self.setup["horz_margin"])

self.canvas.drawRect( topx, ypos_start,
right_side, ypos_end,
edgeColor=black, edgeWidth=1,
fillColor=skyblue)
self.canvas.drawString(client, topx+2, ypos_start+5,
Font(face="sansserif",size=5,bold=0),
color=darkorchid)

def add_data(self, year, month, data):
for action in data:
#print "adding data", action
self.print_action(year, month, action)

def save(self, filename):
self.canvas.flush()
self.canvas.save(filename)

0 new messages