My printer will not accept postscript and all i needed to print was canvas rectangles. So here is something i put together... hope it helps someone else. -works for polys, recs, and lines-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | from Tkinter import *
import tkMessageBox as MB
import win32ui
import win32print
import win32con
root = Tk()
root.option_add('*Font',('Courier New', 12))
def onPrint():
MB.showinfo('FYI','Make sure your printer is turned on and ready!\nThen press OK ;-)\n\nTested with hp f340')
l = [(canvas.type(obj),canvas.coords(obj)) for obj in canvas.find_all()]
print l
print_canvas(l)
def print_canvas(coord_list, scale=20):
'''Print canvas from list of coords for each canvas.object'''
moves = []
for obj in coord_list:
if obj[0] == 'rectangle':
#moves.append(('rectangle@: ', obj[1]))
tlc, trc, blc, brc = (obj[1][0], obj[1][1]),(obj[1][2], obj[1][1]), (obj[1][0],obj[1][3]), (obj[1][2],obj[1][3])
moves.append('dc.MoveTo((scale*%d, scale*-%d))' %(int(tlc[0]), int(tlc[1])))
moves.append('dc.LineTo((scale*%d, scale*-%d))' %(int(blc[0]), int(blc[1])))
moves.append('dc.LineTo((scale*%d, scale*-%d))' %(int(brc[0]), int(brc[1])))
moves.append('dc.LineTo((scale*%d, scale*-%d))' %(int(trc[0]), int(trc[1])))
moves.append('dc.LineTo((scale*%d, scale*-%d))' %(int(tlc[0]), int(tlc[1])))
elif obj[0] == 'line':
#moves.append(('line@: ', obj[1]))
moves.append('dc.MoveTo((scale*%d, scale*-%d))' %(int(obj[1][0]), int(obj[1][1])))
moves.append('dc.LineTo((scale*%d, scale*-%d))' %(int(obj[1][2]), int(obj[1][3])))
elif obj[0] == 'polygon':
#moves.append(('polygon@: ', obj[1]))
start = 0
temp = []
for y in range(1, len(obj[1])+1, 2):
temp.append( (obj[1][start], obj[1][y]) )
start += 2
sc = temp[0]
ec = temp[1]
if sc != ec:
temp.append(sc)#close the polygon
moves.append('dc.MoveTo((scale*%d, scale*-%d))' %(int(temp[0][0]), int(temp[0][1])))
for x in temp[1:]:
moves.append('dc.LineTo((scale*%d, scale*-%d))' %(int(x[0]), int(x[1])))
elif obj[0] == 'arc':
# draw curve to printer ???
pass
elif obj[0] == 'oval':
# draw curve to printer ???
pass
else:
pass
for x in moves:
print x
try:
print '\n\n--- Starting Print ---'
dc = win32ui.CreateDC()
dc.CreatePrinterDC(win32print.GetDefaultPrinter())
dc.SetMapMode(win32con.MM_TWIPS) #1440 per inch
dc.StartDoc('draw line')
pen = win32ui.CreatePen(0, int(scale), 0L)
dc.SelectObject(pen)
for x in moves:
exec(x)
dc.EndDoc()
except:
print '\n\n!!! Print Failed !!!'
canvas = Canvas(root, bg='white')
canvas.pack()
Button(root, text="== Print Canvas Now ==", fg='red', command=onPrint).pack()
canvas.create_rectangle(310,10,325,100)
canvas.create_rectangle(330,10,345,100)
canvas.create_rectangle(350,10,365,100)
canvas.create_line(370,10,370,100)
canvas.create_polygon(200,150, 250,150, 250,250, 200,250)
canvas.create_polygon(135,38, 64,38, 29,100, 64,161, 135,161, 170,100)
root.mainloop()
|
---------- this could be written a lot better ---------------
Checked on vista with HP f340 all in one if only tk.canvas had a method like "canvas.getpoints(canvasitem)" or "canvas.convert_to_poly(canvasitem)" the messy conditional above could be accomplished with a simple for loop Anybody know how to write custom tk functions???
any suggestions to improve or just flame...let me know.