IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

Enregistrer contenu fenêtre Tkinter


Sujet :

Tkinter Python

  1. #1
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Enregistrer contenu fenêtre Tkinter
    Bonjour,
    J'ai créé une fenêtre Tkinter principale qui ouvre automatiquement une fenêtre Toplevel. Celle-ci contient plusieurs canvas et un frame, le tout mis en forme avec des .grid(). Je cherche à créer un bouton "Enregister" sur ma fenêtre principale qui sauvegarde l'ensemble du contenu de ma Toplevel en une image (type .png par exemple). J'ai vu qu'il n'existe pas de fonction pour cela et qu'il faut passer par une capture d'écran
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ImageGrab.grab((x,y,x1,y1))
    Malheureusement je ne parviens pas à faire la bonne capture d'écran: les infos contenues dans me font une capture trop petite et les codes du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        fenetre8.update_idletasks()
        x =fenetre8.winfo_rootx()+canvas1.winfo_x()
        y = fenetre8.winfo_rooty()+canvas1.winfo_y()
        w =canvas1.winfo_width()
        h = canvas1.winfo_height()
        image=ImageGrab.grab((x+2, y+2, (x+w-2)*2, (y+h-2)*2))
    me font une capture plus grande mais avec des bandes noires à droite et en bas de mon image et je ne sais pas pourquoi.

    Quelqu'un aurait une idée de la méthode à suivre ?
    Voici une représentation de ce que je voudrais obtenir:Nom : Capture.PNG
