Imprimir a un archivo PDF usando GTK.
Perfecto. En esta semana me ha tocado estar trabajando sobre un programita que ando haciendo, el cual debe correr sobre Linux y MS Windows >= 2000. El desarrollo se esta haciendo en Python usando GTK para la interfaz grafica, pero me he encontrado uno que otro problemita con GTK, sobre todo con el manejo de ventanas, aunque el que mas tiempo me ha llevado ha sido el de impresion.Gtk+ a partir de la version 2.10 incluye soporte para impreision en Linux y otros Unix'es gracias a CUPS, mientras que en Windows lo hace de manera nativa con el sistema de impresion de Windows.
Debo decir que en linux esta cosa es la maravilla, En windows no tanto, pero funciona decentemente si tus requerimientos no son tan especiales.
Los requerimientos para imprimir son estos:
- Debe imprimir en la impresora por defecto
- NO debe mostrar el dialogo de seleccion de impresora
- Debe imprimir en el tamanio determinado por el programa
En linux, repito, esto es una maravilla, solo le digo imprime usando la constante gtk.PRINT_OPERATION_PRINT y con esto no me muestra el cuadro de dialogo, previamente he creado la operacion de impresion y le he dicho que seleccione la impresora por defecto, en linux, si en settings.set_printer() le pasas el parametro '' usa la impresora por defecto, es mas, si no usas el metodo set_printer usa la impresora por defecto.Pero en Windows la cosa no es tan bonita. para empezar Siempre muestra el cuadro de seleccion de impresora (punto menos). Y para acabarla de amolar, aunque tengas una impresora predeterminada y esta impresora este seleccionada mandas imprimir (Alt +m o ENTER) habra un error porque GTK no ha configurado las cabeceras de impresion para mandarle el 'win32-driver', 'win32-driver-extra' y otros parametros fumados de los que Windows sabe. Obviamente, si seleccionas otra impresora y regresas a la que esta por defecto estos parametros son llenados y entonces la impresion funciona "bien". Obviamente, como no queremos que el usuario vea el cuadro de impresion esto no es opcion.
Lo siguiente es, obtener la impresora por defecto y mandar establecer los encabezados, para esto se pueden valer del modulo win32print
import win32print
printerName = win32print.GetDefaultPrinter()
printer = win32print.OpenPrinter(printerName)
printerValues = win32print.GetPrinter(printer,2)
dir(printerValues['pDevMode'])
printerName = win32print.GetDefaultPrinter()
printer = win32print.OpenPrinter(printerName)
printerValues = win32print.GetPrinter(printer,2)
dir(printerValues['pDevMode'])
Esto les sera util cuando ustedes quieran mostrar el cuadro de impresion, a fin de que lo muestre y espere una configuracion por parte del usuari, o en caso de que no se configure nada por parte del usuario, usar las configuraciones por defecto.
Hasta aqui todo bien, pero, Yo no quiero el cuadro de impresion!, solo quiero que imprima.
Bien, yo no queria hacerlo asi, pero pues bueno, no hay de otra.
if os.name == 'nt':
filename = './ultimafactura.pdf'
op.set_export_filename(filename)
action = gtk.PRINT_OPERATION_ACTION_EXPORT
elif '-d' in sys.argv:
action = gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG
else:
action = gtk.PRINT_OPERATION_ACTION_PRINT
try:
response = op.run(action)
except:
response = gtk.PRINT_OPERATION_RESULT_ERROR
if response == gtk.PRINT_OPERATION_RESULT_ERROR:
settings = op.get_print_settings()
settings.foreach(funcPrintKeys)
print "Hubo un error a imprimir"
elif response == gtk.PRINT_OPERATION_RESULT_APPLY:
if os.name == 'nt':
filename = './ultimafactura.pdf'
import win32api
win32api.ShellExecute(0,
'print',
filename,
None,
'.',
0)
filename = './ultimafactura.pdf'
op.set_export_filename(filename)
action = gtk.PRINT_OPERATION_ACTION_EXPORT
elif '-d' in sys.argv:
action = gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG
else:
action = gtk.PRINT_OPERATION_ACTION_PRINT
try:
response = op.run(action)
except:
response = gtk.PRINT_OPERATION_RESULT_ERROR
if response == gtk.PRINT_OPERATION_RESULT_ERROR:
settings = op.get_print_settings()
settings.foreach(funcPrintKeys)
print "Hubo un error a imprimir"
elif response == gtk.PRINT_OPERATION_RESULT_APPLY:
if os.name == 'nt':
filename = './ultimafactura.pdf'
import win32api
win32api.ShellExecute(0,
'print',
filename,
None,
'.',
0)
Que es lo que hace ShellExecute?. Bien, ejecutara el comando que tu le des, en este caso 'print' sobre el archivo dado por el siguiente parametro "filaname", el siguiente parametro son los parametros al programa que va a realizar la operacion, el siguiente, el directorio de trabajo y por ultimo un valor entre 0 y 1 que dice si se ha de mostrar o no la ventana del programa que ha de realizar la operacion.
Para esto, es necesario tener en Windows un programa que pueda abrir e imprimir PDF. Obviamente el mas conocido es Adobe Acrobat Reader, pero Adobe Acrobat Reader es un Monstruo si lo unico que queremos es impresion. Asi que, lo que he hecho es utilizar Foxit PDF Reader, el cual es mucho mas ligero y rapido.Y eso es todo, ese ha sido el cucharazo porque GTK por defecto no te utiliza la impresora por defecto, ni te esconde el cuadro de impresion en Windows.
En fin. el chiste es lograr que las cosas jalen.
Un ejemplo sencillo de impresion lo pueden encontrar Aqui






Leave a Comment