Bonjour
J'aimerais pouvoir enregistrer mon interface graphique faite sous tkinter python v3.2.3 en format pdf pour pouvoir l'imprimer (le fenêtre avec tout ce qu'elle contient)...
Est-ce possible de faire çà et comment?
Merci d'avance
Bonjour
J'aimerais pouvoir enregistrer mon interface graphique faite sous tkinter python v3.2.3 en format pdf pour pouvoir l'imprimer (le fenêtre avec tout ce qu'elle contient)...
Est-ce possible de faire çà et comment?
Merci d'avance
Bonjour,
La solution c'est de passer par PIL mais... vous avez dit python v3.2.3 et pas de PIL (hors portage non officiel) pour le moment pour Python 3.
Une idée simple serait de passer par un Canvas pour créer l'interface dedans et d'utiliser .postscript() (Qui donne du Postscript, que vous pouvez facilement travailler), .create_window() permettant 'd’intégrer' les Widget à l'image.
Après c'est plus compliqué (voir vos précédents post)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 from tkinter import * master = Tk() cv = Canvas(master, width=200, height=100) cv.pack() cv.create_rectangle(50, 25, 150, 75, fill="blue") l = Label(cv, text='Label', bd=0, padx=3, pady=1) cv.create_window(20, 20, window=l) b = Button(cv, text='draw', command=lambda :cv.postscript(file="ecran.ps", colormode='color')) cv.create_window(100, 48, window=b) mainloop()
@+
et çà serait possible de faire une impression ecran? (en contournant PIL)
Le sujet n'était pas de créer un pdf ? Je vous propose une solution 'simple' (et cela correspond à votre première demande, soit: J'essaye de trouver comment je pourrais enregistrer mon interface graphique (pas la page de code mais la fenêtre avec les bouttons etc) dans un dossier.) (simple, mais tordue il est vrais) de vous en sortir sans toucher à ceux que je vous ai déjà montrer.
Si vous êtes sous Windows, la version non officielle de PIL fonctionne très bien et est même dispo pour 3.3 à l'URL
Vous pouvez aussi utiliser une copie d'écran externe.
- W
merci beaucoup pour vos réponses
PauseKawa j'ai essayé votre code mais çà n'a pas fonctionné. Je suis repartie sur l'idée d'une capture écran pour juste garder une trace de l'interface graphique pour pouvoir l'imprimer automatiquement après (ce qui va être un problème également pour communiquer avec l'imprimante). Je vous remercie énormément pour le mal que vous vous êtes donné à répondre à tous mes topics.
Merci wiztricks pour le lien de PIL.
Sujet résolu
Merci
Cà m'a mis ce message d'erreur:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Traceback (most recent call last): File "C:/Users/Fanny/Desktop/test.py", line 8, in <module> print(getpixelcolor(30,30)) File "C:/Users/Fanny/Desktop/test.py", line 2, in getpixelcolor desktop_id = win32gui.GetDesktopWindow() NameError: global name 'win32gui' is not defined
Ah oui c'est exact !
cela est bien censé m'afficher des coordonnées?
En tapant :J'obtiens:
Code : Sélectionner tout - Visualiser dans une fenêtre à part print(getpixelcolor(30,30))
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 >>> (237, 237, 237) >>>
ah d'accord! Et à partir de là je pouvais reconstruire mon image en parcourant toutes l'interface graphique et en affichant ces couleurs, c'est bien çà?
C'est bien cela:
1) Dans un premier temps recherche les informations sur la géométrie de la fenêtre avec les winfo_* du root tk. Rien de bien difficile.
2) A l'aide de la fonction fournis ou stocke dans une matrice les informations sur la couleur de chaque point.
3) A partir de la matrice obtenue on reconstruit le fichier image dans le format voulu.
3 Bis) Une des particularités du .postscript() du Widget Canvas est qu'il n'est pas besoin d'afficher le Canvas pour en tirer un fichier postscript.
Il est possible de ne pas appliquer de gestionnaire de géométrie (pack, place, grid).
Pas de poste Windows sous la main donc un exemple sans win32gui
A partir de là il vous est possible de créer un Canvas, en positionnant des éléments de 1 de coté (create_oval ou create_rectangle).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 from tkinter import * def saveimg(): w.postscript(file='out.ps', colormode='color', height=100, width=200) root = Tk() w = Canvas(root, width=200, height=100) w.create_line(0, 0, 200, 100) w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4)) w.create_rectangle(50, 25, 150, 75, fill="blue") Button(root, text="Save", command=saveimg).pack() root.mainloop()
Pour la couleur a utiliser c'est rgb = "#%02d%02d%02d" % (valeur R, valeur G, valeur B): Facile puisque vous avez déjà tout cela.
@+
Notes:
create_rectangle et pas create_oval.
Puisque vous avez déjà des coordonnées et les valeurs RGB autant ne pas créer de matrice mais écrire directement dans le Canvas.
Bon code
PhotoImage.put()
Le souci c'est que win32gui.GetPixel est trop long...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 import tkinter as tk import tkinter.filedialog as tkfiledialog import win32gui import webbrowser import os def getpixelcolor(desktop_dc, x, y): long_colour = win32gui.GetPixel(desktop_dc, x, y) colour = int(long_colour) return (colour & 0xff), ((colour >> 8) & 0xff), ((colour >> 16) & 0xff) def setpixel(image, pos, color): r, g, b = color x, y = pos image.put("#%02x%02x%02x" % (r, g, b), (y, x)) def showpreview(tkinst=None): root.screen = tk.PhotoImage(master=root) if tkinst: g = tkinst.winfo_geometry() w, other = g.split('x') h, x, y = other.split('+') x = int(x) y = int(y) w = int(w) + tkinst.winfo_rootx() - x h = int(h) + tkinst.winfo_rooty() - y else: w = int(root.winfo_screenwidth()) h = int(root.winfo_height()) x = 0 y = 0 desktop_dc = win32gui.GetWindowDC(win32gui.GetDesktopWindow()) for i in range(w): for j in range(h): setpixel(root.screen, (j, i), getpixelcolor(desktop_dc, i+x, j+y)) top = tk.Toplevel(root) top.title("Preview") lab = tk.Label(top, image=root.screen, relief=tk.GROOVE) lab.image = root.screen lab.grid(column=0, row=1, columnspan=2, pady=5) tk.Button(top, text="Save", command=onsave).grid(gv, column=0, row=2) tk.Button(top, text="Quit", command=top.destroy).grid(gv, column=1, row=2) def onsave(): file_opt = options = {} options['filetypes'] = [('gif files', '.gif'), ('ppm files', '.ppm')] options['initialdir'] = os.path.expanduser('~') options['initialfile'] = 'screen.gif' options['parent'] = root options['title'] = 'Save as...' filename = tkfiledialog.asksaveasfilename(**file_opt) ext = filename[-3:] root.screen.write(filename, format=ext) def showhtml(url): webbrowser.open(url, new=0, autoraise=True) gv = {'padx': 5, 'pady':5, 'ipadx':5, 'ipady':5} root = tk.Tk() root.title("tkinter.PhotoImage sample") t = tk.Text(root) t.insert(tk.END, " Exemple de capture d'écran sous Python 3\n") t.insert(tk.END, " Avec tkinter et win32gui\n") t.insert(tk.END, " Voir: ") href = "http://www.developpez.net/forums/d1244499/autres-langages/python-zope/gui/tkinter/mettre-interface-graphique-sous-format-pdf/" t.insert(tk.END, "ici", 1) t.grid(column=0, row=1, columnspan=2) tk.Button(root, text="Preview", command=lambda: showpreview(root)).grid(gv, column=0, row=2) tk.Button(root, text="Quit", command=root.destroy).grid(gv, column=1, row=2) t.tag_config(1, foreground="blue") t.tag_bind(1, '<Button-1>', lambda ev=None: showhtml(href)) root.mainloop()
Je me demande s'il ne serait pas plus rapide de passer par le clipboard de Windows (voir l'API Win32).
@+
Edit: Ou
Edit : ()
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 import tkinter as tk import tkinter.filedialog as tkfiledialog import win32gui import webbrowser import os def getpixelcolor(desktop_dc, x, y): long_colour = win32gui.GetPixel(desktop_dc, x, y) colour = int(long_colour) return (colour & 0xff), ((colour >> 8) & 0xff), ((colour >> 16) & 0xff) def showpreview(tkinst=None): root.screen = tk.PhotoImage(master=root) if tkinst: g = tkinst.winfo_geometry() w, other = g.split('x') h, x, y = other.split('+') x = int(x) y = int(y) w = int(w) + tkinst.winfo_rootx() - x h = int(h) + tkinst.winfo_rooty() - y else: w = int(root.winfo_screenwidth) h = int(root.winfo_height) x = 0 y = 0 desktop_dc = win32gui.GetWindowDC(win32gui.GetDesktopWindow()) for i in range(w): for j in range(h): root.screen.put("#%02x%02x%02x" % getpixelcolor(desktop_dc, i+x, j+y), (i, j)) top = tk.Toplevel(root) top.title("Preview") lab = tk.Label(top, image=root.screen, relief=tk.GROOVE) lab.image = root.screen lab.grid(column=0, row=1, columnspan=2, pady=5) tk.Button(top, text="Save", command=onsave).grid(gv, column=0, row=2) tk.Button(top, text="Quit", command=top.destroy).grid(gv, column=1, row=2) def onsave(): print(root.screen) file_opt = options = {} options['filetypes'] = [('gif files', '.gif'), ('ppm files', '.ppm')] options['initialdir'] = os.path.expanduser('~') options['initialfile'] = 'screen.gif' options['parent'] = root options['title'] = 'Save as...' filename = tkfiledialog.asksaveasfilename(**file_opt) ext = filename[-3:] root.screen.write(filename, format=ext) def showhtml(url): webbrowser.open(url, new=0, autoraise=True) gv = {'padx': 5, 'pady':5, 'ipadx':5, 'ipady':5} root = tk.Tk() root.title("tkinter.PhotoImage sample") t = tk.Text(root) t.insert(tk.END, " Exemple de capture d'écran sous Python 3\n") t.insert(tk.END, " Avec tkinter et win32gui\n") t.insert(tk.END, " Voir: ") href = "http://www.developpez.net/forums/d1244499/autres-langages/python-zope/gui/tkinter/mettre-interface-graphique-sous-format-pdf/" t.insert(tk.END, "ici", 1) t.grid(column=0, row=1, columnspan=2) tk.Button(root, text="Preview", command=lambda: showpreview(root)).grid(gv, column=0, row=2) tk.Button(root, text="Quit", command=root.destroy).grid(gv, column=1, row=2) t.tag_config(1, foreground="blue") t.tag_bind(1, '<Button-1>', lambda ev=None: showhtml(href)) root.mainloop()
Edit :j, i > i, j
Il ne vous reste plus qu'a chercher avec le presse papier.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 import tkinter as tk import tkinter.filedialog as tkfiledialog import win32gui import win32ui import win32con import webbrowser import os def onsave(): g = root.winfo_geometry() wfen, other = g.split('x') hfen, xfen, yfen = other.split('+') xfen = int(xfen) yfen = int(yfen) # A revoir wfen = int(wfen) + (root.winfo_rootx() - xfen) * 2 hfen = int(hfen) + int((root.winfo_rooty() - yfen) * 1.5) hwnd = win32gui.GetDesktopWindow() l, t, r, b = win32gui.GetWindowRect(hwnd) h = b - t w = r - l hDC = win32gui.GetWindowDC(hwnd) myDC = win32ui.CreateDCFromHandle(hDC) newDC = myDC.CreateCompatibleDC() saveBitMap = win32ui.CreateBitmap() saveBitMap.CreateCompatibleBitmap(myDC, wfen, hfen) newDC.SelectObject(saveBitMap) newDC.BitBlt((0, 0), (wfen, hfen) , myDC, (xfen, yfen), win32con.SRCCOPY) saveBitMap.Paint(newDC) file_opt = options = {} options['filetypes'] = [('bmp files', '.bmp')] options['initialdir'] = os.path.expanduser('~') options['initialfile'] = 'screen.bmp' options['parent'] = root options['title'] = 'Save as...' filename = tkfiledialog.asksaveasfilename(**file_opt) saveBitMap.SaveBitmapFile(newDC, filename) def showhtml(url): webbrowser.open(url, new=0, autoraise=True) gv = {'padx': 5, 'pady':5, 'ipadx':5, 'ipady':5} root = tk.Tk() root.title("tkinter.PhotoImage sample") t = tk.Text(root) t.insert(tk.END, " Exemple de capture d'écran sous Python 3\n") t.insert(tk.END, " Avec tkinter et win32\n") t.insert(tk.END, " Voir: ") href = "http://www.developpez.net/forums/d1244499/autres-langages/python-zope/gui/tkinter/mettre-interface-graphique-sous-format-pdf/" t.insert(tk.END, "ici", 1) t.grid(column=0, row=1, columnspan=2) tk.Button(root, text="Save", command=onsave).grid(gv, column=0, row=2) tk.Button(root, text="Quit", command=root.destroy).grid(gv, column=1, row=2) t.tag_config(1, foreground="blue") t.tag_bind(1, '<Button-1>', lambda ev=None: showhtml(href)) root.mainloop()
Pour information cela passe par
ou f = 2, 8 ou 17 (2=CF_BITMAP)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 win32clipboard.OpenClipboard()) data = win32clipboard.GetClipboardData(f) win32clipboard.CloseClipboard()
@+
Pour le fun (fonctionne normalement mais juste testé sous tux)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 import tkinter as tk import tkinter.filedialog as tkfiledialog import webbrowser import os def onsave(): file_opt = options = {} options['filetypes'] = [('Postcript files', '.ps')] options['initialdir'] = os.path.expanduser('~') options['initialfile'] = 'screen.ps' options['parent'] = root options['title'] = 'Save as...' filename = tkfiledialog.asksaveasfilename(**file_opt) root.after(100) # Huummm... c.postscript(file=filename, colormode='color', height=f.winfo_reqheight(), width=f.winfo_reqwidth()) def showhtml(url): webbrowser.open(url, new=0, autoraise=True) gv = {'padx': 5, 'pady': 5, 'ipadx': 5, 'ipady': 5} root = tk.Tk() root.title("tkinter.Canvas sample") c = tk.Canvas(root, bd=0) f = tk.Frame(c) t = tk.Text(f) t.insert(tk.END, " Exemple de capture de la fenetre sous Python 2/3\n") t.insert(tk.END, " Juste avec Canvas.postscript()\n") t.insert(tk.END, " Voir: ") href = "http://www.developpez.net/forums/d1244499/autres-langages/python" href += "-zope/gui/tkinter/mettre-interface-graphique-sous-format-pdf/" t.insert(tk.END, "ici", 1) t.grid(column=0, row=1, columnspan=2) tk.Button(f, text="Save", command=onsave).grid(gv, column=0, row=2) tk.Button(f, text="Quit", command=root.destroy).grid(gv, column=1, row=2) t.tag_config(1, foreground="blue") t.tag_bind(1, '<Button-1>', lambda ev=None: showhtml(href)) f.pack() f.update() # f.winfo_req*()/2 ? c.create_window((f.winfo_reqwidth() / 2, f.winfo_reqheight() / 2), window=f) c.pack() root.resizable(0, 0) # Je triche... root.mainloop()
Partager