Affichages : 2139
Taille : 388,8 Ko

    Et voici mon code:
    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
      #fenetre principale      
    fenetre7=Tkinter.Tk()
    fenetre7.geometry('270x170+0+0')
    frame7=Tkinter.LabelFrame(fenetre7,text='Informations générales sur le fichier')
    frame7.pack(fill='both',expand='yes')
    Tkinter.Label(frame7,text='ADCP: '+str(typeADCP)).grid(row=0,column=0)
    Tkinter.Label(frame7,text='Projet: '+str(projet)).grid(row=0,column=1)
    Tkinter.Label(frame7,text='Logiciel utilisé: '+str(typelogiciel)).grid(row=1,column=0)
    Tkinter.Label(frame7,text='On travaille depuis la '+str(typetravail)).grid(row=2,column=0)
    Tkinter.Label(frame7,text='Date: '+str(date[0][0])).grid(row=1,column=1)
    Tkinter.Label(frame7,text='Offset de: '+str(val_off)).grid(row=3,column=0)
    Tkinter.Label(frame7,text='Flagg de: '+str(val_flagg)).grid(row=4,column=0)
    F8(amp_moy_bt,time,binDepth,BT,spd_flagg,vDir_flagg,lon,lat,lon2,lat2,plan,amp_moy_brut,
         spd_brut,vDir_brut,typeADCP,projet,typelogiciel,typetravail,date,val_off,
          val_flagg,cell_size[0,0,0])
    Boutons.boutonSAVE(fenetre7)
    Boutons.boutonOK(fenetre7)
    fenetre7.wm_attributes("-topmost", 1)
    fenetre7.mainloop()
     
    #fenetre Toplevel
    def F8(amp_moy_bt,time,binDepth,BT,spd,vDir,lon,lat,lon2,lat2,plan,amp_moy_brut,spd_brut,vDir_brut,
           typeADCP,projet,typelogiciel,typetravail,date,val_off,val_flagg,cell_size):  
        # affichage donnees brutes
        fenetre8=Tkinter.Toplevel()
        fenetre8.wm_title('Affichage final du fichier: '+str(plan))
        fenetre8.geometry('900x650+300+0')
        fig1=plt.Figure(figsize=(6,4.5))
        fig1.subplots_adjust(hspace=0.2,wspace=0.05,top=1,bottom=0.1,left=0.1,right=1)
        ax11=fig1.add_subplot(311)
        ax12=fig1.add_subplot(312)
        ax13=fig1.add_subplot(313)
        prof=list(-binDepth[plan,:,0])
        prof.append(prof[-1]-cell_size)
        a1=ax11.pcolormesh(time,prof,amp_moy_brut[plan])
        ax11.set_ylabel('Profondeur (en m)')
        ax11.plot(time,-BT[plan,0,:],'.',color='k',linewidth=5)
        fig1.colorbar(a1,ax=ax11)
        b1=ax12.pcolormesh(time,prof,spd_brut[plan])
        ax12.set_ylabel('Profondeur (en m)')
        ax12.plot(time,-BT[plan,0,:],'.',color='k',linewidth=5)
        fig1.colorbar(b1,ax=ax12)
        c1=ax13.pcolormesh(time,prof,vDir_brut[plan])
        ax13.set_ylabel('Profondeur (en m)')
        ax13.plot(time,-BT[plan,0,:],'.',color='k',linewidth=5)
        fig1.colorbar(c1,ax=ax13)
        graph1=FigureCanvasTkAgg(fig1,master=fenetre8)
        canvas1=graph1.get_tk_widget()
        canvas1.grid(row=0,column=0)
        # affichage donnees nettoyees
        fig2=plt.Figure(figsize=(6,4.5))
        fig2.subplots_adjust(hspace=0.2,wspace=0.05,top=1,bottom=0.1,left=0.1,right=1)
        ax21=fig2.add_subplot(311)
        ax22=fig2.add_subplot(312)
        ax23=fig2.add_subplot(313)
        a2=ax21.pcolormesh(time,prof,amp_moy_bt[plan])
        ax21.plot(time,-BT[plan,0,:],'.',color='k',linewidth=5)
        bar21=fig2.colorbar(a2,ax=ax21)
        bar21.ax.set_ylabel('amplitude (en count)',rotation=-90)
        b2=ax22.pcolormesh(time,prof,spd[plan])
        ax22.plot(time,-BT[plan,0,:],'.',color='k',linewidth=5)
        bar22=fig2.colorbar(b2,ax=ax22)
        bar22.ax.set_ylabel('spd (en m/s)',rotation=-90)
        c2=ax23.pcolormesh(time,prof,vDir[plan])
        ax23.plot(time,-BT[plan,0,:],'.',color='k',linewidth=5)
        bar23=fig2.colorbar(c2,ax=ax23)
        bar23.ax.set_ylabel('Direction (en degre)',rotation=-90)
        graph2=FigureCanvasTkAgg(fig2,master=fenetre8)
        canvas2=graph2.get_tk_widget()
        canvas2.grid(row=0,column=1)
        # affichage trace gps
        fig3=plt.Figure(figsize=(6,4.5))
        fig3.subplots_adjust(top=1,bottom=0.1,left=0.1,right=1) 
        import mapsplot
        import pandas
        lat_len=len(lat[plan,0])
        pas=lat_len/140
        d={'latitude':list(lat[plan][0][0:lat_len:pas]),'longitude':list(lon[plan][0][0:lat_len:pas]),
           'colors':['red' for x in range(0,lat_len,pas)],
           'size':['tiny' for y in range(0,lat_len,pas)]}
        df=pandas.DataFrame(data=d)
        mapsplot.register_api_key('AIzaSyD6fp8YjMPQCQ-umDq7WY5ABhc0wtrntCg')
        mapsplot.plot_markers(df,maptype='hybrid')
        img=plt.imread('img_gps.png')
        ax31=fig3.add_subplot(111)
        ax31.imshow(img,aspect='auto',extent=(min(lon[plan,0]),max(lon[plan,0]),min(lat[plan,0]),max(lat[plan,0])),zorder=-1)
        ax31.set_xlim(min(lon[plan,0]),max(lon[plan,0]))
        ax31.set_ylim(min(lat[plan,0]),max(lat[plan,0]))
        graph3=FigureCanvasTkAgg(fig3,master=fenetre8)
        canvas3=graph3.get_tk_widget()
        canvas3.grid(row=1,column=0)    
        # affichage informations generales
        frame4=Tkinter.LabelFrame(fenetre8,text='Informations generales',height=100,width=300)
        Tkinter.Label(frame4,text='ADCP: '+str(typeADCP)).grid(row=0,column=0)
        Tkinter.Label(frame4,text='Projet: '+str(projet)).grid(row=0,column=1)
        Tkinter.Label(frame4,text='Logiciel utilisé: '+str(typelogiciel)).grid(row=1,column=0)
        Tkinter.Label(frame4,text='On travaille depuis la '+str(typetravail)).grid(row=2,column=0)
        Tkinter.Label(frame4,text='Date: '+str(date[0][0])).grid(row=1,column=1)
        Tkinter.Label(frame4,text='Offset de: '+str(val_off)).grid(row=3,column=0)
        Tkinter.Label(frame4,text='Flagg de: '+str(val_flagg)).grid(row=4,column=0)
        frame4.grid_propagate(0)
        frame4.grid(row=1,column=1)
     
    from PIL import ImageGrab
    def boutonSAVE(fenetre):
        def enregistrer():
            ImageGrab.grab((x,y,x1,y1)).save(str(projet)+'_figure_finale.png')
        return Tkinter.Button(fenetre,text='Enregistrer',command=enregistrer).pack(side='left',padx=5,pady=5)
    Il me reste donc à définir x,y,x1,y1 ou à trouver une autre méthode... Je commence à ne plus avoir d'idée alors merci pour votre aide !!

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 302
    Points : 6 782
    Points
    6 782
    Par défaut
    Salut,

    Les bandes noires sont en fait le contenu de l'écran derrière ta TopLevel

    Je vois dans ton code que tu décales x et y de deux pixels donc si tu y ajoutes la largeur à x, la valeur finale est aussi décalée de deux pixels.
    Tu dois donc soustraire 4 pixels aux largeur et hauteur.

  3. #3
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Merci pour ta réponse ! Il s'agit donc bien d'un problème de pixels. J'ai donc repensé ma façon de compter ces fameux pixels:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    fenetre8.update_idletasks()
    x = fenetre8.winfo_rootx()
    y = fenetre8.winfo_rooty()
    w = canvas1.winfo_width()+canvas2.winfo_width()
    h = canvas1.winfo_height()+canvas3.winfo_height()
    image=ImageGrab.grab((x, y, x+w, y+h)
    (en sachant que canvas1 est mon graphe en haut à gauche, canvas2 mon graphe en haut à droite et canvas3 mon graphe en bas à gauche). Cette façon de calculer les extremum de ma capture d'écran me semble plutôt logique et pourtant j'obtient l'image suivante:

    Nom : day24_figure_finale.png
Affichages : 1978
Taille : 270,0 Ko

    N'y aurait-il pas un problème d'unité entre les pixels demandés par ImageGrab.grab() et les canvas.winfo_width/height que j'interroge ?
    Merci pour l'aide

  4. #4
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bonjour, je n'ai que peu avancé sur ma problématique de screenshot de ma fenêtre Tkinter.
    Il s'avère que ImageGrab.grab() sans paramètre devrait faire un screenshot de mon écran complet or il se trouve que non.
    En voici la preuve:
    Nom : day01_figure_finale.png
Affichages : 2084
Taille : 387,6 Ko

    Quelqu'un aurait-il une idée de ce qu'il se passe ? Mon écran a l'air bien paramétré donc je n'ai plus d'idée
    Voici mon code de test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    def boutonSAVE(fenetre):
          def enregistrer():
               im=ImageGrab.grab()
               im.save('figure_finale.png')
    return Tkinter.Button(fenetre,text='Enregistrer',command=enregistrer).pack(side='left',padx=5,pady=5)
    Merci pour votre aide !!

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 329
    Points : 36 848
    Points
    36 848
    Par défaut
    Salut,

    Citation Envoyé par Wasem Voir le message
    Quelqu'un aurait-il une idée de ce qu'il se passe ? Mon écran a l'air bien paramétré donc je n'ai plus d'idée
    Il serait plus sage de vous appliquer à reproduire votre soucis avec un code minimal(*) qui permette de reproduire ce que vous constatez.
    A défaut, pas facile de comprendre.
    (*) ce qui veut dire écrire et poster quelques dizaines de lignes de code et non tout votre programme!

    - W

  6. #6
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bonjour,
    Apparemment vous avez pris la peine de lire mon dernier post et ainsi vous aurez remarqué, je pense, que mon code de test ne fait que 6 lignes exactement, ce qui ne me semble pas très long. En effet, mon premier post présente un code un peu long et cela pour 2 raisons: je ne suis pas développeur et je ne connais donc pas toutes les conventions de ce genre de forum, et, en second lieu, je souhaitais au départ pourvoir laisser la possibilité, à ceux qui me répondraient, de me proposer d'autres solutions qu'un screenshot pas terrible (mais cela demande de comprendre ma fenêtre qui oui est très longue à définir). J'estime, mais peut-être à tord hein ^^ que si les problèmes posés sur ce forum étaient simples on aurait pas besoin de les poser, mais bon...
    Je suis ravie de voir que des architectes ou développeurs confirmés prennent le temps de répondre aux gens comme moi qui ne comprennent rien en info mais je suis atterrée de voir le nombre de posts qui ne font que lyncher ou se moquer des gens qui ne posent pas leur question "de la bonne manière".
    Merci en tout cas pour votre aide inutile, j'ai résolu mon problème autrement.

    Bien cordialement,

    PS: Pour les nuls comme moi que ça intéresse, il faut mettre la résolution de son écran à 100% et non à plus comme c'est le cas pour mon ordi (150%) et le problème est en partie résolu.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 329
    Points : 36 848
    Points
    36 848
    Par défaut
    Citation Envoyé par Wasem Voir le message
    Apparemment vous avez pris la peine de lire mon dernier post et ainsi vous aurez remarqué, je pense, que mon code de test ne fait que 6 lignes exactement, ce qui ne me semble pas très long. En effet, mon premier post présente un code un peu long et cela pour 2 raisons: je ne suis pas développeur et je ne connais donc pas toutes les conventions de ce genre de forum
    Un code qui reproduit le problème doit être complet au sens où on le recopie, on le lance et on constate (ou pas) les mêmes défauts que vous. S'il faut ajouter soi même du code pour le faire fonctionner, pas facile de s'assurer qu'on va être dans les mêmes conditions.
    Dans votre cas, çà pourrait ressembler à çà:
    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
    from PIL import ImageGrab
    import tkinter as tk
     
    root = tk.Tk()
    root.configure(bg='blue')
    x, y, w, h = 100, 100, 200, 200
    root.geometry('%dx%d+%d+%d' % (w, h, x, y))
    tk.Canvas(root, width=100, height=100, bg='grey').grid(row=0, column=0)
    tk.Canvas(root, width=100, height=100, bg='green').grid(row=1, column=1)
     
    root.update()
    x = root.winfo_rootx()
    y = root.winfo_rooty()
     
    im = ImageGrab.grab((x, y, x+w, y+h))
    im.save('test.png')
    im.show()
    Et voilà ce que çà affiche
    Nom : test.png
Affichages : 1837
Taille : 649 octets
    note: j'ai changé la résolution pour voir si çà changeait quelque chose: rien.

    - W

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/09/2007, 12h13
  2. Enregistrer contenu XML en mémoire vers un fichier
    Par kingmandrax dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 26/10/2006, 10h24
  3. PLusieurs fenêtre Tkinter
    Par peyro dans le forum Tkinter
    Réponses: 2
    Dernier message: 14/06/2006, 15h04
  4. Réponses: 1
    Dernier message: 14/04/2006, 16h51
  5. Enregistrer Contenu d'une fenêtre enfant.
    Par yaku dans le forum C++Builder
    Réponses: 3
    Dernier message: 21/12/2004, 18h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo