impression python

Le
ylc
Bonjour,
J'ai récupéré le code d'impression de Frédéric Mazue (ci dessous) =
sur
www.openvet.org et cela fonctionne bien sur Windows XP. Je voudrais
intégrer ce prog dans un autre prog pour imprimer le résultat d'une
requête SQL. comment substituer le résultat de ma requête au "bla bla
bla.." du dc.DrawText ? A moins que je ne puisse utiliser ce prog
comme un sous prog à qui j'enverrai les données à imprimer ?
Merci d'avance à celui ou celle qui voudra bien m'aider.
#!/usr/bin/python
# coding: latin1

from wx import *
true=1
false=0

class MonPrintout(Printout):
def __init__(self, titre):
Printout.__init__(self, titre)

def HasPage(self,page):
if(page <= 1):
return true
else:
return false

def GetPageInfo(self):
return (1, 1, 1, 1)

def OnPrintPage(self, page):
dc = self.GetDC()
dc.SetMapMode(MM_POINTS)
dc.DrawText("Bla bla bla bla bla.", 72, 72)
return true

class MainWindow(Frame):
def __init__(self, parent, id, title):
Frame.__init__(self, parent, -1, title, size = (500, 500),
style=DEFAULT_FRAME_STYLE|NO_FULL_REPAINT_ON_RESIZE)
id_bouton = NewId()
Button(self, id_bouton, 'Imprimer', Point(200, 200))
EVT_BUTTON(self, id_bouton, self.OnPrintBouton)

def OnPrintBouton(self, event):
pd = PrintData()
pd.SetPrinterName('')
pd.SetOrientation(PORTRAIT)
pd.SetPaperId(PAPER_A4)
pd.SetQuality(PRINT_QUALITY_DRAFT)
pd.SetColour(false) # impression noir et blanc
pd.SetNoCopies(1)
pd.SetCollate(true)
pdd = PrintDialogData()
pdd.SetPrintData(pd)
pdd.SetMinPage(1)
pdd.SetMaxPage(1)
pdd.SetFromPage(1)
pdd.SetToPage(1)
pdd.SetPrintToFile(false)
printer = Printer(pdd)
monprintout = MonPrintout("mon objet d'impression")
printer.Print(self, monprintout, true)

def OnCloseWindow(self, event):
self.Destroy()

class App(App):
def OnInit(self):
frame = MainWindow(None, -1, "Demo d'impression avec
wxPython")
self.SetTopWindow(frame)
frame.Show(true)
return true

app = App(0)
app.MainLoop()
Questions / Réponses high-tech
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Bruno Desthuilliers
Le #659081
Bonjour,
J'ai récupéré le code d'impression de Frédéric Mazue (ci dessous) sur
www.openvet.org et cela fonctionne bien sur Windows XP. Je voudrais
intégrer ce prog dans un autre prog pour imprimer le résultat d'une
requête SQL. comment substituer le résultat de ma requête au "bla bla
bla.." du dc.DrawText ?


Au hasard : en lui passant le texte à imprimer ?-)

A moins que je ne puisse utiliser ce prog
comme un sous prog à qui j'enverrai les données à imprimer ?


Ou l'art de se compliquer la vie...

Merci d'avance à celui ou celle qui voudra bien m'aider.
#!/usr/bin/python
# coding: latin1

from wx import *
true=1
false=0


Tu sais que Python a déjà True et False ?


class MonPrintout(Printout):
def __init__(self, titre, draw_text):
Printout.__init__(self, titre)
self.draw_text = draw_text


def HasPage(self,page):
if(page <= 1):
return true
else:
return false


Hem... remplace donc cette (ho|e)rreur de grand débutant par cette
simple ligne:
return page <= 1

def GetPageInfo(self):
return (1, 1, 1, 1)

def OnPrintPage(self, page):
dc = self.GetDC()
dc.SetMapMode(MM_POINTS)
if callable(draw_text):

# fonction de rappel pour les cas compliqués
draw_text(dc)
else:
# texte pour les cas simples
dc.DrawText(draw_text, 72, 72)
return true

class MainWindow(Frame):
def __init__(self, parent, id, title):
Frame.__init__(self, parent, -1, title, size = (500, 500),
styleÞFAULT_FRAME_STYLE|NO_FULL_REPAINT_ON_RESIZE)
id_bouton = NewId()
Button(self, id_bouton, 'Imprimer', Point(200, 200))
EVT_BUTTON(self, id_bouton, self.OnPrintBouton)

def OnPrintBouton(self, event):
pd = PrintData()
pd.SetPrinterName('')
pd.SetOrientation(PORTRAIT)
pd.SetPaperId(PAPER_A4)
pd.SetQuality(PRINT_QUALITY_DRAFT)
pd.SetColour(false) # impression noir et blanc
pd.SetNoCopies(1)
pd.SetCollate(true)
pdd = PrintDialogData()
pdd.SetPrintData(pd)
pdd.SetMinPage(1)
pdd.SetMaxPage(1)
pdd.SetFromPage(1)
pdd.SetToPage(1)
pdd.SetPrintToFile(false)
printer = Printer(pdd)


ici, tu a deux possibilités :
1. passer du texte:
monprintout = MonPrintout("titre", "allo la terre ?")

2. passer une fonction de rappel:
def draw(dc):
dc.DrawText('allo la terre ???', 72, 72)
dc.DrawText('ici mars !!!', 72, 72)
monprintout = MonPrintout("titre", draw)

(nb : je ne sais pas exactement à quoi correspondent les arguments de
dc.DrawText, c'est juste pour l'exemple, hein...)

printer.Print(self, monprintout, true)

(snip)


HTH

ylc
Le #658811
Merci de ton aide Bruno, mais je ne suis pas trop avancé par tes
explications. J'ai intégré tes remarques simples (true au lieu de
True..etc) mais je n'ai pas trouvé comment passer mes données à
imprimer. Il faut dire que je ne connais pas wxpython: mes
connaissances s'arrêtent à python, tkinter et sqlite.....
Mais comme tu me dis que la solution que j'envisage est "l'art de se
compliquer la vie" comment ferais-tu pour imprimer simplement une
liste de données ? (je veux déclencher l'impression directement par
un bouton.)
Bruno Desthuilliers
Le #658810
Merci de ton aide Bruno, mais je ne suis pas trop avancé par tes
explications. J'ai intégré tes remarques simples (true au lieu de
True..etc) mais je n'ai pas trouvé comment passer mes données à
imprimer.


Soit je n'ai pas compris ta question, soit tu n'a pas bien lu ma réponse.

Il faut dire que je ne connais pas wxpython: mes
connaissances s'arrêtent à python, tkinter et sqlite.....


Pour ce que j'ai compris (mais peut-être n'ai-je pas compris ?), le
problème n'est pas avec wx.

Mais comme tu me dis que la solution que j'envisage est "l'art de se
compliquer la vie"


Appeler un programme distinct ? Oui, effectivement.

comment ferais-tu pour imprimer simplement une
liste de données ?


Dans la solution que je te proposais, il suffit de passer une fonction
de rappel en second paramètre à l'instanciation de MonPrintOut. C'est
cette fonction qui fait le travail.

Après, pour ce qui est des fonctionnalités d'impression de wxPython, la
doc est ton amie. Si ta question portait sur ce point, je me déclare
totalement incompétent.

ylc
Le #658806
Salut,
Bon c'a y est, je me suis débrouillé tout seul, comme d'hab. Si
j'avais sollicité de l'aide c'est justement parce que la doc (qui a
beau être mon amie) m'a parue totalement hermétique. J'ai fini à force
de tortures à faire avouer à un sample d'un site américain comment
l'impression fonctionne sous wxpython.(cela m 'a pris une bonne
dizaine d'heures à essayer toutes les combinaisons sur 20 lignes de
code.....). J'ai gardé quand même l'appel à un sous prog car il n'est
apparamment pas possible de faire coexister du Tkinter et du wx dans
un même prog : et comme mon prog principal était déjà écrit avec
tkinter......Merci qd même.
A+ YLC
Laurent Pointal
Le #658804
Le Sat, 01 Dec 2007 01:08:33 -0800, ylc a écrit :

<zip>
J'ai fini à force de tortures
à faire avouer à un sample d'un site américain comment l'impression
fonctionne sous wxpython.(cela m 'a pris une bonne dizaine d'heures à
essayer toutes les combinaisons sur 20 lignes de code.....).


Hé bien, poste tes 20 lignes, ça sera indexé par Google, et ça pourra
dépanner quelqu'un d'autre dans le même cas que toi (ou donner des idées
à certains).

A+

Laurent.



--
Laurent POINTAL -

Laurent Pointal
Le #661859
Le Sun, 02 Dec 2007 01:10:06 +0100, Méta-MCI (MVP) a écrit :

Bonsoir !


Laurent, je viens de constater, avec horreur, que tu as raison.

En cherchant, dans Google.groupes, avec ces mots :
python script marseillais
Mon message message d'il y a deux jours sort (en 4ème ou 5ème position).

Dur ! Dur !


@-salutations


M'ouaif, le mec qui recherche sur google ces trois mots clés
simultanément... il faut qu'il aille se faire soigner. Cong.

A moins... que tu ne nous fasses un script marseillais.py qui devienne
incontournable :-)



--
Laurent POINTAL -

