Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > fr.comp.lang.python > #3304

Re: erreur 'UnboundLocalError' incompréhensible

Newsgroups fr.comp.lang.python
From Lulu <lulu042@fry.fr.invalid>
Subject Re: erreur 'UnboundLocalError' incompréhensible
References <slrnr75bu9.47j.lulu042@Minty.Rock-n-Roll.org> <5e73b495$0$9910$426a74cc@news.free.fr>
Organization koitess?
Message-ID <slrnr7997t.gp0.lulu042@Minty.Rock-n-Roll.org> (permalink)
Date 2020-03-20 12:11 +0100

Show all headers | View raw


Le 19-03-2020, Nicolas <nicolasp@aaton.com> a écrit :
>  Le 19/03/2020 à 00:33, Lulu a écrit :

>> Je cherche à afficher une nouvelle fenetre depuis mon application et
>> je voudrais qu'elle utilise une autre fonte que ma fenetre principale
>> :
>> 
>> mon code (ceci n'est pas un ECM) :
>> import tkinker as tk
>> from tkinter import font
>> ...
>> # fonction appelée par le clic sur le bouton "Dessiner le spectre"
>> def callback()
>>      ze_info_window = tk.Toplevel(height=200, width=120)
>>      ze_info_window_font = font.Font(family='Courier', size='9'	
>>      label = tk.label( ze_info_window, text = "test", font=ze_info_wondow_font)
>> 
>> mais si ma nouvelle fenetre s'affiche bien (sans afficher 'test') mon
>> application plante avec :
>> Exception in TKinter callback
>> Traceback (most recent caall last):
>>    File "/usr/lib/pyrhon3.6/tkinter/__init__.py", line 1705, in __call__
>>      return self.func(*args)
>>    File 'spectres_tk.py" line 68, in callback
>>      ze_info_window_font = font.Font(family='Courier', size='9')
>> UnboundLocalError: local variable 'font' referenced before assignment
>> 
>> J'ai parcouru le web à la recherche d'une solution, j'ai compris qu'il
>> doit s'agir d'un problème de local/global, mais aucune piste pour
>> résoudre le problème.
>> 
>> Tout ce que je veux, c'est ouvrir une nouvelle fenêtre à partir de la
>> fenêtre principale quand on clique sur le bouton qui appelle la fonction
>> callback() en changeant la fonte pour cette nouvelle fenêtre.
>> 
>> Je précise que si je ne cherche pas à ouvrir cette nouvelle fenêtre, mon
>> application fonctionne très bien.
> 
>  Le code de de la fonction "callback" est
>    complet ?

Oh non, loin de là !
Je mets ton mon code à la fin du message.

>  Je ne connais pas tKinter mais il est possible que la police de 
>  caractères doive être chargée lors du lancement de l'application pour 
>  qu'elle soit toujours accessible.
>  Dans le code fourni, la police de caractères n'existe que dans la 
>  fonction callback.

J'ai résolu mon problème quand je me suis rendu compte (dans une partie
du code écrite il y a plusieurs semaines) que j'utilisais le mot 'font'
pour sélectionner la fonte pour écrire sur mon image :
    font = ImageFont.truetype(CONST_FONTE, CONST_FONTE_TAILLE)
dès que j'ai remplacé par :
    font_image = ImageFont.truetype(CONST_FONTE, CONST_FONTE_TAILLE)
tout est rentré dans l'ordre.

Mon code (testé uniquement sous linux) :
8<-----------8<---------8<----------8<----------8<----------8<----------8<
#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Auteur : <h.fertin@ac-rouen.fr>, Lycée Jules Siegfried, Le Havre
# Creative Commons : https://creativecommons.org/licenses/by-nc-sa/2.0/fr/
# Attribution :: Pas d'utilisation commerciale :: Partage dans les mêmes conditions

CONST_FONTE = 'courbd.ttf'
CONST_FONTE_TAILLE = 14

import sys
from datetime import datetime
#from tkinter import *
import tkinter as tk
from tkinter import font
from tkinter import messagebox
# sous windows :
# - ouvrir une "Commande MS-DOS" en tant qu'administrateur
# - se placer dans le répertoire \programs\<répertoire_d'installation_de_python>
# - taper la commande : py -m pip install Pillow
from PIL import Image, ImageDraw, ImageFont


# cette fonction détermine la couleur RGB d'une longueur d'onde WL
def color_of_ray( WL ):
    rouge = vert = bleu = int( 0 )
    if WL >=380 and WL < 420:
        amplification = 0.3 + 0.7 * ( WL - 380) / 40
        rouge = int( amplification * 255 * ( 440 - WL ) / 60 )
        vert = int( 0 )
        bleu = int( amplification * 255 )
    elif WL >=420 and WL < 440:
        rouge = int( 255 * ( 440 - WL ) / 60 )
        vert = int( 0 )
        bleu = int( 255 )
    elif WL >= 440 and WL < 490:
        rouge = int( 0 )
        vert = int( 255 * ( WL - 440 ) / 50 )
        bleu = int( 255 )
    elif WL >= 490 and WL < 510:
        rouge = int( 0 )
        vert = int( 255 )
        bleu = int( 255 * ( 510 - WL ) / 20 )
    elif WL >= 510 and WL < 580:
        rouge = int( 255 * ( WL - 510 ) / 70 )
        vert = int( 255 )
        bleu = int( 0 )
    elif WL >= 580 and WL < 645:
        rouge = int( 255 )
        vert = int( 255 * ( 645 - WL ) / 65 )
        bleu = int( 0 )
    elif WL >= 645 and WL < 700:
        rouge = int( 255 )
        vert = bleu = int( 0 )
    elif WL >= 700 and WL < 800:
        amplification = 0.3 + 0.7 * ( 800 - WL) / 100
        rouge = int( amplification * 255 )
        vert = bleu = int( 0 )
    return (rouge, vert, bleu)



# fonction appelée par le clic sur le bouton "Dessiner le spectre"
def dessiner_le_spectre():

    # création d'une fenêtre d'info
    ze_info_window = tk.Toplevel(fenetre, height=400, width=260)
    ze_info_window.configure(background='#000')
    ze_info_window.geometry("%dx%d%+d%+d" % (400, 260, 10, 10))
    ze_info_window.title('info')
    ze_font_info = font.Font(family='Helvetica', size='12', weight='bold')
    ze_bg = "#000"
    ze_fg = "#f00"

    label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = "Paramètres :", font=ze_font_info, anchor='w')
    label.grid(row=0, column=0, sticky = 'ew')

    while True :
        x = WL_start_saisie.get()
        try :
            WL_start = int(x)
            break
        except ValueError :
            WL_start_saisie.set("380")
            WL_start = 380
            pass

    while True :
        x = WL_end_saisie.get()
        try :
            WL_end = int(x)
            break
        except ValueError :
            WL_end_saisie.set("800")
            WL_end = 800
            pass

    if WL_start > WL_end: swap = WL_start ; WL_start = WL_end ; WL_end = swap
    if WL_start > 800: WL_start = 380 
    if WL_end < 380: WL_end = 800 

    # on se limite évidemment au spectre visible
    if WL_start < 380: WL_start = 380 
    if WL_end > 800: WL_end = 800 


    # Si un plaisantin a saisi des valeurs telles que WL_start = WL_end
    if int( WL_start ) == int( WL_end ):
        WL_start = 380
        WL_end = 800
    
    # fin traitement saisie WL_start et WL_end
    WL_start_saisie.set(WL_start)
    WL_end_saisie.set(WL_end)

    WL_range = WL_end - WL_start

    ze_font_info = font.Font(family='Helvetica', size='12', weight='normal')

    ze_text = "   --> " + str(WL_start) + " nm à " + str(WL_end) + " nm"
    label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
    label.grid( row = 1, column = 0, sticky = 'ew')

    ze_text = "   --> range : " + str(WL_range) + " nm"
    label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
    label.grid( row = 2, column = 0, sticky ='ew')

    while True :
        x = nb_pixels_largeur_saisie.get()
        try :
            nb_pixels_largeur = int(x)
            break
        except ValueError :
            nb_pixels_largeur_saisie.set("1260")
            nb_pixels_largeur = 1260
            pass

    while True :
        x = nb_pixels_hauteur_saisie.get()
        try :
            nb_pixels_hauteur = int(x)
            break
        except ValueError :
            nb_pixels_hauteur_saisie.set("160")
            nb_pixels_hauteur = 160
            pass

    s = nb_pixels_largeur * nb_pixels_hauteur
    # WL_resolution est le nombre de nanomètre que représente un pixel
    WL_resolution = ( WL_range ) / ( nb_pixels_largeur )

    ze_text = "   --> taille de l'image : " + str(nb_pixels_largeur) + " px × " + str(nb_pixels_hauteur) + " px = " + str(s) + " px²    "
    label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
    label.grid( row = 3, column = 0, sticky = 'ew')

    ze_text = "   --> résolution : {0:.2e}".format(WL_resolution) + " nm/pixel" 
    label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
    label.grid( row = 4, column = 0, sticky = 'ew')

    # une fois connue la largeur du spectre en pixels, création de deux listes
    # contenant la valeur en nanomètres du début du pixel et de la fin du pixel
    WL_list_start = []
    WL_list_end = []
    for i in range(nb_pixels_largeur):
        WL_list_start.append( WL_start + i * WL_resolution )
        WL_list_end.append( WL_start + ( i + 1 ) * WL_resolution )

    # test de l'argument n°5 : le type de spectre, 1, 2 ou 3
    choix_spectre = choix_spectre_value.get()

    if choix_spectre == "1":
        grad_color = ( 0, 0, 0 )
        ze_text = "   --> spectre continu"
    elif choix_spectre == "2":
        grad_color = ( 255, 255, 255 )
        ze_text = "   --> spectre d'émission"
    elif choix_spectre == "3":
        grad_color = ( 0, 0, 0 )
        ze_text = "   --> spectre d'absorption"

    label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
    label.grid( row = 5, column = 0, sticky = 'ew')

    # test de l'argument n°6 : oui ou non, imprimer la range en nm ?
    imprime_nanometres = imprime_nanometres_value.get()
    if imprime_nanometres =='n':
        choix_imprime_nanometres = False
        ze_text = "   --> pas d'impression des nanomètres"
    else:
        choix_imprime_nanometres = True
        ze_text = "   --> impression des nanomètres"

    label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
    label.grid(row = 6, column = 0, sticky = 'ew')

    # on n'a pas choisi le spectre continu : test des autres arguments.
    if choix_spectre != "1":
        liste_elements = []
        if var_Hydrogene.get() == "1" :
            liste_elements.append("H")
        if var_Helium.get() == "1" :
            liste_elements.append("He")
        if var_Lithium.get() == "1" :
            liste_elements.append("Li")
        if var_Sodium.get() == "1" :
            liste_elements.append("Na")
        if var_Magnesium.get() == "1" :
            liste_elements.append("Mg")
        if var_Argon.get() == "1" :
            liste_elements.append("Ar")
        if var_Calcium.get() == "1" :
            liste_elements.append("Ca")
        if var_Titane.get() == "1" :
            liste_elements.append("Ti")
        if var_Manganese.get() == "1" :
            liste_elements.append("Mn")
        if var_Fer.get() == "1" :
            liste_elements.append("Fe")
        if var_Hydrargyrum.get() == "1" :
            liste_elements.append("Hg")

        if ( len(liste_elements) == 0) :
            ze_font_info = font.Font(family='Helvetica', size='12', weight='bold')
            ze_text = "   --> AUCUN ÉLÉMENT SÉLECTIONNÉ !!" 
        else :
            ze_text = "   --> liste des éléments : " + str( liste_elements ) 
        
        label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
        label.grid(row = 7, column = 0, sticky = 'ew')

        imprime_elements = imprime_elements_value.get()
        if imprime_elements == 'n':
            choix_imprime_elements = False
            ze_text = "   --> pas d'impression du nom des éléments"
        else:
            choix_imprime_elements = True
            ze_text = "   --> impression du nom des éléments"

        ze_font_info = font.Font(family='Helvetica', size='12', weight='normal')

        label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
        label.grid(row = 8, column = 0, sticky = 'ew')

        # Établissement de la liste des raies à tracer
        # raies trouvées sur
        # https://media4.obspm.fr/public/ressources_lu/pages_tp-spectre-soleil/identification.html
        liste_de_toutes_les_raies=[]
        nom_element = ""
        for ze_element in liste_elements:
            if ze_element == "H":
                nom_element = nom_element + "Hydrogène "
                liste_raies = [ 388.9, 397, 410.2, 434.1, 486.1, 656.3 ]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "He":
                nom_element = nom_element + "Hélium "
                liste_raies = [ 447, 468.5, 471.5, 492, 501.5, 587.5, 668 ]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Li":
                nom_element = nom_element + "Lithium "
                liste_raies = [ 496, 549, 610, 671 ]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Na":
                nom_element = nom_element + "Sodium "
                liste_raies = [ 568.8, 589, 589.6, 615.4 ] 
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Mg":
                nom_element = nom_element + "Magnésium "
                liste_raies = [ 516.7, 517.3, 518.4 ]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Ar":
                nom_element = nom_element + "Argon "
                liste_raies = [ 452, 472, 562, 605, 644, 670 ]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Ca":
                nom_element = nom_element + "Calcium "
                liste_raies = [ 393.3, 396.9, 425, 433, 447, 588, 589, 614, 618, 646, 648, 674, 717, 735 ]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Ti":
                nom_element = nom_element + "Titane "
                liste_raies = [ 466.8, 469.1, 498.2 ]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Mn":
                nom_element = nom_element + "Manganèse "
                liste_raies = [ 402.1, 403.1, 403.6 ] 
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Fe":
                nom_element = nom_element + "Fer "
                liste_raies =  [ 389.9, 404.6, 423.4, 425.1, 426, 427.2, 438.3, 452.9, 459.3, 489.1, 491.9, 495.7, 501.2, 508, 527, 532.8, 536.7, 536.9, 543, 543.4, 544.7, 545.6, 561.6 ]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)
            elif ze_element == "Hg":
                nom_element = nom_element + "Hydrargyrum "
                liste_raies = [ 404.7, 435.8, 546.1, 577, 579.1]
                for raie in liste_raies:
                    if raie >= WL_start - 1 and raie <= WL_end + 1 :
                        liste_de_toutes_les_raies.append(raie)

        if ( len(liste_elements) == 0 ) :
            choix_imprime_elements = True
            nom_element = "C'est pas très malin de demander un spectre d'"
            if choix_spectre == "2" :
                nom_element = nom_element + "émission"
            else :
                nom_element = nom_element + "absorption"
            nom_element = nom_element + " sans sélectionner d'élément !"
            
        # tri de la liste de toutes les raies par ordre croissant
        x = liste_de_toutes_les_raies.sort()

    #creation en mémoire de l'image du spectre
    try:
        spectre_image = Image.new( "RGB", ( nb_pixels_largeur, nb_pixels_hauteur) )
    except:
        ze_font_info = font.Font(family='Helvetica', size='12', weight='bold')
        ze_text = "   Erreur à la création de l'image du spectre !!"
        label = tk.Label( ze_info_window, bg=ze_fg, fg=ze_bg, text = str(ze_text), font=ze_font_info, anchor = 'w')
        label.grid(row = 9, column = 0, sticky = 'ew')
        # sys.exit(1)

    now = datetime.now()
    timestamp_debut = datetime.timestamp(now)
    draw = ImageDraw.Draw(spectre_image)

    if choix_spectre == "1" :
        for i in range(nb_pixels_largeur):
            WL_middle = ( WL_list_start[i] + WL_list_end[i] ) / 2
            draw.line(( i, 0, i, nb_pixels_hauteur ), fill = color_of_ray( WL_middle ))
    else:
        if ( len(liste_elements) != 0 ) :
            ze_text = "   --> Liste des raies pour " + str( liste_elements ) + " :"
            # label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), anchor = 'w')
            # label.grid(row = 8, column = 0, sticky = 'ew')

            ze_text = str(liste_de_toutes_les_raies)
            # label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), anchor = 'w')
            # label.grid(row = 9, column = 0, sticky = 'ew')

            ze_text = "   --> " + str(len(liste_de_toutes_les_raies)) + " raies à tracer"
            label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
            label.grid(row = 9, column = 0, sticky = 'ew')

    # La largeur d'une raie dépend de la valeur de WL_resolution de manière à séparer les
    # raies mitoyennes quand on "zoome" en demandant une étendue faible en nanomètre mais
    # élevée en pixels.
    # Mais je voudrais qu'une raie soit large d'un nombre impair de pixels...
    # Sur la TODO list !
    if choix_spectre == "2" :
        for i in range(nb_pixels_largeur):
            WL_middle = ( WL_list_start[i] + WL_list_end[i] ) / 2
            for raie in liste_de_toutes_les_raies:
                if abs( WL_middle - raie ) <= ( 2 * WL_resolution ):
                    draw.line(( i, 0, i, nb_pixels_hauteur ), fill = color_of_ray( WL_middle ))

    if choix_spectre == "3" :
        for i in range(nb_pixels_largeur):
            WL_middle = ( WL_list_start[i] + WL_list_end[i] ) / 2
            draw_the_ray = True
            for raie in liste_de_toutes_les_raies:
                if abs( WL_middle - raie ) <= ( 2 * WL_resolution ):
                    draw_the_ray = False # on est à moins de 0,5 nm d'une raie : laisser noir

            if draw_the_ray:
                draw.line(( i, 0, i, nb_pixels_hauteur ), fill = color_of_ray( WL_middle ))

    fonte_image = ImageFont.truetype(CONST_FONTE, CONST_FONTE_TAILLE)
    draw = ImageDraw.Draw(spectre_image)

    if choix_imprime_nanometres:
        Comment = "from " + str( WL_start ) + " nm to " + str( WL_end ) + " nm" 
    else:
        Comment = ""

    if choix_spectre == "2" :
        # fond noir
        if choix_imprime_nanometres:
            draw.text((10.0, 8.0), Comment, grad_color, font=fonte_image)
        if choix_imprime_elements:
            draw.text((10.0, 22.0), nom_element, grad_color, font=fonte_image)
    else:
        # fond coloré pour le spectre continu (1) ou le spectre d'absoption (3)
        if choix_imprime_nanometres:
            draw.text((9.0, 7.0), Comment, ( 255, 255, 255 ), font=fonte_image)
            draw.text((9.0, 8.0), Comment, ( 255, 255, 255 ), font=fonte_image)
            draw.text((9.0, 9.0), Comment, ( 255, 255, 255 ), font=fonte_image)
            draw.text((10.0, 7.0), Comment, ( 255, 255, 255 ), font=fonte_image)
            draw.text((10.0, 9.0), Comment, ( 255, 255, 255 ), font=fonte_image)
            draw.text((11.0, 7.0), Comment, ( 255, 255, 255 ), font=fonte_image)
            draw.text((11.0, 8.0), Comment, ( 255, 255, 255 ), font=fonte_image)
            draw.text((11.0, 9.0), Comment, ( 255, 255, 255 ), font=fonte_image)
            draw.text((10.0, 8.0), Comment, grad_color, font=fonte_image)
        if choix_spectre == "3" :
            if choix_imprime_elements:
                draw.text((9.0, 21.0), nom_element, ( 255, 255, 255 ), font=fonte_image)
                draw.text((9.0, 22.0), nom_element, ( 255, 255, 255 ), font=fonte_image)
                draw.text((9.0, 22.0), nom_element, ( 255, 255, 255 ), font=fonte_image)
                draw.text((10.0, 21.0), nom_element, ( 255, 255, 255 ), font=fonte_image)
                draw.text((10.0, 23.0), nom_element, ( 255, 255, 255 ), font=fonte_image)
                draw.text((11.0, 21.0), nom_element, ( 255, 255, 255 ), font=fonte_image)
                draw.text((11.0, 22.0), nom_element, ( 255, 255, 255 ), font=fonte_image)
                draw.text((11.0, 23.0), nom_element, ( 255, 255, 255 ), font=fonte_image)
                draw.text((10.0, 22.0), nom_element, grad_color, font=fonte_image)
        
    # tracé des graduations
    h100nm = nb_pixels_hauteur // 4      # un trait long pour 100 nm
    h50nm = nb_pixels_hauteur // 8       # un trait moyen pour 50 nm
    h10nm = nb_pixels_hauteur // 16      # un trait court pour 10 nm 
    base = nb_pixels_hauteur             # base du trait

    # grad_color a été déterminée au moment du choix de type de spectre.
    # largeur d'un trait de graduation en pixel : grad_W
    #    impair
    #    peu ou prou égal à un nanomètre donc (presque égal à 1 / WL_resolution)
    WL_res_inverse = 1 / WL_resolution

    if int( WL_res_inverse ) % 2 == 0:   # pair
        grad_W = int( WL_res_inverse ) + 1
    else:  # impair
        grad_W = int( WL_res_inverse )

    # graduation sur le premier pixel ? (donc i = 0)
    if WL_start % 100 == 0:
        draw.line( ( 0, base, 0, base - h100nm ), fill=grad_color )
        draw.rectangle(((0, base), (((grad_W - 1) / 2), base - h100nm + 1)), fill=grad_color )
    elif WL_start % 50 == 0:
        draw.line( ( 0, base, 0, base - h50nm ), fill=grad_color )
        draw.rectangle(((0, base), (((grad_W - 1 ) / 2), base - h50nm + 1)), fill=grad_color)
    elif WL_start % 10 == 0:
        draw.line(( 0, base, 0, base - h10nm ), fill=grad_color )
        draw.rectangle(((0, base), (((grad_W - 1 ) / 2), base - h10nm + 1)), fill=grad_color)

    for i in range(nb_pixels_largeur):
        # un trait vertical quand passer de WL_list_start[i] à WL_list_end[i] fait
        # changer de centaine sur les nanomètres...
        if WL_list_start[i] // 100 != WL_list_end[i] // 100 :
            # changement de centaine sur les nanomètres
            draw.line(( i, base, i, base - h100nm), fill=grad_color)
            draw.rectangle(((i-((grad_W-1)/2),base),(i+((grad_W-1)/2),base - h100nm + 1)), fill=grad_color)
        elif WL_list_start[i] // 50 != WL_list_end[i] // 50 :
            # changement de cinquantaine sur les nanomètres
            draw.line(( i, base, i, base - h50nm), fill=grad_color)
            draw.rectangle(((i-((grad_W-1)/2),base),(i+((grad_W-1)/2),base - h50nm + 1)), fill=grad_color)
        elif WL_list_start[i] // 10 != WL_list_end[i] // 10 :
            # changement de dizaine sur les nanomètres
            draw.line(( i, base, i, base - h10nm), fill=grad_color)
            draw.rectangle(((i-((grad_W-1)/2),base),(i+((grad_W-1)/2),base - h10nm + 1)), fill=grad_color)

    spectre_image.show()
    
    now = datetime.now()
    timestamp_fin = datetime.timestamp(now)
    duree = timestamp_fin - timestamp_debut
    ze_text = "   --> done in {0:.3f}".format(duree) + " seconde"
    label = tk.Label( ze_info_window, bg=ze_bg, fg=ze_fg, text = str(ze_text), font=ze_font_info, anchor = 'w')
    label.grid(row = 10, column = 0, sticky = 'ew')

    if messagebox.askyesno("Enregister", "Enregister le spectre ?") :

        if choix_spectre == "1" :
            nom_image = "Spectre_continu_"
        elif choix_spectre == "2" :
            nom_image = "Spectre_emission_"
        else :
            nom_image = "Spectre_absorption_"

        nom_image = nom_image + str(WL_start) + "_to_" + str(WL_end)
        if choix_spectre == "2" or choix_spectre == "3": 
            for ze_element in liste_elements:
                nom_image = nom_image + "_" + ze_element

        year = now.year
        month = now.month
        if month < 10:
            month = "0" + str( month )
        day = now.day
        if day < 10:
            day = "0" + str( day )
        hour = now.hour
        if hour < 10:
            hour = "0" + str( hour )
        minute = now.minute
        if minute < 10:
            minute = "0" + str( minute )
        second = now.second
        if second < 10:
            second = "0" + str( second )

        nom_image = nom_image + "_" + str(year) + "-" + str(month) + "-" + str(day) 
        nom_image = nom_image + "_" + str(hour) + str(minute) + str(second) + str(".png")
        spectre_image.save( nom_image, "PNG" )
    
        messagebox.showinfo("Enregistré", "Spectre enregistré sous\n" + nom_image)
        ze_info_window.destroy()
    else :
        ze_info_window.destroy()



fenetre = tk.Tk()
# http://python.jpvweb.com/python/mesrecettespython/doku.php?id=geometrie_fenetre
#fenetre.geometry("%dx%d%+d%+d" % (700,400,50,50))
#fenetre.geometry('700x400')
fenetre.configure(background='#86b')
fenetre.title('Spectres lumineux')
fenetre.iconbitmap('@' + 'spectre.xbm')

ze_font = font.Font(family='Helvetica', size='12')

# code RGB classique, sur 4, 8 ou 12 bits
ze_bg='#a0a0ff'  #bg = background = couleur du fond
ze_fg='#404080'  #fg = foreground = couleur du texte
ze_abg='#ffff60'  #active_foreground = couleur du fond survolé
# à choisir parmi 'flat', 'raised', 'sunken', 'groove', 'ridge'
# http://tkinter.fdex.eu/doc/sa.html#reliefs
ze_relief='groove'
# 'borderwidth' peut s'abréger en 'bd' : valeur en pixels
ze_bd=4



# frame pour le mode d'emploi
cadre_MdE = tk.Frame(fenetre, bg=ze_bg, relief=ze_relief, bd=ze_bd)
cadre_MdE.grid( row=0, column=0, padx=10, pady=5, ipadx=10, sticky='ew')

label = tk.Label( cadre_MdE, bg=ze_bg, fg=ze_fg, text = "Mode d'emploi :", font=ze_font)
label.grid( row=0, sticky='w')

