#! /usr/bin/python3 from math import * import time, sys, random, os sv5=sys.version.split()[0] try: from tkinter import * from tkinter.colorchooser import * from tkinter.messagebox import * from tkinter.filedialog import * except: input(""" Python %s Tkinter module is not on your system. Linux provides it under the name python3-tk or so. Windows: I really don't know... tkinter n'est pas installé sur votre système Le nom sous Linux est python3-tk ou proche Pour Windows... je n'en sais rien Hit [Enter/Return] / Frappez [Entrer/Retour]... """ %(sv5)) sys.exit() r=250 # rayon maximal, addition des trois rayons back6="#ffffff"; fore6="#000000"; fore6bis="#00dd00" couleur=0 rainure="#789" svr=0 dec1=0; dec2=0; dec3=0 back0=""; nouveau=False fcolor="#d3d7cf" # random configuration precfg=random.randrange(12) if precfg==0: r1,r2,r3,s2,s3,t2,t3,g,q=100,55,85,9,9,0,1,1,1 elif precfg==1: r1,r2,r3,s2,s3,t2,t3,g,q=94,49,97,5,5,1,0,1,1 elif precfg==2: r1,r2,r3,s2,s3,t2,t3,g,q=114,45,81,10,5,1,1,1,1 elif precfg==3: r1,r2,r3,s2,s3,t2,t3,g,q=128,30,82,3,4,1,0,1,1 elif precfg==4: r1,r2,r3,s2,s3,t2,t3,g,q=151,28,61,12,3,0,1,1,1 elif precfg==5: r1,r2,r3,s2,s3,t2,t3,g,q=165,36,39,12,3,1,0,1,1 elif precfg==6: r1,r2,r3,s2,s3,t2,t3,g,q=190,30,20,4,6,1,0,1,1 elif precfg==7: r1,r2,r3,s2,s3,t2,t3,g,q=194,19,27,3,4,1,1,1,1 elif precfg==8: r1,r2,r3,s2,s3,t2,t3,g,q=104,99,37,6,12,0,0,1,1 elif precfg==9: r1,r2,r3,s2,s3,t2,t3,g,q=109,99,32,6,18,0,0,1,1 elif precfg==10: r1,r2,r3,s2,s3,t2,t3,g,q=115,94,31,6,11,0,1,1,1 elif precfg==11: r1,r2,r3,s2,s3,t2,t3,g,q=117,28,95,12,3,1,0,1,1 languages=(".fr", ".en", ".sp", ".nl") colorbox={} colorbox[".fr"]=["Information", "Il est impossible de modifier la couleur de fond sans commencer un nouveau dessin. La couleur de fond précédente va être restaurée."] colorbox[".en"]=["Information","It's not possible to modify the back colour without a new drawing. The former colour will be restaurated."] colorbox[".sp"]=["Información","No es posible de cambiar el color de fundo sin empezar un nuevo dibujo. El antiguo color resultará restaurado"] colorbox[".nl"]=["Informatie","'t Is niet mogelijk een nieuwe kleur te zetten zonder een nieuwe tekening te beginnen. De oude kleur zal terug zijn."] title={} title[".fr"]="À propos de 'Boucles'" title[".en"]="About 'Boucles'" title[".es"]="Sobre 'Boucles'" title[".nl"]="Over 'Boucles'" title["ver"]="Pedigree, versions, to-do and bugs" manual={} manual["ver"]="""ver 0.98 [2014.11.02] GPL2 - Jean-Christophe Beumier GPL2: www.gnu.org/licenses/old-licenses/gpl-2.0.txt jchrbe.pythonblogs.com - www.jchr.be/python written with python 2.7 et Tkinter 8.5 ImageMagick recommended *Already done... 2014.05.17 [0.90] minimal command-line script, random 2nd and 3rd rayon length, random loop number, clockwise or counterclockwise, bold line only 2014.06.01 [0.91] first adaptation to Tkinter: [--] (-10), [-] (-1), [+] (+1) and [++] (+10) buttons for radius length and loop number - [Nouveau] ('new') and [Ajout] ('add') action buttons - [Hasard] (random) button for lack of inspiration 2014.10.08 [0.92] first french doc - english, spanish and dutch ones planned 2014.10.20 [0.93] twelve built-in curves randomly choosen at welcome - curve sliders rather than [--], [-], [+] and [++] button for loop numbers and radius length settings - colours for line and background 2014.10.25 [0.94] burst mode: severals intermediate curves between two 2ry/3ry radius lengths and two colours (easier than thought) 2014.10.31 [0.95] reorienting the whole graphic from 0° to 360°, dephasing secundary and tertiary cycles as well (spent a lot of time to find a former bug: the first loop was clockwise - damned!) - line density from 1 to 16 thousands dots per curve to adjust to graphic complexity 2014.11.02 [0.96] n repetitions each 360°/n - swapping foreground colours - sliders for doc windows and this one 2014.11.19 [0.97] genuine french doc with an enhanced display - shows the whole graphic dots number: 16kdots density, burst=60, repetition=16 and bold (=2) means 30720 kdots (about 15min on my computer)! 2014.11.26 [0.98]; saving the making-off in the namefile, and getting parameters by filename *Soon... - genuine english / spanish / dutch translations for [Help] windows - and this one - before version 1.00! - saving the whole making-off into a file-info, allowing further loading of parameters - any version: correcting bugs, renaming variables and better comments for a genuine GPL-app - some more information boxes needed! *Known bugs 2014.11.05: the application hangs when asking too much (burst mode=50, repetitions=10, density=16...); making rather difficult to kill the application 2014.10.28: activating the burst mode doesn't colourise the [2] button at once; it only does when hovering it with the mouse""" manual[".fr"]="""Documentation par Jean-Christophe Beumier - 2014.11.19 *Argument Comme la terre tourne autour du soleil, la lune autour de la terre et Lunik 10 autour de la lune du 3 avril au 30 mai 1966, cette application dessine une courbe fermée composée de trois cycles dans un carré de 512px de côté *Boutons du haut [Exit] fait quitter l'application [Charg.] (en débogage) charge des paramètres en fonction du titre d'une image déjà sauvegardée. [Sauv.] sauvegarde le graphique réalisé par l'application, au format PNM: «P5» pour les dessins en N/B ou gris, ou «P6» pour les dessins en couleurs. Pour les systèmes UNIX munis de ImageMagick, le fichier au format PNM est transformé en PNG, économique et sans perte de qualité. Les données sont écrites dans le nom du fichier, ce qui permet à l'application de se remémorer les paramètres en chargeant le fichier. *Informations '00008 kilopt' donne le nombre de milliers de points que les boutons [Dessin] ou [Ajout] vont dessiner. Sur un amd64 à 1.7GHz, cela prend environ 20 kpt par seconde: Le maximum, 30720, prendrait alors 1500 secondes, c'est-à-dire 25 minutes! [.fr], [.en], [.es] et [.nl] affichent la documentation en une de ces quatres langues. [version] fournit les diverses étapes de l'écriture de l'application, le todo et les bugs connus. *Cycle primaire 'C1: 000px' est la longueur du cycle primaire, il est déduit de la longueur des cycles secondaire et tertiaire, la somme des trois cycles valant 250px 'C2: 000px' (seulement en mode «Rafale») est la longueur du cycle primaire pour une seconde courbe. 'Trigo' rappelle que le premier cycle court toujours dans le sens trigonométrique. '+000°' permet de réorienter la courbe (de 0 à 360°). *Cycles secondaire et tertiaire 'C1: 000px' affiche la longueur du rayon du cycle secondaire ou tertiaire (de 0 à 120px), modifiable par l'ascenseur horizontal situé à droite. 'C2: 000px' (seulement en mode «Rafale») idem pour une deuxième courbe. '000sp' afffiche le nombre de spires du cycle secondaire ou tertiaire, modifiable par l'ascenseur à droite (de 0 à 100). [Trigo] définit le sens du cycle secondaire ou tertiaire: noir sur fond blanc pour le sens trigonométrique, noir sur fond gris pour le sens horaire. '+000°' permet de déphaser les cycles secondaire ou tertiaire (de 0 à 360°). *Généralités [ ] appelle la boîte de sélection des couleurs pour définir la couleur de fond de l'image. [1] appelle la boîte de sélection des couleurs pour définir la couleur de la première courbe. [<>] (en mode «rafale» seulement) permet d'intervertir les couleurs de la première et seconde courbe. [2] (en mode «rafale» seulement) appelle la boîte de sélection des couleurs pour définir la couleur de la seconde courbe. [g] définit l'épaisseur de la courbe: noir sur fond blanc pour deux pixels, noir sur fond gris pour un simple pixel. 'd: 4 ^' permet de définir la densité de la courbe, de 1 à 16 milliers de points pour la révolution complète d'une courbe (4 milliers par défaut). *Répétitions 'x 1 ^' permet de répéter le graphique: pour n répétitions, la courbe est répétée tous les (360/n)°. [Rafale] permet de passer en mode «rafale», à savoir plusieurs courbes de la première à la seconde (comprise), définies selon les rayons '1' et '2' et les couleurs associées. Les courbes intermédiaires sont colorées selon le gradient de couleur. '05' (mode «rafale» seulement) est le nombre de courbes (de 2 à 60) définissable par l'ascenseur à droite. *Action [Nouveau] efface et dessine un graphique complet selon les paramètres définis. [Ajout] dessine un graphique au dessus d'un autre existant déjà. Attention: dans ce cas, une nouvelle couleur de fond ne sera pas prise en compte. [Hasard] dessine un graphique selon des paramètres redéfinis au hasard.""" manual[".en"]="""translation in progress - 2014.11.26 *Plot As the earth revolves around the sun, the moon around the earth and Lunik 10 around the moon from April 3 to May 30, 1966 and perhaps later, «Boucles» draws a three cycles curve. *First buttons [Exit] fait quitter l'application. [Charg.] (on debugging) load parameters following the image title already saved [Sauv.] sauvegarde le graphique réalisé par l'application, au format PNM: «P5» pour les dessins en N/B ou gris, ou «P6» pour les dessins en couleurs. Pour les systèmes UNIX munis de ImageMagick, le fichier au format PNM est transformé en PNG, économique et sans perte de qualité. Les données sont écrites dans le nom du fichier, ce qui permet à l'application de se remémorer les paramètres en chargeant le fichier. *Informations '00008 kilopt' donne le nombre de milliers de points que les boutons [Dessin] ou [Ajout] vont dessiner. Sur un amd64 à 1.7GHz, cela prend environ 20000 pt par seconde. [.fr], [.en], [.es] et [.nl] affichent la documentation en une de ces quatres langues. [version] fournit les diverses étapes de l'écriture de l'application, le todo et les bugs connus. *Cycle primaire 'C1: 000px' est la longueur du cycle primaire, il est déduit de la longueur des cycles secondaire et tertiaire, la somme des trois cycles valant 250px. 'C2: 000px' (seulement en mode «Rafale») est la longueur du cycle primaire pour une seconde courbe. 'Trigo' rappelle que le premier cycle court toujours dans le sens trigonométrique. '+000°' permet de réorienter la courbe (de 0 à 360°). *Cycles secondaire et tertiaire 'C1: 000px' affiche la longueur du rayon du cycle secondaire ou tertiaire (de 0 à 120px), modifiable par l'ascenseur horizontal situé à droite. 'C2: 000px' (seulement en mode «Rafale») idem pour une deuxième courbe. '000sp' afffiche le nombre de spires du cycle secondaire ou tertiaire, modifiable par l'ascenseur à droite (de 0 à 100). [Trigo] définit le sens du cycle secondaire ou tertiaire: noir sur fond blanc pour le sens trigonométrique, noir sur fond gris pour le sens horaire. '+000°' permet de déphaser les cycles secondaire ou tertiaire (de 0 à 360°) *Généralités [ ] appelle la boîte de sélection des couleurs pour définir la couleur de fond de l'image. [1] appelle la boîte de sélection des couleurs pour définir la couleur de la première courbe. [<>] (en mode «rafale» seulement) permet d'intervertir les couleurs de la première et seconde courbe. [2] (en mode «rafale» seulement) appelle la boîte de sélection des couleurs pour définir la couleur de la seconde courbe. [g] définit l'épaisseur de la courbe: noir sur fond blanc pour deux pixels, noir sur fond gris pour un simple pixel. 'd: 4 ^' permet de définir la densité de la courbe, de 1 à 16 milliers de points pour la révolution complète d'une courbe (4 milliers par défaut). *Répétitions 'x 1 ^' permet de répéter le graphique: pour n répétitions, la courbe est répétée tous les (360/n)°. [Rafale] permet de passer en mode «rafale», à savoir plusieurs courbes de la première à la seconde (comprise), définies selon les rayons '1' et '2' et les couleurs associées. Les courbes intermédiaires sont colorées selon le gradient de couleur. '05' (mode «rafale» seulement) est le nombre de courbes (de 2 à 60) définissable par l'ascenseur à droite. *Action [Nouveau] efface et dessine un graphique complet selon les paramètres définis. [Ajout] dessine un graphique au dessus d'un autre existant déjà. Attention: dans ce cas, une nouvelle couleur de fond ne sera pas prise en compte. [Hasard] dessine un graphique selon des paramètres redéfinis au hasard.""" manual[".es"]="""hasta la traducción, siempre! *Guión [Exit] para irse. [Charg.] (en debogaje) carga parámetros según el título de una imagen. [Sauv.] salva el gráfico, sobre el formato PNM: «P5» para los dibujos blanco y negra, o «P6» para los dibujos en colores. Para los systemas UNIX con «ImageMagick», el fichero resulta transformado en PNG, éconómico y sin perdida de qualidad. Los datos son escrito en el nombre de fichero, y eso permite a la aplication de recoger los parámetros cargando el fichero. *Informations '00008 kilopt' da el nombre de millares de puntos que los botones [Dessin] o [Ajout] van a dibujar. Con un amd64 de 1.7GHz, eso toma mas o menos 20000 pts per secundas. [.fr], [.en], [.es] et [.nl] dan la documentación en una de esos quatros lenguages. [version] dan las differentes etapas de la escritura de la applicación, el 'to-do' et los bugs conocidos. *Cycle primaire 'C1: 000px' est la longueur du cycle primaire, il est déduit de la longueur des cycles secondaire et tertiaire, la somme des trois cycles valant 250px. 'C2: 000px' (seulement en mode «Rafale») est la longueur du cycle primaire pour une seconde courbe. 'Trigo' rappelle que le premier cycle court toujours dans le sens trigonométrique. '+000°' permet de réorienter la courbe (de 0 à 360°). *Cycles secondaire et tertiaire 'C1: 000px' affiche la longueur du rayon du cycle secondaire ou tertiaire (de 0 à 120px), modifiable par l'ascenseur horizontal situé à droite. 'C2: 000px' (seulement en mode «Rafale») idem pour une deuxième courbe. '000sp' afffiche le nombre de spires du cycle secondaire ou tertiaire, modifiable par l'ascenseur à droite (de 0 à 100). [Trigo] définit le sens du cycle secondaire ou tertiaire: noir sur fond blanc pour le sens trigonométrique, noir sur fond gris pour le sens horaire. '+000°' permet de déphaser les cycles secondaire ou tertiaire (de 0 à 360°). *Généralités [ ] appelle la boîte de sélection des couleurs pour définir la couleur de fond de l'image. [1] appelle la boîte de sélection des couleurs pour définir la couleur de la première courbe. [<>] (en mode «rafale» seulement) permet d'intervertir les couleurs de la première et seconde courbe. [2] (en mode «rafale» seulement) appelle la boîte de sélection des couleurs pour définir la couleur de la seconde courbe. [g] définit l'épaisseur de la courbe: noir sur fond blanc pour deux pixels, noir sur fond gris pour un simple pixel. 'd: 4 ^' permet de définir la densité de la courbe, de 1 à 16 milliers de points pour la révolution complète d'une courbe (4 milliers par défaut). *Répétitions 'x 1 ^' permet de répéter le graphique: pour n répétitions, la courbe est répétée tous les (360/n)°. [Rafale] permet de passer en mode «rafale», à savoir plusieurs courbes de la première à la seconde (comprise), définies selon les rayons '1' et '2' et les couleurs associées. Les courbes intermédiaires sont colorées selon le gradient de couleur. '05' (mode «rafale» seulement) est le nombre de courbes (de 2 à 60) définissable par l'ascenseur à droite. *Action [Nouveau] efface et dessine un graphique complet selon les paramètres définis. [Ajout] dessine un graphique au dessus d'un autre existant déjà. Attention: dans ce cas, une nouvelle couleur de fond ne sera pas prise en compte. [Hasard] dessine un graphique selon des paramètres redéfinis au hasard.""" manual[".nl"]="""aan het traduceren... *??? Op dezelfde manier dat de aarde draait om de zon, de maan rond de aarde en Lunik 10 rond de maan van de 3rde van april tot de 30ste van mei 1966 en misschien later, dit programma tekent de curve bepaald door een samenstelling van drie cycli???. *Hoger buttons [Exit] verlaat. [Charg.] (weldra) load parameters van een ouder bild. [Sauv.] sauvegarde le graphique réalisé par l'application, au format PNM: «P5» pour les dessins en N/B ou gris, ou «P6» pour les dessins en couleurs. Pour les systèmes UNIX munis de ImageMagick, le fichier au format PNM est transformé en PNG, économique et sans perte de qualité. Les données sont écrites dans le nom du fichier, ce qui permet à l'application de se remémorer les paramètres en chargeant le fichier. *Inlinchtingen '00008 kilopt' donne le nombre de milliers de points que les boutons [Dessin] ou [Ajout] vont dessiner. Sur un amd64 à 1.7GHz, cela prend environ 20000 pt par seconde. [.fr], [.en], [.es] et [.nl] affichent la documentation en une de ces quatres langues. [version] fournit les diverses étapes de l'écriture de l'application, le todo et les bugs connus. *Cycle primaire 'C1: 000px' est la longueur du cycle primaire, il est déduit de la longueur des cycles secondaire et tertiaire, la somme des trois cycles valant 250px. 'C2: 000px' (seulement en mode «Rafale») est la longueur du cycle primaire pour une seconde courbe. 'Trigo' rappelle que le premier cycle court toujours dans le sens trigonométrique. '+000°' permet de réorienter la courbe (de 0 à 360°). *Cycles secondaire et tertiaire 'C1: 000px' affiche la longueur du rayon du cycle secondaire ou tertiaire (de 0 à 120px), modifiable par l'ascenseur horizontal situé à droite. 'C2: 000px' (seulement en mode «Rafale») idem pour une deuxième courbe. '000sp' afffiche le nombre de spires du cycle secondaire ou tertiaire, modifiable par l'ascenseur à droite (de 0 à 100). [Trigo] définit le sens du cycle secondaire ou tertiaire: noir sur fond blanc pour le sens trigonométrique, noir sur fond gris pour le sens horaire. '+000°' permet de déphaser les cycles secondaire ou tertiaire (de 0 à 360°). *Généralités [ ] appelle la boîte de sélection des couleurs pour définir la couleur de fond de l'image. [1] appelle la boîte de sélection des couleurs pour définir la couleur de la première courbe. [<>] (en mode «rafale» seulement) permet d'intervertir les couleurs de la première et seconde courbe. [2] (en mode «rafale» seulement) appelle la boîte de sélection des couleurs pour définir la couleur de la seconde courbe. [g] définit l'épaisseur de la courbe: noir sur fond blanc pour deux pixels, noir sur fond gris pour un simple pixel. 'd: 4 ^' permet de définir la densité de la courbe, de 1 à 16 milliers de points pour la révolution complète d'une courbe (4 milliers par défaut). *Répétitions 'x 1 ^' permet de répéter le graphique: pour n répétitions, la courbe est répétée tous les (360/n)°. [Rafale] permet de passer en mode «rafale», à savoir plusieurs courbes de la première à la seconde (comprise), définies selon les rayons '1' et '2' et les couleurs associées. Les courbes intermédiaires sont colorées selon le gradient de couleur. '05' (mode «rafale» seulement) est le nombre de courbes (de 2 à 60) définissable par l'ascenseur à droite. *Action [Nouveau] efface et dessine un graphique complet selon les paramètres définis. [Ajout] dessine un graphique au dessus d'un autre existant déjà. Attention: dans ce cas, une nouvelle couleur de fond ne sera pas prise en compte. [Hasard] dessine un graphique selon des paramètres redéfinis au hasard.""" def display(): global title000, manual, lang, text000 textlist=text000.split("\n") star=[] # title lines longueur=len(textlist) for i in range(longueur): if textlist[i][0]=="*": star+=[i+1] # title lines textlist[i]=textlist[i][1:] # removing the initial star text000="\n".join(textlist) canvas70.delete(title70) window0=Toplevel(root0) window0.geometry("500x612") window0.title(title000) lift0=Scrollbar(window0) lift0.pack(side=RIGHT, fill=Y) helptext0=Text(window0, yscrollcommand=lift0.set, wrap=WORD) helptext0.tag_config(text000, lmargin2=10) helptext0.insert(END, text000) helptext0.config(state=DISABLED) helptext0.pack(side=LEFT, fill=BOTH) lift0.config(command=helptext0.yview) # formatting any line (except the first) if star: # a title must exist for i in range(star[0]-1): # all lines before the first title helptext0.tag_add("pedigree", str(i+1)+".0", str(i+1)+".100") for i in range(star[0],longueur): # any line after first title: helptext0.tag_add("doc", str(i+1)+".0", str(i+1)+".1000") if "<" in textlist[i]: lieu=textlist[i].find("<", 1, 10) helptext0.tag_add("sub", str(i+1)+"."+str(lieu), str(i+1)+"."+str(lieu+1)) if ">" in textlist[i]: lieu=textlist[i].find(">", 1, 10) helptext0.tag_add("sup", str(i+1)+"."+str(lieu), str(i+1)+"."+str(lieu+1)) if "'" in textlist[i] and textlist[i][0]=="'": lieu=textlist[i].find("'", 1, 20) helptext0.tag_add("quote", str(i+1)+".0", str(i+1)+"."+str(lieu+1)) if "[" in textlist[i] and textlist[i][0]=="[": lieu=textlist[i].find("]", 1, 20) helptext0.tag_add("quote", str(i+1)+".0", str(i+1)+"."+str(lieu+1)) helptext0.tag_config("pedigree", font="sans 10", justify=CENTER) helptext0.tag_config("doc", font="sans 12", lmargin1=10, lmargin2=10, rmargin=10, spacing3=5) helptext0.tag_config("quote", font="sans 11 bold") helptext0.tag_config("sub", font="sans 8", offset=-2) helptext0.tag_config("sup", font="sans 8", offset=5) for i in star: # title processor helptext0.tag_add("title", str(i)+".0",str(i)+".100") helptext0.tag_config("title", font="sans 14 italic", foreground="#125634", lmargin1=20, spacing1=3, spacing3=5) def help(dummy): global manual, text000, title000 lang=r_option022.get() text000=manual[lang] title000=title[lang] display() def version(): global text000, manual, title000 text000=manual["ver"] title000=title["ver"] display() def decale1(vide): # ???each 2ry cycle dephasing number change dec1=r_scale122.get() text121.config(text="+%03d°" %(dec1)) def repx(dummy): # after any radius change: setting R1 r2=r_scale212.get() r3=r_scale312.get() r1=250-r2-r3 text111.config(text="C1: %03dpx - " %(r1)) text211.config(text="C1: %03dpx" %(r2)) text311.config(text="C1: %03dpx" %(r3)) def rrepx(dummy): # after any radius change: setting R1 rr2=r_scale212.get() rr3=r_scale312.get() rr1=250-rr2-rr3 text112.config(text="C2: %03dpx" %(rr1)) text221.config(text="C2: %03dpx" %(rr2)) text321.config(text="C2: %03dpx" %(rr3)) def resp2(vide): # each 2ry cycle loop number change s2=r_scale232.get() text231.config(text="%03dsp" %(s2)) def resp3(vide): # each 3ry cycle loop number change s3=r_scale332.get() text331.config(text="%03dsp" %(s3)) def decale2(vide): # each 2ry cycle dephasing number change dec2=r_scale242.get() text241.config(text="+%03d°" %(dec2)) def decale3(vide): # each 3ry cycle dephasing number change dec3=r_scale342.get() text341.config(text="+%03d°" %(dec3)) def iter222(vide): it24=r_scale222.get() text221.config(text="C2: %03dpx" %(it24)) rr1=250-scale222.get()-scale322.get() text112.config(text="C2: %03dpx" %(rr1)) def iter322(vide): it322=r_scale322.get() text321.config(text="C2: %03dpx" %(it322)) rr1=250-scale222.get()-scale322.get() text112.config(text="C2: %03dpx" %(rr1)) def kilopt(): bold=r_bold415.get()+1 raf=1 # if r_option513.get()==1: try: # not sure r_scale515 already set raf=r_scale515.get() except: pass density=4 try: density=int(r_spin417.get()) except: pass portion=1 try: portion=r_portion512.get() except: pass text021.config(text="%05d kilopt" %(bold*density*portion*raf)) def rafale(): global back6, fore6, fore6bis if r_option513.get() ==1: button413.config(state =ACTIVE) # foreground colours swapping button button414.config(state =ACTIVE, bg =back6, fg =fore6bis, relief =RAISED) # secund curve colour button text221.config(state =ACTIVE) # second rayon length slider text321.config(state =ACTIVE) # third rayon length slider text514.config(state =ACTIVE) # rafale slider text112.config(state =ACTIVE) r2 =r_scale212.get(); rr2 =r_scale222.get() if rr2 ==0: rr2 =10 +random.randrange(100) text221.config(text ="C2: %03dpx" %(rr2)) r_scale222.set(rr2); iter222(0) scale222.config(state =ACTIVE, sliderrelief =RAISED, troughcolor =fore6bis) r3 =r_scale312.get(); rr3 =r_scale322.get() if rr3 ==0: rr3 =10 +random.randrange(100) text321.config(text="C2: %03dpx" %(rr3)) r_scale322.set(rr3); iter322(0) scale322.config(state =ACTIVE, sliderrelief =RAISED, troughcolor =fore6bis) scale515.config(state =ACTIVE, sliderrelief =RAISED) else: button413.config(state =DISABLED) # foreground colours swapping button button414.config(state =DISABLED, relief =FLAT) # secund foreground button text221.config(state =DISABLED) text321.config(state =DISABLED) text514.config(state =DISABLED) scale222.config(state =DISABLED, sliderrelief =SUNKEN, relief =FLAT, troughcolor ="#d3d7cf") scale322.config(state =DISABLED, sliderrelief =SUNKEN, relief =FLAT, troughcolor ="#d3d7cf") scale515.config(state =DISABLED, sliderrelief =SUNKEN, relief =FLAT, troughcolor ="#d3d7cf") text112.config(state =DISABLED) kilopt() def iteration(vide): kilopt() it53=r_scale515.get() text514.config(text ="%02d" %(it53)) def tosave(): button003.config(state =ACTIVE) # now something to save def triple(colour): return int(colour[1:3], 16), int(colour[3:5], 16), int(colour[5:7], 16) def tracer(): global back6, fore6, fore6bis, couleur, nouveau, colorbox, matrice back0 =back6 lang =r_option022.get() # from listbox (.fr, .en, .sp, .nl) if nouveau ==False and back0 !=back0: showinfo(colorbox[lang][0], colorbox[lang][1]) back6 =back0; bgset() nouveau =False # trigonometrical loops must regain the main one (+1), clockwise must loose one # so, +1 if trigonometrical course, -1 if clockwise t2 =r_sens233.get()*2-1 # =+1 for counterclockwise (trigonometrical course) t3 =r_sens333.get()*2-1 # =-1 for clockwise dec1 =r_scale122.get(); dec2 =r_scale242.get(); dec3 =r_scale342.get() s2 =r_scale232.get(); s3=r_scale332.get() # loop number sp2 =s2 +t2; sp3= s3 +t3 # correction dec1 =r_scale122.get(); dec2 =r_scale242.get(); dec3 =r_scale342.get() sdec1 =dec1 *pi /180 # dephasing for the main loop sdec2 =sdec1 +dec2 *pi /180 # cumulated dephasing for the secund loop sdec3 =sdec2 +dec3 *pi /180 # cumulated dephasing for the third loop c=256 # graphic is 512*512 pixel: center is +/- (256,256). bold =r_bold415.get() # is bold set? m =1; nb =1; nbb =nb if couleur: m =3 # one byte per pixel, 3 if colour is set if r_option513.get(): nb =r_scale515.get() # burst mode repetition number if nb >1: nbb =nb-1 # r2 =r_scale212.get(); r3 =r_scale312.get() rt2 =r_scale222.get(); rt3 =r_scale322.get() rr2 =(r2-rt2)/nbb; rr3 =(r3 -rt3) /nbb fore =triple(fore6); forebis =triple(fore6bis) foredelta0 =(fore[0] -forebis[0]) /nbb foredelta1 =(fore[1] -forebis[1]) /nbb foredelta2 =(fore[2] -forebis[2]) /nbb density =int(r_spin417.get()) *1000 # dot number per curve halfdensity =density/2 mm =r_portion512.get() for k in range(mm): # multi level: repetition every 360°/n mult =pi *2 *k /mm # computing each dephasing eg. from 0 to 360° *6 /7 for n in range(nb) : # burst level: computing step for colours and radius rstep2 =r2 -rr2 *n rstep3 =r3 -rr3 *n rstep1 =250 -rstep2 -rstep3 forestep0 =int(round(fore[0] -foredelta0 *n)) forestep1 =int(round(fore[1] -foredelta1 *n)) forestep2 =int(round(fore[2] -foredelta2 *n)) couleurs =["#%02x%02x%02x" %(forestep0, forestep1, forestep2)] fst0 =chr(forestep0); fst1 =chr(forestep1); fst2 =chr(forestep2) for i in range(density): angle =i *pi /halfdensity # avoids i*pi*2/density ang1 =mult +angle +sdec1 # multi dephasing + angle + curve dephasing ang2 =mult +angle *sp2 *t2+sdec2 ang3 =mult +angle *sp3 *t3+sdec3 x=int(round(cos(ang1)*rstep1+cos(ang2)*rstep2+cos(ang3)*rstep3)) y=int(round(sin(ang1)*rstep1+sin(ang2)*rstep2+sin(ang3)*rstep3)) # rationalizing is rather useless yy =c -y; xx =c +x # '-y': first ligne at the top! dot =(yy *512 +xx) *m # dot offset in the matrix ; m is 1 (b/w) or 3 (colour) dotplus =dot +512 *m # one line farther for bold line matrice[dot] =fst0 # if couleur: matrice[dot +1] =fst1 matrice[dot +2] =fst2 if bold ==0: # single line canvas70.create_line(xx, yy, xx, yy +1, fill =couleurs) pass else: # thick line xx1=xx+1; yy2=yy+2 canvas70.create_line(xx,yy, xx,yy2, fill=couleurs) canvas70.create_line(xx1,yy, xx1,yy2, fill=couleurs) matrice[dot+m]=fst0 matrice[dotplus]=fst0 matrice[dotplus+m]=fst0 if couleur: matrice[dot+m+1]=fst1 matrice[dotplus+1]=fst1 matrice[dotplus+m+1]=fst1 matrice[dot+m+2]=fst2 matrice[dotplus+2]=fst2 matrice[dotplus+m+2]=fst2 canvas70.create_line(xx,yy, xx,yy+1, fill=couleurs) tosave() def matrix(): # matrix cleaning and background global matrice, back6, fore6, fore6bis, couleur matrice =[] fore =triple(fore6); back=triple(back6); forebis=triple(fore6bis) if fore[0] ==fore[1] ==fore[2] and back[0] ==back[1] ==back[2] and forebis[0] ==forebis[1] ==forebis[2]: couleur=0 back1 =chr(back[0]) for i in range(512*512): matrice +=[back1] else: couleur=1 back1 =chr(back[0]); back2 =chr(back[1]); back3 =chr(back[2]); for i in range(512 *512): matrice +=[back1, back2, back3] def draw(): global back6, nouveau matrix() canvas70.create_rectangle(1,1,512,512, fill =back6) nouveau =True button612.config(state =ACTIVE) tracer() def save(): global back6, fore6, fore6bis ts=time.time() qu=r_portion512.get() deph1=r_scale122.get(); deph2=r_scale242.get(); deph3=r_scale342.get() g=r_bold415.get() gras=["n", "g"] r2=r_scale212.get() r3=r_scale312.get() t2=r_sens233.get() t3=r_sens333.get() s2=r_scale232.get() s3=r_scale332.get() st2="h"; st3="h"; if t2==1: st2="t"; if t3==1: st3="t" s2=r_scale232.get() s3=r_scale332.get() if couleur==0: # header PNM gray or colour-file, binary-data pp="P5" else: pp="P6" rawete="" if r_option513.get(): # only if burst mode: number of curve, new radius and colour raf=r_scale515.get() rr2=r_scale222.get() rr3=r_scale322.get() rawete="-%02d-%03d%03d-%s" %(raf, rr2, rr3, fore6bis[1:]) nom="boucles098-%02d%s%03d-%03d%s%03d-%03d%s%03d-%s-%03d%03d-%s" %(qu, gras[g], deph1, s2, st2, deph2, s3, st3, deph3, back6[1:], r2, r3, fore6[1:]) + rawete entete="%s\n# Boucles 0.98 www.jchr.be\n%s %s 255 " %(pp,512,512) fichier=entete+"".join(matrice)+" " han=open(nom+".pnm","w") han.write(fichier) han.close() try: os.system("convert "+nom+".pnm "+nom+".png") os.remove(nom+".pnm") except: print(""" On GNU/Linux system with Imagemagick, PNM5 or PNM6 are converted to PNG! """) button003.config(state=DISABLED) # nothing else to save def charger(): global back6, fore6, fore6bis assoc=[("Images «boucles»", "boucles*.*")] fichier=askopenfilename(filetypes=assoc) fichier=fichier.rsplit(".",1)[0] elements=fichier.split("-")[1:] nbrel=len(elements) if nbrel==6 or nbrel==9: el0=elements[0] portions=int(el0[0:2]) # angular reiteration r_portion512.set(portions) bold=el0[2] # bold lines graphic? if bold=="n": r_bold415.set(0) if bold=="g": r_bold415.set(1) deph1=int(el0[3:]) # R1 dephasing (globale orientation) r_scale122.set(deph1); scale122.config(); text121.config(text="+%03d°" %(deph1)) el1=elements[1] s2=int(el1[0:3]) # secund loop number r_scale232.set(s2); scale232.config(); text231.config(text="+%03sp°" %(s2)) text231.config(text="%03dsp" %(s2)) st2=el1[3] # trigonometrical or clockwise sense if st2=="t": r_sens233.set(1) if st2=="h": r_sens233.set(0) deph2=int(el1[4:]) # R2 dephasing r_scale242.set(deph2); scale242.config(); text241.config(text="+%03d°" %(deph2)) el2=elements[2] s3=int(el2[0:3]) # third loop number text331.config(text="%03dsp" %(s3)) r_scale332.set(s3); scale332.config() st3=el2[3] # trigonometrical sense if st3=="t": r_sens333.set(1) if st3=="h": r_sens333.set(0) deph3=int(el2[4:]) # R3 dephasing r_scale342.set(deph3); scale342.config(); text341.config(text="+%03d°" %(deph3)) back6="#"+elements[3] el4=elements[4] r2=int(el4[0:3]) # secund rayon length r_scale212.set(r2) r3=int(el4[3:]) # third rayon length r_scale312.set(r3) #text111.configure(text="C1: %03dpx -" %(r1)) repx(0) fore6="#"+elements[5] button412.config(bg=back6, fg=fore6) bgset() if nbrel==6: r_option513.set(0) rafale() if nbrel==9: raf=int(elements[6]) r_option513.set(1) text514.config(state=ACTIVE, text="%02d" %(raf)) r_scale515.set(raf); scale515.config(state=ACTIVE) el7=elements[7] rr2=int(el7[0:3]); rr3=int(el7[3:]); rr1=250-rr2-rr3 text112.config(state=ACTIVE, text="C2: %03dpx" %(rr1)) text221.config(state=ACTIVE, text="C2: %03dpx" %(rr2)) r_scale222.set(rr2); scale222.config(state=ACTIVE) text321.config(state=ACTIVE, text="C2: %03dpx" %(rr3)) r_scale322.set(rr3); scale322.config(state=ACTIVE) fore6bis="#"+elements[8] button413.config(state=ACTIVE) # activating colour swapping button button414.config(state=ACTIVE, bg=back6, fg=fore6bis) # secund colour button rafale() if nbrel not in [6,9]: print("Nom de fichier image mal formé") kilopt() def randcol(): return "#%02x%02x%02x" %(random.randrange(256), random.randrange(256), random.randrange(256)) def hasard(): # randomised curve (french 'hasard' is english 'random') global fore6, back6, fore6bis # matrice r2 =10 +random.randrange(90); r_scale212.set(r2) r3 =10 +random.randrange(90); r_scale312.set(r3) r1 =250 -r2 -r3 # since r1 +r2 +r3 =250 s2=random.randrange(16) # from 1 to 15 s3=random.randrange(16) r_scale232.set(s2) r_scale332.set(s3) back6=randcol() # random background colour button411.config(bg=back6) fore6=randcol() # random first curve colour button412.config(fg=fore6, bg=back6) tt2=random.randrange(2); r_sens233.set(tt2) # 1= ccw (trigo), 0=cw tt3=random.randrange(2); r_sens333.set(tt3) scale212.config(troughcolor=fore6) scale312.config(troughcolor=fore6) if r_option513.get(): # burst mode is on: fore6bis=randcol() # random first curve colour button414.config(fg=fore6bis, bg=back6) rr2=10+random.randrange(110); r_scale222.set(rr2) rr3=10+random.randrange(110); r_scale322.set(rr3) scale222.config(troughcolor=fore6bis) # \ secund curve secund scale322.config(troughcolor=fore6bis) # / and third rayon scale repx(43); rrepx(43); resp2(43); resp3(43) # onto the dashboard draw() def curve(): global back6, fore6 fore0 =fore6 dummy, fore6 =askcolor(initialcolor=fore6, title ="Choisir la couleur du trait") if fore6 ==None : # if something wrong happened fore6 =fore0 # we have to give back the former colour button412.config(fg =fore6, bg =back6) scale212.config(troughcolor =fore6) scale312.config(troughcolor =fore6) def curvebis(): global back6, fore6bis fore0bis =fore6bis dummy, fore6bis =askcolor(initialcolor =fore6bis, title ="Choisir la seconde couleur du trait (mode «rafale»)") if fore6bis==None: # if something wrong happened fore6bis=fore0bis # we have to give back the former colour # coloring the second foreground button: button414.config(fg=fore6bis, bg=back6) scale222.config(troughcolor=fore6bis) scale322.config(troughcolor=fore6bis) def swap(): # swapping foreground colours global fore6, fore6bis fore6bis, fore6 =fore6, fore6bis scale212.config(troughcolor =fore6) scale312.config(troughcolor =fore6) scale222.config(troughcolor =fore6bis) scale322.config(troughcolor =fore6bis) button412.config(fg =fore6) button414.config(fg =fore6bis) def bgset() : # colouring the color buttons backgrounds global back6 button411.config(bg =back6) # background button background button412.config(bg =back6) # last curve button background if r_option513.get() ==1: # only if burst mode : button414.config(bg =back6) # last curve button background def bgchoose(): global back6 back0 =back6 dummy, back6 =askcolor(initialcolor=back6, title="Choisir la couleur de fond") if back6 ==None: # if something wrong occurs: back, back6 =back0, back06 # gives back the former colour bgset() inter=""" #define au_width 14 #define au_height 14 static unsigned char au_bits[] = { 0x00, 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x20, 0x0f, 0x30, 0x07, 0x38, 0x03, 0x3c, 0x01, 0x3e, 0x00, 0x3c, 0x00, 0x38, 0x00, 0x30, 0x00, 0x20, 0x00 }; """ # T K I N T E R M A I N L O O P root0=Tk() root0.geometry("714x555") # (formerly 714x512) root0.title("Boucles et autres spires...") frame0=Frame(root0) frame00=Frame(frame0) # framelet 1: leaving and saving button001=Button(frame00, text="Exit", font="sans 11", bg="#b05", fg="#ffffff",command=root0.quit) button001.pack(side=LEFT) # leaving the application: should ask for saving button002=Button(frame00, text="Charg.", font="sans 11", fg="white", bg="black", command=charger) button002.pack(side=LEFT) # loading a coded name picture button003=Button(frame00, text="Sauv.", font="sans 11", state=DISABLED, command=save) button003.pack(side=LEFT) # nothing yet to save frame00.pack() canvas01=Canvas(frame0, width=200, height=24, bg='darkgray') title01=canvas01.create_text(100, 12, text="Informations", font="sans 16 italic", fill="#125634") canvas01.pack(side=TOP) frame02=Frame(frame0) # framelet 2 text021=Label(frame02, text="00004 kilopt") text021.pack(side=LEFT) r_option022=StringVar(); r_option022.set(".fr") option022=OptionMenu(frame02, r_option022, ".fr", ".en", ".es", ".nl", command=help) option022.pack(side=LEFT) button025=Button(frame02,text="version", width=4, font="sans 10", command=version) button025.pack(side=RIGHT) # licence, versions, todo and bugs frame02.pack() canvas11=Canvas(frame0, width=200, height=24, bg='darkgray') title11=canvas11.create_text(100, 12, text="Cycle primaire", font="sans 14 italic", fill="#125634") canvas11.pack(side=TOP) # primary cycle title frame11=Frame(frame0) # primary cycle radius length text111=Label(frame11, text="C1: %03dpx - " %(r1)) text111.pack(side=LEFT) text112=Label(frame11, text="C2: 000px", state=DISABLED) text112.pack(side=LEFT) text113=Label(frame11, text=" - Trigo") text113.pack(side=LEFT) frame11.pack() # pixel number for radius 1, depending on r2 and r3 frame12=Frame(frame0) # framelet 4: primary cycle dephasing scale text121=Label(frame12, text="+000°") text121.pack(side=LEFT) r_scale122=IntVar(); r_scale122.set(0) scale122=Scale(frame12, variable=r_scale122, to=360, length=148, width=10, orient=HORIZONTAL, showvalue=0, troughcolor="#ffffff", sliderlength=20, command=decale1) scale122.pack(side=LEFT) # first cycle dephasing, so: graphic orientation frame12.pack() # S E C O N D A R Y C Y C L E canvas20=Canvas(frame0, width=200, height=24, bg='darkgray') title20=canvas20.create_text(100, 12, text="Cycle secondaire", font="sans 14 italic", fill="#125634") canvas20.pack(side=TOP) frame21=Frame(frame0) # 2 N D C Y C L E: first radius length (slider) text211=Label(frame21, text="C1: %03dpx" %(r2)) text211.pack(side=LEFT) r_scale212=IntVar(); r_scale212.set(r2) scale212=Scale(frame21, variable=r_scale212, to=125, length=128, width=10, orient=HORIZONTAL, showvalue=0, troughcolor=fore6, sliderlength=20, command=repx) scale212.pack(side=LEFT) frame21.pack() frame22=Frame(frame0) # 2 N D C Y C L E: secund radius length text221=Label(frame22, text="C2: 000px", state=DISABLED) text221.pack(side=LEFT) r_scale222=IntVar(); r_scale222.set(0) scale222=Scale(frame22, variable=r_scale222, from_=0, to=125, length=128, orient=HORIZONTAL, showvalue=0, state=DISABLED, width=10, sliderlength=20, sliderrelief=SUNKEN, relief=FLAT, troughcolor="#d3d7cf", command=iter222) scale222.pack(side=LEFT) frame22.pack() frame23=Frame(frame0) text231=Label(frame23, text="%03dsp" %(s2)) text231.pack(side=LEFT) r_scale232=IntVar(); r_scale232.set(s2) # 2 N D C Y C L E: loop number scale232=Scale(frame23, variable=r_scale232, to=100, length=110, width=10, orient=HORIZONTAL, showvalue=0, troughcolor=rainure, sliderlength=20, command=resp2) scale232.pack(side=LEFT) r_sens233=IntVar(); r_sens233.set(t2) button233=Checkbutton(frame23, variable=r_sens233, text="Trigo", indicatoron=0, width=4, bg="#555") button233.pack(side=LEFT) frame23.pack() frame24=Frame(frame0) text241=Label(frame24, text="+000°") text241.pack(side=LEFT) r_scale242=IntVar(); r_scale242.set(0) # 2 N D C Y C L E: dephasing scale242=Scale(frame24, variable=r_scale242, to=360, length=148, width=10, orient=HORIZONTAL, showvalue=0, troughcolor="#ffffff", sliderlength=20, command=decale2) scale242.pack(side=LEFT) frame24.pack() # T H I R D C Y C L E canvas30=Canvas(frame0, width=200, height=24, bg='darkgray') title30=canvas30.create_text(100, 12, text="Cycle tertiaire", font="sans 14 italic",fill="#125634") canvas30.pack(side=TOP) frame31=Frame(frame0) # 3 R D C Y C L E: first radius length text311=Label(frame31, text="C1: %03dpx" %(r3)) text311.pack(side=LEFT) r_scale312=IntVar(); r_scale312.set(r3) scale312=Scale(frame31, variable=r_scale312, length=128, to=125, width=10, orient=HORIZONTAL, showvalue=0, troughcolor=fore6, sliderlength=20, command=repx) scale312.pack() frame31.pack() frame32=Frame(frame0) # 3 R D C Y C L E: secund radius length text321=Label(frame32, text="C2: 000px", state=DISABLED) text321.pack(side=LEFT) r_scale322=IntVar(); r_scale322.set(0) scale322=Scale(frame32, variable=r_scale322, from_=0, to=125, length=128, orient=HORIZONTAL, showvalue=0, state=DISABLED, width=10, sliderlength=20, sliderrelief=SUNKEN, relief=FLAT, troughcolor="#d3d7cf", command=iter322) scale322.pack(side=LEFT) frame32.pack() frame33=Frame(frame0) # 3 R D C Y C L E: loop number text331=Label(frame33, text="%03dsp" %(s3)) text331.pack(side=LEFT) r_scale332=IntVar(); r_scale332.set(s3) scale332=Scale(frame33, variable=r_scale332, to=100, length=110, width=10, orient=HORIZONTAL, showvalue=0, troughcolor=rainure, sliderlength=20, command=resp3) scale332.pack(side=LEFT) r_sens333=IntVar(); r_sens333.set(t3) button333=Checkbutton(frame33, variable=r_sens333, text="Trigo", indicatoron=0, width=4, bg="#555") button333.pack(side=LEFT) frame33.pack() frame34=Frame(frame0) # 3 R D C Y C L E: dephasing angle text341=Label(frame34, text="+000°") text341.pack(side=LEFT) r_scale342=IntVar(); r_scale342.set(0) scale342=Scale(frame34, variable=r_scale342, to=360, length=149, width=10, orient=HORIZONTAL, showvalue=0, troughcolor="#ffffff", sliderlength=20, command=decale3) scale342.pack(side=LEFT) frame34.pack() # C O L O U R S, L I N E A N D D E N S I T Y canvas40=Canvas(frame0, width=200, height=24, bg='darkgray') title40=canvas40.create_text(100, 12, text="Généralités", font="sans 14 italic",fill="#125634") canvas40.pack(side=TOP) frame41=Frame(frame0) # background colour setting button button411=Button(frame41,text="", bg=back6, command=bgchoose) button411.pack(side=LEFT) # foreground first curve colour setting button button412=Button(frame41,text="1", width=1, fg=fore6, bg=back6, font="sans 9 bold", command=curve) button412.pack(side=LEFT) fleches=BitmapImage(data=inter) # colours swapping button (burst mode only) button413=Button(frame41, image=fleches, width=0, state=DISABLED, command=swap) button413.pack(side=LEFT) # foreground last curve colour setting button (burst mode only) button414=Button(frame41,text="2", width=1, state=DISABLED, fg=fore6bis, bg=back6, font="sans 9 bold", relief=FLAT, command=curvebis) button414.pack(side=LEFT) r_bold415=IntVar(); r_bold415.set(g) button415=Checkbutton(frame41, variable=r_bold415, text="g", font="sans 14", indicatoron=0, bg="#666", command=kilopt) button415.pack(side=LEFT) text416=Label(frame41, text=" d:", font="sans 12") text416.pack(side=LEFT) r_spin417=IntVar(); r_spin417.set(4) # density: n thousands of dots per curve r_spin417=Spinbox(frame41, textvariable=r_spin417, from_=1, to=16, width=2, font="sans 12", relief=FLAT, command=kilopt) r_spin417.pack(side=LEFT) frame41.pack() # R E P E T I T I O N S (title) canvas50=Canvas(frame0, width=200, height=24, bg='darkgray') title50=canvas50.create_text(100, 12, text="Répétitions", font="sans 14 italic",fill="#125634") canvas50.pack(side=TOP) # R E P E T I T I O N S (parameters) frame51=Frame(frame0) text511=Label(frame51, text=" x", font="sans 12") text511.pack(side=LEFT) r_portion512=IntVar(); r_portion512.set(1) r_spin512=Spinbox(frame51, textvariable=r_portion512, from_=1, to=16, width=2, font="sans 12", relief=FLAT, command=kilopt) r_spin512.pack(side=LEFT) r_option513=IntVar(); r_option513.set(0) button513=Checkbutton(frame51, variable=r_option513, text="Rafale", bg="#666", indicatoron=0, command=rafale) button513.pack(side=LEFT) text514=Label(frame51, text="05", state=DISABLED) text514.pack(side=LEFT) r_scale515=IntVar(); r_scale515.set(5) # setting scale return-variable scale515=Scale(frame51, variable=r_scale515, from_=2, to=60, length=75, orient=HORIZONTAL, showvalue=0, state=DISABLED, width=10, sliderlength=20, sliderrelief=SUNKEN, relief=FLAT, troughcolor="#d3d7cf", command=iteration) scale515.pack(side=LEFT) frame51.pack() # A C T I O N S (title) canvas60=Canvas(frame0, width=200, height=24, bg='darkgray') title60=canvas60.create_text(100, 12, text="Action", font="sans 14 italic",fill="#125634", anchor=CENTER) canvas60.pack(side=TOP) # A C T I O N S (buttons) frame61=Frame(frame0) button613=Button(frame61, text="Hasard", width="5", command=hasard, fg="white", bg="black") button613.pack(side=LEFT) button612=Button(frame61, text="Ajout", width="4", state=DISABLED, command=tracer) button612.pack(side=LEFT) button611=Button(frame61, text="Nouveau", width="5", fg="white", bg="black", command=draw) button611.pack(side=RIGHT) frame61.pack() frame0.pack(side=LEFT) # left column completed canvas70=Canvas(root0, width=512, height=512, bg='white') title70=canvas70.create_text(256, 256, text=""" Click on [.en] for english Cliquee en [.es] para el castillano Klik op [.nl] voor he nederlands """, font="sans 14",fill="#125634") canvas70.pack(side=RIGHT) # setting square for drawing surface root0.mainloop()