ylc
Le #661857
Bonjour,
Je n'ai rien compris à votre histoire de python marseillais.....?
C'est un code entre vous ?
Sinon je veux bien publier mon prog et je cherche sur quel site le
mettre.
a+ YLC
Bruno Desthuilliers
Le #661856
Bonjour,
Je n'ai rien compris à votre histoire de python marseillais.....?
C'est un code entre vous ?


Regarde deux threads plus bas ("Erreurs de syntaxe incompréhensibles").
Et si quelque chose t'échappe, dis toi bien que c'est normal quand il
s'agit d'un post de Michel !-)

Sinon je veux bien publier mon prog et je cherche sur quel site le
mettre.


Bin, déjà poste le ici - comme ça ce sera indexé avec le reste du thread.

Sinon, il y a aussi le wiki:
http://wikipython.flibuste.net/

ylc
Le #661855
Ok voila le sous prog d'impression : je n'ai rien inventé, je me suis
contenté de modifier quelques paramètres à ce que j'ai trouvé sur le
web et y intégrer le recherche des données dans ma table SQL.

#sous-prog d'impression de repert
import wx
import wx.lib.printout as printout
import sqlite3


class Frame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title,size=((200,
120)))
panel = wx.Panel(self)
box1 = wx.StaticBox(panel, -1, u"")
bsizer1 = wx.StaticBoxSizer(box1, wx.HORIZONTAL)
b22 = wx.Button(panel, -1, u"confirmez la demande
d'impression")
bsizer1.Add(b22, 10,wx.RIGHT|wx.ALL, 10)
self.liste =
wx.ListCtrl(panel,-1,size=(1000,300),style=wx.LC_REPORT)
self.Bind(wx.EVT_BUTTON, self.imprimer, b22)

sizer = wx.BoxSizer(wx.VERTICAL)
boit = wx.BoxSizer(wx.HORIZONTAL)
boit.Add(bsizer1, 0, wx.ALL, 10)
sizer.Add(boit, 0, wx.ALL|wx.CENTER, 10)
sizer.Add(self.liste, 1, wx.ALL|wx.CENTER, 0)

panel.SetSizer(sizer)
panel.Layout()
self.Centre()

def imprimer(self, evt):
self.lignes=[]
cx = sqlite3.connect(u"repert.db3")
cur = cx.cursor()
cur.execute(u"select
nom,pren,adress,copost,nocom,nutel1,nutel2,mail from coord order by
nom,pren")
for row in cur:
self.listeitem=[]
self.listeitem.append(row[0])
self.listeitem.append(row[1])
self.listeitem.append(row[2])
self.listeitem.append(row[3])
self.listeitem.append(row[4])
self.listeitem.append(row[5])
self.listeitem.append(row[6])
self.listeitem.append(row[7])
self.lignes.append(self.listeitem)
prt = printout.PrintTable(self)
prt.SetLandscape()
prt.SetHeader("LISTE DU REPERTOIRE")
prt.label =
[u"Nom",u"Prénom",u"Adresse",u"C.postal",u"Commune",u"Tél.1",u"Tél.
2",u"Mail"]
prt.text_font_size = 7
prt.set_column =[1.4,1,2,0.6,1.7,0.7,0.7,2]
prt.cell_left_margin = 1/32.5
prt.data = self.lignes
prt.SetFooter(u"Page ", type =u"Num")
prt.Print()
self.Destroy()

class MyApp(wx.App):
def OnInit(self):
frame = Frame(None, u"Impression du répertoire")
self.SetTopWindow(frame)
frame.Show(True)
return True

#main
app = MyApp(True)
app.MainLoop()

Et j'appele ce programme par la ligne suivante dans le prog. principal

retcode = os.popen("imprimrepert.exe","r")

nb : j'ai compilé les prog, c'est pourquoi le prog appelé est suffixé
par .exe sinon en python interprété j'utilise .pyw pour éviter
d'ouvrir la console à l'appel du sous prog.
voilà. A+
YLC
Bruno Desthuilliers
Le #661854
Ok voila le sous prog d'impression : je n'ai rien inventé, je me suis
contenté de modifier quelques paramètres à ce que j'ai trouvé sur le
web et y intégrer le recherche des données dans ma table SQL.


Je me permets quelques commentaires et critiques...

#sous-prog d'impression de repert
import wx
import wx.lib.printout as printout
import sqlite3


class Frame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title,size=((200,
120)))
panel = wx.Panel(self)
box1 = wx.StaticBox(panel, -1, u"")
bsizer1 = wx.StaticBoxSizer(box1, wx.HORIZONTAL)
b22 = wx.Button(panel, -1, u"confirmez la demande
d'impression")
bsizer1.Add(b22, 10,wx.RIGHT|wx.ALL, 10)
self.liste > wx.ListCtrl(panel,-1,size=(1000,300),style=wx.LC_REPORT)
self.Bind(wx.EVT_BUTTON, self.imprimer, b22)

sizer = wx.BoxSizer(wx.VERTICAL)
boit = wx.BoxSizer(wx.HORIZONTAL)
boit.Add(bsizer1, 0, wx.ALL, 10)
sizer.Add(boit, 0, wx.ALL|wx.CENTER, 10)
sizer.Add(self.liste, 1, wx.ALL|wx.CENTER, 0)

panel.SetSizer(sizer)
panel.Layout()
self.Centre()

def imprimer(self, evt):
self.lignes=[]
cx = sqlite3.connect(u"repert.db3")
cur = cx.cursor()
cur.execute(u"select
nom,pren,adress,copost,nocom,nutel1,nutel2,mail from coord order by
nom,pren")
for row in cur:
self.listeitem=[]


Tu n'a pas besoin d'en faire un attribut.

self.listeitem.append(row[0])
self.listeitem.append(row[1])
self.listeitem.append(row[2])
self.listeitem.append(row[3])
self.listeitem.append(row[4])
self.listeitem.append(row[5])
self.listeitem.append(row[6])
self.listeitem.append(row[7])
self.lignes.append(self.listeitem)


tu peux remplacer tout ça par:

self.lignes = cur.fetchall()

ou, si tu a vraiment besoin (bien que j'en doute fortement) d'avoir une
liste de liste (au lieu d'une liste de tuples):

self.lignes = map(list, cur.fetchall())

Accessoirement, libérer explicitement les ressources peut être une bonne
idée aussi:

cur.close()
cx.close()

prt = printout.PrintTable(self)

prt.SetLandscape()
prt.SetHeader("LISTE DU REPERTOIRE")
prt.label > [u"Nom",u"Prénom",u"Adresse",u"C.postal",u"Commune",u"Tél.1",u"Tél.
2",u"Mail"]
prt.text_font_size = 7
prt.set_column =[1.4,1,2,0.6,1.7,0.7,0.7,2]
prt.cell_left_margin = 1/32.5
prt.data = self.lignes
prt.SetFooter(u"Page ", type =u"Num")
prt.Print()
self.Destroy()


Dernier point: les conventions de nommage sont importantes. Mélanger
français et anglais n'est pas une bonne idée AMHA. De même, la
convention dans wxWidgets (et donc dans wxPython) est de capitaliser les
noms de méthodes. Ca va certes à contresens des conventions habituelles
de Python, mais dans ce cas il est probablement préférable de respecter
la convention wxWidgets.


class MyApp(wx.App):
def OnInit(self):
frame = Frame(None, u"Impression du répertoire")
self.SetTopWindow(frame)
frame.Show(True)
return True

#main
app = MyApp(True)
app.MainLoop()

Et j'appele ce programme par la ligne suivante dans le prog. principal

retcode = os.popen("imprimrepert.exe","r")


Alors là, j'avoue que ça me laisse songeur... Tu penses faire des
programmes distincts pour chaque fenêtre de ton appli ???

nb : j'ai compilé les prog, c'est pourquoi le prog appelé est suffixé
par .exe sinon en python interprété j'utilise .pyw pour éviter
d'ouvrir la console à l'appel du sous prog.


CPython n'est pas interprété. Il y a *toujours* une compilation en
bytecode. La compilation des modules et paquetages est sauvegardée dans
des fichiers .pyc, et l'"interpréteur" (qu'on devrait appeler "machine
virtuelle") Python se charge de détecter des modifs (en comparant les
dates de modifs des .py et .pyc) et de recompiler si nécessaire. Le
fichier principal, lui, est systématiquement recompilé - il est donc de
tradition, sauf pour des scripts triviaux, de ne mettre dans ce fichier
que l'import et l'appel du point d'entrée du programme.

Ce que tu appelle ici "compiler" n'est pas une compilation mais un
empaquetage de tout le nécessaire au fonctionnement "autonome" de ton
appli (runtime Python, bibliothèques - donc ici tout wxPython - etc)
*sous Windows*.

Dans le cas présent, passer par un "sous-programme" empaqueté de cette
façon est un monstrueux gaspillage de ressources à tous points de vue:
espace disque, ressources mémoire et ressources CPU. C'est aussi tout à
fait non-portable sur un autre OS - ce qui est un peu en contradiction
avec l'utilisation de wxPython...

Bref, tu aurais tout intérêt à revoir l'organisation de ton appli pour
intégrer cette fonctionnalité d'impression dans l'appli principale... Ce
qui te permettrait également, le cas échéant, de mieux gérer les
connections à la base de donnée (ouvrir une connection sur une base de
donnée est généralement une opération assez coûteuse, on préfère donc
avoir soit une seule connection partagée dans toute l'appli, soit un
'pool' de connections si nécessaire.

HTH

Publicité
Poster une réponse
Anonyme