label = tk.Label( cadre_MdE, bg=ze_bg, fg=ze_fg, text = " - il faut saisir longueur d'onde initiale et finale (en nanomètres) ;", font=ze_font)
label.grid( row=1, sticky='w')

label = tk.Label( cadre_MdE, bg=ze_bg, fg=ze_fg, text = " - largeur et hauteur de l'image contenant le spectre (en pixels) ;", font=ze_font)
label.grid( row=2, sticky='w')

label = tk.Label( cadre_MdE, bg=ze_bg, fg=ze_fg, text = " - le type de spectre : continu, émission ou absorption ;", font=ze_font)
label.grid( row=3, sticky='w')

label = tk.Label( cadre_MdE, bg=ze_bg, fg=ze_fg, text = " - éventuellement la liste des éléments chimiques ;", font=ze_font)
label.grid( row=4, sticky='w')

label = tk.Label( cadre_MdE, bg=ze_bg, fg=ze_fg, text = " - indiquer si on souhaite que le nom des éléments soit inscrit sur le spectre.", font=ze_font)
label.grid( row=5, sticky='w')



# frame pour la saisie des longueurs d'onde _ET_ les pixels (contient deux frames)
cadre_spectre_input = tk.Frame(fenetre, bg=ze_bg, relief=ze_relief, bd=ze_bd)
cadre_spectre_input.grid( row=1, column=0, padx=10, pady=5, ipadx=10, sticky='ew')



