Dorian Fevrier's blog - Mot-clé - tkinterJe m’appelle FEVRIER Dorian, je suis infographiste 3D passionné par mon métier, l’informatique en général, l’internet, la programmation et l’évolution de tout ce petit monde. Vous trouverez sur ce blog des tutoriaux, mes coups de cœurs, avis, etc.2024-01-02T23:48:05+01:00FEVRIER Dorianurn:md5:695d9c73474c33ce3dab043823509c4bDotclearTkinter: Faire communiquer les variables de l'interfaceurn:md5:63aa6ec3946a173d21138e81febfcbea2009-03-15T23:04:00+01:002013-07-26T22:41:25+02:00NarannScript et codecppdéveloppementfrinterface graphiquepythonscripttkinter<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter009.png" alt="debutTkinter009.png" style="float:left; margin: 0 1em 1em 0;" title="debutTkinter009.png, mar. 2009" height="92" width="192" />Quand on fait une interface, on est souvent amené à récupérer le contenu des informations qui sont dans la dite interface (Est ce que la checkbox est activé? Qui y a t'il dans le widget Entry? etc...). Je vous propose de voir rapidement comment faire interagir des éléments d'une interface tkinter avec différentes variables. Nous allons voir qu'on passe par un objet qui est en fait... Une variable, ou plus précisément, la classe variable. :hehe: Nous aborderons brièvement le resizing des fenêtres dans la dernière partie.</p> <h5>Ze "minimal code" <a name="Ze_minimal_code"></a></h5>
<p>Avant de commencer il faut un code minimum. Le voici:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> tkinter <span style="color: #ff7700;font-weight:bold;">as</span> tk
<span style="color: #ff7700;font-weight:bold;">class</span> tkinterTuto<span style="color: black;">(</span>tk.<span style="color: black;">Frame</span><span style="color: black;">)</span>:
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
tk.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ ==<span style="color: #483d8b;">'__main__'</span>:
tkinterTuto<span style="color: black;">(</span><span style="color: black;">)</span>.<span style="color: black;">mainloop</span><span style="color: black;">(</span><span style="color: black;">)</span></pre>
<p>L'initialisation de tkinter est subtile et ce serait vous mentir si je vous disais que je sais exactement ce que fait Python avec ce code. Je vais tout de même vous expliquer du mieux que je peut chacune des lignes de ce code minimum.</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> tkinter <span style="color: #ff7700;font-weight:bold;">as</span> tk</pre>
<p>Ici, pas de soucis, c'est la ligne qui import le module tkinter. "as tk" est un moyen d'abréger le code. Au lieu de taper "tkinter" devant chaque fonction du module, nous pourront abréger par "tk".</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">class</span> tkinterTuto<span style="color: black;">(</span>tk.<span style="color: black;">Frame</span><span style="color: black;">)</span>:</pre>
<p>C'est la déclaration de la classe principale qui va contenir l'interface. Pour le "tk.Frame" il semblerait que ce soit obligatoire et que ça fasse partie du fonctionnement de tkinter. Il s'agit surement du frame principale qui va contenir tout les autres.</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:</pre>
<p>Cette procédure (<strong>init</strong>()) est la procédure qui sera exécuté en premier, à l'initialisation de la classe (C'est le "constructeur").</p>
<pre class="python python">tk.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span></pre>
<p><img src="http://www.fevrierdorian.com/blog/themes/blueSilenceCustom/smilies/parkingBouley.gif" alt="" style="float:right; margin: 0 0 1em 1em;" />
Alors celle la je pige rien! Je suppose qu'il initialise la frame principal. Mais je comprends pas car il reçois déjà une frame à la création de la classe. Bref, si quelqu'un est capable de m'expliquer exactement pourquoi, au final, il semble que nous ayons deux frames (celle en argument puis celle là) je suis preneurs! :seSentCon:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">if</span> __name__ ==<span style="color: #483d8b;">'__main__'</span>:
tkinterTuto<span style="color: black;">(</span><span style="color: black;">)</span>.<span style="color: black;">mainloop</span><span style="color: black;">(</span><span style="color: black;">)</span></pre>
<p>Ces deux lignes permettent de vérifier qu'on a lancer ce fichier (et non pas importé par exemple), et "exécute" la classe.</p>
<p>Nous avons donc le programme minimum:</p>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter001.png" alt="debutTkinter001.png" style="display:block; margin:0 auto;" title="debutTkinter001.png, mar. 2009" height="227" width="208" /></p>
<h5>Part en thèse <a name="Part_en_these"></a></h5>
<p>J'ajoute aussi des lignes qui permettent d'aligner la taille des widgets en fonction de la taille de la fenêtres. L'ajout de ses lignes n'est pas indispensable pour finir la première partie du tutorial mais elles le seront ensuite, lors ce que nous parlerons du "resizing". Vous pouvez essayer de faire sans si vous n'êtes intéressé par la seconde partie.</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">class</span> tkinterTuto<span style="color: black;">(</span>tk.<span style="color: black;">Frame</span><span style="color: black;">)</span>:
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
tk.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">master</span>.<span style="color: black;">columnconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">master</span>.<span style="color: black;">rowconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">columnconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">rowconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">grid</span><span style="color: black;">(</span>sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span></pre>
<p>Quelques mots quand même: "columnconfigure" et "rowconfigure" permettent de configurer respectivement les "rows" (lignes) et les "columns" (collones). Le premier chiffre est l'index et le second, sont "poids". (Pour l'instant, ses lignes n'ont pas d'effet).
La dernière ligne indique à quoi le widget en question (ici, la fenêtre principale) va "s'accrocher". NSEW indique: Nord-Sud-Est-West. Vous indiquez donc les "poles" que vous voulez connecter au bordures (Vous n'êtes pas obligé de toute les mettre). Vous avez plusieurs façon de l'écrire suivant la façon dont est importé le module tkinter:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> tkinter
<span style="color: black;">[</span>...<span style="color: black;">]</span>
<span style="color: #008000;">self</span>.<span style="color: black;">grid</span><span style="color: black;">(</span>sticky=tkinter.<span style="color: black;">N</span>+tkinter.<span style="color: black;">S</span>+tkinter.<span style="color: black;">E</span>+tkinter.<span style="color: black;">W</span><span style="color: black;">)</span></pre>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> tkinter <span style="color: #ff7700;font-weight:bold;">as</span> tk
<span style="color: black;">[</span>...<span style="color: black;">]</span>
<span style="color: #008000;">self</span>.<span style="color: black;">grid</span><span style="color: black;">(</span>sticky=tk.<span style="color: black;">N</span>+tk.<span style="color: black;">S</span>+tk.<span style="color: black;">E</span>+tk.<span style="color: black;">W</span><span style="color: black;">)</span></pre>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> tkinter <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #66cc66;">*</span>
<span style="color: black;">[</span>...<span style="color: black;">]</span>
<span style="color: #008000;">self</span>.<span style="color: black;">grid</span><span style="color: black;">(</span>sticky=N+S+E+W<span style="color: black;">)</span></pre>
<p>Mais la technique qui marche tout le temps est celle que j'ai fait, directement en string.</p>
<p>Bon, après ses explications <del>foirasses</del> approximatives, attaquons nous à la parti intéressante:</p>
<h5>Donner un titre <a name="Donner_un_titre"></a></h5>
<p>C'est le premier truc qui fait qu'on commence à s'approprier un programme (Ok les puristes, je sais qu'on parle de script...). Vous ne pouvez pas deviner la méthode, elle est donné dans la doc (qui, comme <a href="https://www.fevrierdorian.com/blog/index.php?post/2009/03/10/Tkinter%2C-vous-aussi%2C-faites-des-GUI-en-Python...-Ouai%2C-mes-fesses-ouai...#tkinter">je l'ai écrit avant</a>, est un peu moyenne).</p>
<pre class="python python"><span style="color: #008000;">self</span>.<span style="color: black;">master</span>.<span style="color: black;">title</span><span style="color: black;">(</span><span style="color: #483d8b;">"tkinterTuto"</span><span style="color: black;">)</span></pre>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">class</span> tkinterTuto<span style="color: black;">(</span>tk.<span style="color: black;">Frame</span><span style="color: black;">)</span>:
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
tk.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">master</span>.<span style="color: black;">title</span><span style="color: black;">(</span><span style="color: #483d8b;">"tkinterTuto"</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;">#Ça, c'est du nom!</span>
<span style="color: #008000;">self</span>.<span style="color: black;">master</span>.<span style="color: black;">columnconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">master</span>.<span style="color: black;">rowconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">columnconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">rowconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">grid</span><span style="color: black;">(</span>sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span></pre>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter002.png" alt="debutTkinter002.png" style="display:block; margin:0 auto;" title="debutTkinter002.png, mar. 2009" height="227" width="208" /></p>
<h5>La procédure "qui-créé-les-choses"</h5>
<p>Maintenant que nous avons un titre, nous allons créé une seconde procédure (createWidgets) qui va nous servir à créer les éléments de l'interface. Une fois celle ci créer, nous la lançons à partir de la précédure <strong>init</strong>:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">class</span> tkinterTuto<span style="color: black;">(</span>tk.<span style="color: black;">Frame</span><span style="color: black;">)</span>:
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
tk.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>
<span style="color: black;">[</span>...<span style="color: black;">]</span>
<span style="color: #008000;">self</span>.<span style="color: black;">createWidgets</span><span style="color: black;">(</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;">#lance la procédure qui créer les widgets</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createWidgets<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
mainFrame = tk.<span style="color: black;">Frame</span><span style="color: black;">(</span><span style="color: #008000;">self</span>, borderwidth=<span style="color: #ff4500;">2</span>, relief=<span style="color: #483d8b;">"groove"</span><span style="color: black;">)</span>
mainFrame.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span></pre>
<p>Les explication:</p>
<pre class="python python">mainFrame = tk.<span style="color: black;">Frame</span><span style="color: black;">(</span><span style="color: #008000;">self</span>, borderwidth=<span style="color: #ff4500;">2</span>, relief=<span style="color: #483d8b;">"groove"</span><span style="color: black;">)</span></pre>
<p>Créé un Frame, qui a comme parent "self" (le widget principal), qui a deux pixels de bordure et un relief de type groove (Vous pouvez regarder les différents <a href="http://infohost.nmt.edu/tcc/help/pubs/tkinter/relief.html" hreflang="en">types de relief</a>).</p>
<pre class="python python">mainFrame.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span></pre>
<p>cette ligne est importante... En effet, nous avons créer le widget mais ne lui avons donné aucun emplacement... Cette ligne s'en charge. "column" et "row" définisse les index de la grille dans laquelle nous "incrustons" les widgets. "sticky" est, comme tout à l'heure, pour accrocher le widget sur les bords de sa grille.</p>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter003.png" alt="debutTkinter003.png" style="display:block; margin:0 auto;" title="debutTkinter003.png, mar. 2009" height="139" width="155" /></p>
<p>Nous avons un joli petit effet de bordure. Vous pouvez tester, la fenêtre est resizeable (C'est nos petites lignes de tout à l'heure qui font cet effet).</p>
<h5>Dévidons le vide... <a name="Devidons_le_vide"></a></h5>
<p>C'est pas le tout mais notre fenêtre reste bien vide... :hehe:</p>
<p>Nous allons la remplir avec le widget le plus simple (Je crois...), le "Label".</p>
<p>Le "Label" c'est quoi? Et bien c'est tout simplement un texte qui se loge dans l'interface...</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> createWidgets<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
<span style="color: #808080; font-style: italic;">#creation des widgets</span>
mainFrame = tk.<span style="color: black;">Frame</span><span style="color: black;">(</span><span style="color: #008000;">self</span>, borderwidth=<span style="color: #ff4500;">2</span>, relief=<span style="color: #483d8b;">"groove"</span><span style="color: black;">)</span>
valeurOneLabel = tk.<span style="color: black;">Label</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"ValeurOne"</span><span style="color: black;">)</span>
<span style="color: #808080; font-style: italic;">#position des widgets</span>
mainFrame.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span>
valeurOneLabel.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"EW"</span><span style="color: black;">)</span></pre>
<pre class="python python">valeurOneLabel = tk.<span style="color: black;">Label</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"ValeurOne"</span><span style="color: black;">)</span></pre>
<p>Le premier argument est, comme toujours, le parent du widget (mainFrame), pour le second je vous épargne les explications...</p>
<pre class="python python">valeurOneLabel.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"EW"</span><span style="color: black;">)</span></pre>
<p>Comme pour tout à l'heure, nous plaçons le widget dans la grille. Vous aurez remarqué qu'à priori "mainFrame" et "valeurOneLabel" sont placé au même endroit mais si vous regardez leurs parents respectif, vous verrez qu'il n'ont pas les mêmes... Et oui! Chaque frame à sa propre grille.</p>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter004.png" alt="debutTkinter004.png" style="display:block; margin:0 auto;" title="debutTkinter004.png, mar. 2009" height="50" width="112" /></p>
<h5>Toc! Toc!... Entry?<a name="Toc_Toc_Entry"></a></h5>
<p>Nous allons maintenant ajouter notre second widget: Entry!</p>
<p>Entry est un champ de texte dans lequel l'utilisateur peut taper... Du texte... Mais c'est surtout un widget qui utilise la classe variable! :hehe:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> createWidgets<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
<span style="color: #808080; font-style: italic;">#creation des objets variables</span>
<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span> = tk.<span style="color: black;">StringVar</span><span style="color: black;">(</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span>.<span style="color: #008000;">set</span><span style="color: black;">(</span><span style="color: #483d8b;">"Ecrivez ici"</span><span style="color: black;">)</span>
<span style="color: #808080; font-style: italic;">#creation des widgets</span>
mainFrame = tk.<span style="color: black;">Frame</span><span style="color: black;">(</span><span style="color: #008000;">self</span>, borderwidth=<span style="color: #ff4500;">2</span>, relief=<span style="color: #483d8b;">"groove"</span><span style="color: black;">)</span>
valeurOneLabel = tk.<span style="color: black;">Label</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"ValeurOne"</span><span style="color: black;">)</span>
valeurOneEntry = tk.<span style="color: black;">Entry</span><span style="color: black;">(</span>mainFrame, textvariable=<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span><span style="color: black;">)</span>
<span style="color: #808080; font-style: italic;">#position des widgets</span>
mainFrame.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span>
valeurOneLabel.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"EW"</span><span style="color: black;">)</span>
valeurOneEntry.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">1</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"EW"</span><span style="color: black;">)</span></pre>
<p>Les explications:</p>
<pre class="python python"><span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span> = tk.<span style="color: black;">StringVar</span><span style="color: black;">(</span><span style="color: black;">)</span></pre>
<p>La première ligne créé un objet de type StringVar qui va stocker une variable de type... String!</p>
<pre class="python python"><span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span>.<span style="color: #008000;">set</span><span style="color: black;">(</span><span style="color: #483d8b;">"Ecrivez ici"</span><span style="color: black;">)</span></pre>
<p>Cette seconde ligne montre comment nous stockons les informations dans cet objet. Il faut imaginer que nous avons affaire à un objet qui contient une variable et non à une variable "classique". On y stocke avec ".set" et récupère avec ".get".</p>
<pre class="python python">valeurOneEntry = tk.<span style="color: black;">Entry</span><span style="color: black;">(</span>mainFrame, textvariable=<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span><span style="color: black;">)</span></pre>
<p>Vous avez remarquez? Nous avons ajouter l'argument "textvariable" et lui avons donné notre objet-variable. Ainsi quand nous modifierons "valeurOneEntry", nous modifierons directement la variable! Simple non? :sourit:</p>
<p>Vous remarquerez le "self" devant "valeurOneEntry". En si nous ne l'avions pas fait, "valeurOneEntry" aurait été supprimé dès la fin de la procédure "createWidgets". En ajoutant le nom du parent devant une variable (Ici, self renvois au parent de la procédure qui est la classe tout simplement), nous disons à l'interpréteur de créer cette variable au niveau de ce parent (Ainsi, notre variable sera présente dans toute la classe). Cela évite (comme en C par exemple :siffle: ) de devoir initialiser une variable (que l'on souhaite conserver) avant d'entrer dans une procédure.</p>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter005.png" alt="debutTkinter005.png" style="display:block; margin:0 auto;" title="debutTkinter005.png, mar. 2009" height="50" width="192" /></p>
<h5>Les python, ça me donne des boutons... <a name="Les_python_ca_me_donne_des_boutons"></a></h5>
<p>Maintenant nous allons ajouter un bouton qui réagit au clique. C'est toujours le même principe:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> createWidgets<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
<span style="color: #808080; font-style: italic;">#creation des variables</span>
<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span> = tk.<span style="color: black;">StringVar</span><span style="color: black;">(</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span>.<span style="color: #008000;">set</span><span style="color: black;">(</span><span style="color: #483d8b;">"Ecrivez ici"</span><span style="color: black;">)</span>
<span style="color: #808080; font-style: italic;">#creation des widgets</span>
mainFrame = tk.<span style="color: black;">Frame</span><span style="color: black;">(</span><span style="color: #008000;">self</span>, borderwidth=<span style="color: #ff4500;">2</span>, relief=<span style="color: #483d8b;">"groove"</span><span style="color: black;">)</span>
valeurOneLabel = tk.<span style="color: black;">Label</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"ValeurOne"</span><span style="color: black;">)</span>
valeurOneEntry = tk.<span style="color: black;">Entry</span><span style="color: black;">(</span>mainFrame, textvariable=<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span><span style="color: black;">)</span>
button = tk.<span style="color: black;">Button</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"Click Me!"</span><span style="color: black;">)</span>
<span style="color: #808080; font-style: italic;">#position des widgets</span>
mainFrame.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span>
valeurOneLabel.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"EW"</span><span style="color: black;">)</span>
valeurOneEntry.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">1</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"EW"</span><span style="color: black;">)</span>
button.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, columnspan=<span style="color: #ff4500;">2</span>, row=<span style="color: #ff4500;">1</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span></pre>
<p>Explications:</p>
<pre class="python python">button = tk.<span style="color: black;">Button</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"Click Me!"</span><span style="color: black;">)</span></pre>
<p>Notre bouton, son parent est "mainFrame", et son texte est "Click Me!"...</p>
<pre class="python python">button.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, columnspan=<span style="color: #ff4500;">2</span>, row=<span style="color: #ff4500;">1</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span></pre>
<p>Et on le place dans l'interface! Vous remarquerez l'argument "columnspan". Celui ci permet de "manger" un certain nombre de colonne (comme en html pour ceux qui ont eu "la chance" de faire des sites en tableau :aupoil: )</p>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter006.png" alt="debutTkinter006.png" style="display:block; margin:0 auto;" title="debutTkinter006.png, mar. 2009" height="73" width="192" /></p>
<p>On vois que malgré que le bouton soit placé dans la colonne zéro, il utilise deux colonnes.</p>
<p>Hop hop hop! Passons à l'étape suivante! :marioCours:</p>
<h5>Faut que ça réagisse! <a name="Faut_que_ca_reagisse"></a></h5>
<p>Bien! Maintenant que notre interface est prête, nous allons commencer à la faire "réagire"...</p>
<p>Pour cela, il faut lui indiquer quoi executer... En l'occurrence, une procédure. Créons dans un premier temps une procédure toute simple:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> printSomething<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span><span style="color: #483d8b;">"something"</span><span style="color: black;">)</span></pre>
<p>Cette procédure ne fait qu'écrire "something" dans la console...</p>
<p>Il faut maintenant dire au bouton de l'exécuter quand on clique dessus:</p>
<pre class="python python">button = tk.<span style="color: black;">Button</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"Click Me!"</span>, command=<span style="color: #008000;">self</span>.<span style="color: black;">printSomething</span><span style="color: black;">)</span></pre>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter007.png" alt="debutTkinter007.png" style="display:block; margin:0 auto;" title="debutTkinter007.png, mar. 2009" height="91" width="301" /></p>
<p>L'objectif maintenant est de pouvoir récupérer, dans notre procédure "printSomething" le contenu de la variable, rien de plus simple! Ça s fait grace au .get:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> printSomething<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span><span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span>.<span style="color: black;">get</span><span style="color: black;">(</span><span style="color: black;">)</span><span style="color: black;">)</span></pre>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter008.png" alt="debutTkinter008.png" style="display:block; margin:0 auto;" title="debutTkinter008.png, mar. 2009" height="88" width="282" /></p>
<p>Ça avance, ça avance!</p>
<p>Ce qui peut être interessant, c'est de faire intervenir cette variable dans l'interface.</p>
<p>La première fois où j'ai eu à faire un changement de valeur de texte dans l'interface, je ne me suis pas servi de la classe variable mais je fesai tout avec des events... Pour chaque clique je fesai une modification... :baffed:</p>
<p>Grace aux class variable c'est super simple! (On ne se moque pas les développeurs, ça peut sembler évident mais je n'ai pas encore une approche object-oriented très avancé et je découvre tkinter en fesant des relations entre la <a href="http://www.tcl.tk/man/tcl8.5/TkCmd/contents.htm" hreflang="en">doc officiel des commandes tk</a>, et la syntaxe Python)</p>
<p>Donc voici la méthode:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> createWidgets<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
<span style="color: #808080; font-style: italic;">#creation des variables</span>
<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span> = tk.<span style="color: black;">StringVar</span><span style="color: black;">(</span><span style="color: black;">)</span>
<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span>.<span style="color: #008000;">set</span><span style="color: black;">(</span><span style="color: #483d8b;">"Ecrivez ici"</span><span style="color: black;">)</span>
<span style="color: #808080; font-style: italic;">#creation des widgets</span>
mainFrame = tk.<span style="color: black;">Frame</span><span style="color: black;">(</span><span style="color: #008000;">self</span>, borderwidth=<span style="color: #ff4500;">2</span>, relief=<span style="color: #483d8b;">"groove"</span><span style="color: black;">)</span>
valeurOneLabel = tk.<span style="color: black;">Label</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"ValeurOne"</span><span style="color: black;">)</span>
valeurOneEntry = tk.<span style="color: black;">Entry</span><span style="color: black;">(</span>mainFrame, textvariable=<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span><span style="color: black;">)</span>
button = tk.<span style="color: black;">Button</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"Click Me!"</span>, command=<span style="color: #008000;">self</span>.<span style="color: black;">printSomething</span><span style="color: black;">)</span>
valeurTwoLabel = tk.<span style="color: black;">Label</span><span style="color: black;">(</span>mainFrame, text=<span style="color: #483d8b;">"ValeurTwo"</span>, textvariable=<span style="color: #008000;">self</span>.<span style="color: black;">valeurOneVar</span><span style="color: black;">)</span>
<span style="color: #808080; font-style: italic;">#position des widgets</span>
mainFrame.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span>
valeurOneLabel.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"EW"</span><span style="color: black;">)</span>
valeurOneEntry.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">1</span>, row=<span style="color: #ff4500;">0</span>, sticky=<span style="color: #483d8b;">"EW"</span><span style="color: black;">)</span>
button.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, columnspan=<span style="color: #ff4500;">2</span>, row=<span style="color: #ff4500;">1</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span>
valeurTwoLabel.<span style="color: black;">grid</span><span style="color: black;">(</span>column=<span style="color: #ff4500;">0</span>, columnspan=<span style="color: #ff4500;">2</span>, row=<span style="color: #ff4500;">2</span>, sticky=<span style="color: #483d8b;">"NSEW"</span><span style="color: black;">)</span></pre>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter009.png" alt="debutTkinter009.png" style="display:block; margin:0 auto;" title="debutTkinter009.png, mar. 2009" height="92" width="192" /></p>
<p>Et en temps réel!</p>
<p>C'est la fin de la première partie. Avec ça on peu faire pas mal de choses (comme un générateur de batch par exemple... :sauteJoie:</p>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter010.png" alt="debutTkinter010.png" style="display:block; margin:0 auto;" title="debutTkinter010.png, mar. 2009" height="301" width="676" /></p>
<h5>Varier la taille de la fenêtre<a name="Varier_la_taille_de_la_fenetre"></a></h5>
<p>Si vous avez essayé de resize la fenêtre, vous verrez que les widgets ne s'adaptent pas à sa taille:</p>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter011.png" alt="debutTkinter011.png" style="display:block; margin:0 auto;" title="debutTkinter011.png, mar. 2009" height="142" width="269" /></p>
<p>Le problème vient du "mainFrame" qui ne s'adapte pas à la taille de la fenetre...
Vu que nous avions déjà placé les informations de "poids" de la grille <a href="https://www.fevrierdorian.com/blog/post/2009/03/16/Tkinter%3A-Faire-communiquer-les-variables-de-l-interface.#Part_en_these">plus haut</a>, le reste est assez simple pour le coup:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> createWidgets<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: black;">)</span>:
<span style="color: #808080; font-style: italic;">#creation des variables</span>
<span style="color: black;">[</span>...<span style="color: black;">]</span>
<span style="color: #808080; font-style: italic;">#creation des widgets</span>
mainFrame = tk.<span style="color: black;">Frame</span><span style="color: black;">(</span><span style="color: #008000;">self</span>, borderwidth=<span style="color: #ff4500;">2</span>, relief=<span style="color: #483d8b;">"groove"</span><span style="color: black;">)</span>
mainFrame.<span style="color: black;">columnconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">0</span><span style="color: black;">)</span>
mainFrame.<span style="color: black;">columnconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">1</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span>
<span style="color: black;">[</span>...<span style="color: black;">]</span>
<span style="color: #808080; font-style: italic;">#position des widgets</span>
<span style="color: black;">[</span>...<span style="color: black;">]</span></pre>
<p>Explications:</p>
<pre class="python python">mainFrame.<span style="color: black;">columnconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">0</span>, weight=<span style="color: #ff4500;">0</span><span style="color: black;">)</span>
mainFrame.<span style="color: black;">columnconfigure</span><span style="color: black;">(</span><span style="color: #ff4500;">1</span>, weight=<span style="color: #ff4500;">1</span><span style="color: black;">)</span></pre>
<p>Le premier argument est l'index de la colonne. weight, est le "poids" du widget.</p>
<p><img src="https://www.fevrierdorian.com/blog/public/tkinter/faireCommuniquerVariables/debutTkinter012.png" alt="debutTkinter012.png" style="display:block; margin:0 auto;" title="debutTkinter012.png, mar. 2009" height="135" width="269" /></p>
<p>Et voila! :youplaBoum:</p>
<p>Vous pouvez vous amuser à modifier les valeurs des poids pour voir comment le programme réagit.</p>
<p>En espérant que ce petit tutorial vous sera utile, passez une bonne journée.</p>
<p>Dorian</p>