# (sous-)frame pour la saisie des longueurs d'onde
cadre_spectre_WL = tk.Frame(cadre_spectre_input, bg=ze_bg)
cadre_spectre_WL.grid( row=0, ipadx=10, ipady=0, sticky='w')

label = tk.Label( cadre_spectre_WL, bg=ze_bg, fg=ze_fg, text = "Longueur d'onde initiale :", font=ze_font)
label.grid( row=0, column=0, sticky='w')

WL_start_saisie = tk.StringVar() 
WL_start_saisie.set("380")
saisie_WL_start = tk.Entry( cadre_spectre_WL, textvariable = WL_start_saisie, width=3, font=ze_font)
saisie_WL_start.grid( row=0, column=1)

label = tk.Label( cadre_spectre_WL, bg=ze_bg, fg=ze_fg, text = " (nm) ; longueur d'onde finale :", font=ze_font)
label.grid( row=0, column=2)

WL_end_saisie = tk.StringVar() 
WL_end_saisie.set("800")
saisie_WL_end = tk.Entry( cadre_spectre_WL, textvariable = WL_end_saisie, width=3, font=ze_font)
saisie_WL_end.grid( row=0, column=3)

label = tk.Label( cadre_spectre_WL, bg=ze_bg, fg=ze_fg, text = " (nm).", font=ze_font)
label.grid( row=0, column=4)



# (sous-)frame pour la saisie des pixels
cadre_spectre_pixels = tk.Frame(cadre_spectre_input, bg=ze_bg)
cadre_spectre_pixels.grid( row=1, ipadx=10, ipady=0, sticky='ew')

label = tk.Label( cadre_spectre_pixels, bg=ze_bg, fg=ze_fg, text = "Dimensions de l'image du spectre, largeur :", font=ze_font)
label.grid( row=0, column=0, sticky='w')

nb_pixels_largeur_saisie = tk.StringVar() 
nb_pixels_largeur_saisie.set("1260")
saisie_nb_pixels_largeur = tk.Entry( cadre_spectre_pixels, textvariable = nb_pixels_largeur_saisie, width=4, font=ze_font)
saisie_nb_pixels_largeur.grid( row=0, column=1)

label = tk.Label( cadre_spectre_pixels, bg=ze_bg, fg=ze_fg, text = " (pixels) ; hauteur : ", font=ze_font)
label.grid( row=0, column=2)

nb_pixels_hauteur_saisie = tk.StringVar() 
nb_pixels_hauteur_saisie.set("160")
saisie_nb_pixels_hauteur = tk.Entry( cadre_spectre_pixels, textvariable = nb_pixels_hauteur_saisie, width=4, font=ze_font)
saisie_nb_pixels_hauteur.grid( row=0, column=3)

label = tk.Label( cadre_spectre_pixels, bg=ze_bg, fg=ze_fg, text = " (pixels) ", font=ze_font)
label.grid( row=0, column=4)



# frame pour le choix du type de spectre
cadre_choix_spectre = tk.Frame( fenetre, bg=ze_bg, relief=ze_relief, bd=ze_bd)
cadre_choix_spectre.grid( row=2, column=0, padx=10, pady=5, ipadx=10, sticky='ew')

texte_choix_spectre = tk.Label( cadre_choix_spectre, bg=ze_bg, fg=ze_fg, text = "Type de spectre :", font=ze_font)
texte_choix_spectre.grid( row=0, column=0, )

choix_spectre_value = tk.StringVar()
choix_spectre_value.set("2")
choix_spectre_continu = tk.Radiobutton(cadre_choix_spectre, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="continu", variable=choix_spectre_value, value = "1", highlightthickness=0, font=ze_font)
choix_spectre_emission = tk.Radiobutton(cadre_choix_spectre, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="émission", variable=choix_spectre_value, value = "2", highlightthickness=0, font=ze_font)
choix_spectre_absorption = tk.Radiobutton(cadre_choix_spectre, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="absorption", variable=choix_spectre_value, value = "3", highlightthickness=0, font=ze_font)
choix_spectre_continu.grid(row=0, column=1, padx=10, pady=0, sticky='ew')
choix_spectre_emission.grid(row=0, column=2, padx=10, pady=0, sticky='ew')
choix_spectre_absorption.grid(row=0, column=3, padx=10, pady=0, sticky='ew')



# frame pour le choix de l'impression des nanometres
cadre_imprime_nanometres = tk.Frame( fenetre, bg=ze_bg, relief=ze_relief, bd=ze_bd)
cadre_imprime_nanometres.grid( row=3, column=0, padx=10, pady=5, ipadx=10, sticky='ew')

texte = tk.Label( cadre_imprime_nanometres, bg=ze_bg, fg=ze_fg, text = "Écrire l'échelle en nanomètres sur l'image ?", font=ze_font)
texte.grid( row=0, column=0)

imprime_nanometres_value = tk.StringVar()
imprime_nanometres_value.set("o")
imprime_nanometres_oui = tk.Radiobutton(cadre_imprime_nanometres, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="oui", variable=imprime_nanometres_value, value="o", highlightthickness=0, font=ze_font)
imprime_nanometres_non = tk.Radiobutton(cadre_imprime_nanometres, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="non", variable=imprime_nanometres_value, value="n", highlightthickness=0, font=ze_font)
imprime_nanometres_oui.grid(row=0, column=1, padx=10, pady=0, sticky='ew')
imprime_nanometres_non.grid(row=0, column=2, padx=10, pady=0, sticky='ew')



# frame pour choisir les éléments chimiques
cadre_choix_elements = tk.Frame( fenetre, bg=ze_bg, relief=ze_relief, bd=ze_bd, cursor='pirate')
cadre_choix_elements.grid( row=4, column=0, padx=10, pady=5, ipadx=10, sticky='ew')
cadre_choix_elements.columnconfigure(0, weight=1)
cadre_choix_elements.columnconfigure(1, weight=1)
cadre_choix_elements.columnconfigure(2, weight=1)
cadre_choix_elements.columnconfigure(3, weight=1)

texte = tk.Label( cadre_choix_elements, bg=ze_bg, fg=ze_fg, text = "Éléments chimiques :", font=ze_font)
texte.grid( row=0, column=0, sticky='w')

ze_sticky = 'ew'

var_Hydrogene = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Hydrogène", anchor='w', variable=var_Hydrogene, highlightthickness=0, font=ze_font)
case.grid( row=1, column=0, sticky=ze_sticky)
# var_Hydrogene.get()
# Si la case est cochée, la valeur renvoyée par la variable sera la chaîne "1".
# Si elle n'est pas cochée, ce sera "0".
# Ça se teste avec if var_Hydrogene.get() == "1" (PAS == 1)

var_Helium = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Hélium", anchor='w', variable=var_Helium, highlightthickness=0, font=ze_font)
case.grid( row=1, column=1, sticky=ze_sticky)

var_Lithium = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Lithium", anchor='w', variable=var_Lithium, highlightthickness=0, font=ze_font)
case.grid( row=1, column=2, sticky=ze_sticky)

var_Sodium = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Sodium", anchor='w', variable=var_Sodium, highlightthickness=0, font=ze_font)
case.grid( row=1, column=3, sticky=ze_sticky)

var_Magnesium = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Magnésium", anchor='w', variable=var_Magnesium, highlightthickness=0, font=ze_font)
case.grid( row=2, column=0, sticky=ze_sticky)

var_Argon = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Argon", anchor='w', variable=var_Argon, highlightthickness=0, font=ze_font)
case.grid( row=2, column=1, sticky=ze_sticky)

var_Calcium = tk.StringVar()
# var_Calcium.set("1")
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Calcium", anchor='w', variable=var_Calcium, highlightthickness=0, font=ze_font)
case.grid( row=2, column=2, sticky=ze_sticky)

var_Titane = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Titane", anchor='w', variable=var_Titane, highlightthickness=0, font=ze_font)
case.grid( row=2, column=3, sticky=ze_sticky)

var_Manganese = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Manganèse", anchor='w', variable=var_Manganese, highlightthickness=0, font=ze_font)
case.grid( row=3, column=0, sticky=ze_sticky)

var_Fer = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Fer", anchor='w', variable=var_Fer, highlightthickness=0, font=ze_font)
case.grid( row=3, column=1, sticky=ze_sticky)

var_Hydrargyrum = tk.StringVar()
case = tk.Checkbutton(cadre_choix_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="Hydrargyrum", anchor='w', variable=var_Hydrargyrum, highlightthickness=0, font=ze_font)
case.grid( row=3, column=2, sticky=ze_sticky)



# frame pour le choix de l'impression des éléments
cadre_imprime_elements = tk.Frame( fenetre, bg=ze_bg, relief=ze_relief, bd=ze_bd)
cadre_imprime_elements.grid( row=5, column=0, padx=10, pady=5, ipadx=10, sticky='ew')

texte = tk.Label( cadre_imprime_elements, bg=ze_bg, fg=ze_fg, text = "Écrire les éléments chimiques sur l'image ?", font=ze_font)
texte.grid( row=0, column=0)

imprime_elements_value = tk.StringVar()
imprime_elements_value.set("o")
imprime_elements_oui = tk.Radiobutton(cadre_imprime_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="oui", variable=imprime_elements_value, value="o", highlightthickness=0, font=ze_font)
imprime_elements_non = tk.Radiobutton(cadre_imprime_elements, bg=ze_bg, fg=ze_fg, activebackground=ze_abg, text="non", variable=imprime_elements_value, value="n", highlightthickness=0, font=ze_font)
imprime_elements_oui.grid(row=0, column=1, padx=10, pady=0, sticky='ew')
imprime_elements_non.grid(row=0, column=2, padx=10, pady=0, sticky='ew')



# frame pour les boutons 'Quitter' et 'Dessiner le spectre'
cadre_boutons = tk.Frame( fenetre, bg=ze_bg, relief=ze_relief, bd=ze_bd)
cadre_boutons.grid( row=6, column=0, padx=10, pady=5, ipadx=10, ipady=0, sticky='ew')
cadre_boutons.columnconfigure(0, weight=1)
cadre_boutons.columnconfigure(1, weight=1)
cadre_boutons.columnconfigure(2, weight=1)
cadre_boutons.columnconfigure(3, weight=1)

button = tk.Button( cadre_boutons, text = "Quitter", bg=ze_bg, fg=ze_fg, activebackground=ze_abg, command = fenetre.quit, font=ze_font, anchor='w')
button.grid( row=0, column=0, padx=10, pady=5, sticky='w')

cadre_notice = tk.Frame( cadre_boutons, bg=ze_bg, relief='flat', bd=ze_bd)
cadre_notice.grid( row=0, column=1, columnspan=2, sticky='ew')

ze_font = font.Font(family='Helvetica', size='9')
label = tk.Label( cadre_notice, bg=ze_bg, fg=ze_fg, text = "Auteur : Hugues FERTIN, <h.fertin@ac-rouen.fr>", font=ze_font)
label.grid( row=0, column=0, columnspan=2, sticky='ew')
label = tk.Label( cadre_notice, bg=ze_bg, fg=ze_fg, text = "licence CC-BY-NC-SA : attribution, non-commercial, share alike", font=ze_font)
label.grid( row=1, column=0, columnspan=2, sticky='ew')

ze_font = font.Font(family='Helvetica', size='12')
button = tk.Button( cadre_boutons, text = "Dessiner le spectre", bg=ze_bg, fg=ze_fg, activebackground=ze_abg, command = dessiner_le_spectre, font=ze_font, anchor='e')
button.grid( row=0, column=3, padx=10, pady=5, sticky='e')

# vendredi 20 mars 2020, 11:59:02 (UTC+0100)
# pas encore compris comment ça marche...
#fenetre.bind_all('<Return>', dessiner_le_spectre)

fenetre.mainloop()

Back to fr.comp.lang.python | Previous | NextPrevious in thread | Find similar


Thread

erreur 'UnboundLocalError' incompréhensible Lulu <lulu042@fry.fr.invalid> - 2020-03-19 00:33 +0100
  Re: erreur 'UnboundLocalError' incompréhensible Nicolas <nicolasp@aaton.com> - 2020-03-19 19:06 +0100
    Re: erreur 'UnboundLocalError' incompréhensible Lulu <lulu042@fry.fr.invalid> - 2020-03-20 12:11 +0100

csiph-web