InfoBook.ro ← Harta anului
Modul 12 · Interfețe grafice (Tkinter)
Modul 12 · Conținut 3.4

De la consolă la fereastră

Consola neagră a fost utilă — dar utilizatorii adevărați vor butoane, casete și ferestre. Tkinter e biblioteca standard Python pentru interfețe grafice, iar tot ce știi despre obiecte (Modulul 11!) intră azi în joc.

🎯 Obiectiv 1Construiești ferestre cu Label, Entry, Button și le așezi cu pack, grid și place.
🎯 Obiectiv 2Legi evenimente (command=), citești caseta cu .get() și tratezi erorile cu messagebox.
🎯 Obiectiv 3Duci totul într-un PROIECT propriu, evaluat pe etape — de la idee la aplicație.
1

Anatomia unei ferestre Tkinter

Fereastra (Tk) e pânza; pe ea așezi widget-uri: etichete (Label), casete (Entry), butoane (Button). Apasă pe orice widget din fereastra de mai jos!

Aplicația mea — Tk()
Scrie numele tău:
Salută-mă
ⓘ Salut
Bună, Maria!
👆 apasă pe bară, etichetă, casetă, buton sau mesaj
Legătura cu Modulul 11: Tk(), Label(...), Entry(...), Button(...) sunt toate instanțieri de clase predefinite — fereastra și widget-urile sunt OBIECTE, iar .pack() și .get() sunt metodele lor. POO în acțiune!
⚠ Atenție — fragmentele de mai sus sunt IZOLATE! Fiecare arată un singur widget. Dacă le lipești pur și simplu, primești NameError: name 'salut' is not defined, pentru că command=salut cere ca funcția să fie definită ÎNAINTE. Iată programul COMPLET, în ordinea corectă — copiază-l pe ACESTA:
1import tkinter as tk
2from tkinter import messagebox
3 
4fereastra = tk.Tk()
5fereastra.title("Aplicația mea")
6fereastra.geometry("320x230") # fereastră cu spațiu
7 
8eticheta = tk.Label(fereastra, text="Scrie numele tău:",
9 font=("Arial", 12))
10eticheta.pack(pady=(24, 6)) # spațiu sus, apoi jos
11 
12caseta = tk.Entry(fereastra, font=("Arial", 12), width=22)
13caseta.pack(pady=6, ipady=4) # ipady = casetă mai înaltă
14 
15def salut(): # definită ÎNAINTE de buton
16 nume = caseta.get() # citirea, LA CLIC
17 messagebox.showinfo("Salut", "Bună, " + nume + "!")
18 
19buton = tk.Button(fereastra, text="Salută-mă",
20 font=("Arial", 11), command=salut)
21buton.pack(pady=16, ipadx=10, ipady=4) # buton mai mare
22 
23fereastra.mainloop() # la FINAL
Ordinea care contează: întâi fereastra și widget-urile → apoi def salut() (cu .get() și messagebox ÎNĂUNTRU) → apoi butonul care o leagă → la final mainloop().
🪟 Rețeta ferestrei „aerisite" — folosește-o la TOATE proiectele:
  • fereastra.geometry("320x230") — dă ferestrei o mărime decentă (lățime × înălțime), altfel se strânge cât widget-urile;
  • .pack(pady=10, padx=20) — spațiu ÎN JURUL widget-ului (sus-jos / stânga-dreapta); pady=(24, 6) = 24 sus, 6 jos;
  • .pack(ipady=4, ipadx=8) — spațiu ÎN INTERIOR: casete și butoane mai înalte/late, mai ușor de apăsat;
  • font=("Arial", 12) și width=22 — text mai mare și casete mai lungi.

Familia de widget-uri — pe scurt

Cele patru pe care le folosești mereu — plus două pe care e bine să le cunoști, exact cum le enumeră programa.

1tk.Label(...) # text static
2tk.Entry(...) # o linie de introdus
3tk.Button(...) # buton apăsabil
4tk.Frame(...) # cutie care grupează
5tk.Text(...) # casetă pe MAI MULTE linii
6tk.Canvas(...) # pânză de DESEN
7 
8# messagebox = pop-up, nu widget
Când le folosești: Text = un „Entry mare", pentru paragrafe (o notiță, un mesaj lung) — citit cu .get("1.0", "end"). Canvas = suprafață pe care DESENEZI cu cod: linii, dreptunghiuri, cercuri — perfect pentru un grafic, o hartă sau un mic joc. Le vei folosi în proiecte mai ambițioase.
2

Așezarea widget-urilor: pack · grid · place

Un widget creat nu apare până nu-l AȘEZI. Sunt trei manageri de aranjare — aceleași 3 widget-uri, trei feluri de a le pune. Comută:

Layout — Tk()
Regula practică: pack pentru liste simple, unul sub altul (90% din cazuri); grid pentru formulare aliniate pe rânduri și coloane (etichetă lângă casetă); place doar când vrei poziții fixe exacte. Nu amesteca pack și grid în aceeași fereastră — Tkinter se blochează!

place în detaliu: sistemul de coordonate și mărimea ferestrei

Fereastra e o grilă de pixeli — mici pătrățele luminoase. Colțul din stânga-sus e (0, 0). De acolo, x crește spre DREAPTA, iar y crește în JOS (atenție: y merge în jos, nu ca la matematică!). widget.place(x=150, y=80) pune widget-ul cu colțul lui la 150 pixeli dreapta și 80 pixeli jos.

(0, 0) x → y ↓ buton place(x=150, y=80)
Mărimea ferestrei: implicit, fereastra se strânge cât să încapă widget-urile. O faci mai mare cu fereastra.geometry("400x300") — 400 pixeli LĂȚIME × 300 ÎNĂLȚIME. Poți adăuga și poziția pe ecran: "400x300+200+100" (400×300, la 200px dreapta și 100px jos de colțul ecranului).

🎮 trage cursoarele — butonul se mută în fereastra de 240×150:

geometry("240x150") — Tk()
Salut
x = 60
y = 40
buton.place(x=60, y=40)
Program complet cu place și fereastră mărită:
1import tkinter as tk
2fereastra = tk.Tk()
3fereastra.geometry("300x200") # 300 lat × 200 înalt
4buton = tk.Button(fereastra, text="aici!")
5buton.place(x=120, y=90) # fix la (120, 90)
6fereastra.mainloop()
3

Evenimente și messagebox

O interfață grafică nu rulează de sus în jos — așteaptă evenimente (clic!) și reacționează cu funcția legată prin command=. Testează live:

📋 program COMPLET și AERISIT — copiază-l pe tot, rulează direct:

1import tkinter as tk
2from tkinter import messagebox
3 
4fereastra = tk.Tk()
5fereastra.title("Salut")
6fereastra.geometry("300x180")
7 
8caseta = tk.Entry(fereastra, font=("Arial", 12), width=20)
9caseta.pack(pady=(28, 10), ipady=4)
10 
11def salut(): # funcția-reacție
12 messagebox.showinfo("Salut", "Bună, " + caseta.get())
13 
14buton = tk.Button(fereastra, text="Salută-mă",
15 font=("Arial", 11), command=salut) # FĂRĂ ()
16buton.pack(pady=10, ipadx=10, ipady=4)
17 
18fereastra.mainloop()
Capcana command: scrii command=salut (FĂRĂ paranteze!). Cu salut() funcția ar rula imediat, nu la clic. Și nu uita import tkinter as tk pe prima linie — altfel: NameError: name 'tk' is not defined.

▶ demo funcțional — aplicația chiar merge:

Salut — Tk()
Scrie numele tău:
Salută-mă
ⓘ Salut
OK
scrie ceva și apasă butonul — exact ca aplicația reală 👆
4

Calculatorul grafic — versiunea „ca lumea"

Codul de manual e scurt, dar dacă îl rulezi cu litere sau împarți la 0… crapă. Iată versiunea REZISTENTĂ: cu etichete, validare și mesaje de eroare. Click pe orice linie pentru explicație.

👆 apasă pe orice linie din cod pentru explicație

▶ aplicația, funcțională — încearcă și cu litere sau ÷ 0:

Calculator — Tk()
Primul număr:
Al doilea număr:
+
×
÷
Rezultat:
⛔ Eroare
OK
Ce s-a îmbunătățit față de codul de manual: etichete deasupra fiecărei casete, butoanele grupate cu un Frame, rezultatul arată toată expresia (12 + 4 = 16), iar erorile (text în loc de număr, împărțire la 0) sunt prinse cu try/except și messagebox.showerror — aplicația nu mai crapă niciodată.
5

Verificare rapidă

Cinci întrebări despre lumea ferestrelor.

6

Fișa de sinteză

Tkinter pe scurt.

Fereastra: fereastra = tk.Tk() — un obiect! La final, fereastra.mainloop() pornește bucla de evenimente.
Widget-uri: Label (text), Entry (o linie), Button (buton), Frame (grupează), Text (mai multe linii), Canvas (desen) — toate primesc fereastra ca părinte.
Așezarea: .pack() unul sub altul · .grid(row=, column=) pe tabel · .place(x=, y=) la coordonate fixe.
Fereastră aerisită: geometry("320x230") pentru mărime · pady/padx = spațiu în jur · ipady/ipadx = widget mai mare · font=("Arial", 12).
Evenimente: Button(..., command=functie) — FĂRĂ paranteze; funcția rulează la clic.
Citirea din casetă: caseta.get() dă un STRING → int(caseta.get()) pentru numere (ca la fișiere!).
messagebox.showinfo(titlu, mesaj) — pop-up simplu de informare; există și showerror, showwarning.
Exersează pe pbinfo.ro — rezolvă-le întâi pe consolă, apoi îmbracă-le în interfață:
#1258 · ușoară

scadere2

Diferența a două numere — primul buton al calculatorului tău.

Rezolvă pe pbinfo.ro →
#105 · ușoară

max2

Maximul a două numere — pentru un buton „Cine e mai mare?".

Rezolvă pe pbinfo.ro →
#3978 · medie

sabc

Sume pe intervale — bun pentru mai multe casete de intrare.

Rezolvă pe pbinfo.ro →
#469 · ușoară

Interval2

x aparține intervalului [a,b]? — perfect pentru un quiz cu buton de verificare.

Rezolvă pe pbinfo.ro →
7

🚀 Proiect final — aplicația ta cu interfață

Aici pui totul în practică. Alege UNA din cele trei teme (sau propune-ți una) și construiește o aplicație Tkinter completă, pe etape.

● ușor

🎱 Magic 8-Ball / zaruri

  • buton „Întreabă" → random.choice dintr-o listă de răspunsuri
  • afișezi răspunsul într-un Label mare
  • variantă: „Aruncă zarul" → număr 1–6
  • pui o întrebare, primești un verdict amuzant
● ușor

🔐 Generator de parole

  • o casetă pentru lungime + buton „Generează"
  • random alege litere, cifre, simboluri
  • parola apare într-un Label
  • bonus: buton „Copiază" (clipboard_append)
●● mediu

❓ Quiz cu scor

  • întrebări despre muzică, filme, jocuri (o listă)
  • buton „Verifică" → messagebox „Corect!/Greșit!"
  • ții scorul într-o variabilă și îl afișezi
  • buton „Următoarea" trece la altă întrebare
●● mediu

✊✋✌ Piatră-foarfece-hârtie

  • 3 butoane; calculatorul alege aleator
  • compari și afișezi „Ai câștigat/pierdut/egal"
  • ții scorul: tu vs calculator
  • bonus: primul la 5 puncte câștigă
●●● provocare

⚡ Joc de reacție

  • butonul devine verde după un timp ALEATOR
  • apeși cât mai repede → măsori timpul de reacție
  • folosești fereastra.after(ms, funcție) și time
  • ții cel mai bun scor (record personal)
●●● provocare

🎨 Tablă de desen (Canvas)

  • desenezi cu mouse-ul pe un Canvas
  • butoane de culoare + „Șterge tot"
  • legi evenimentul de mișcare a mouse-ului (bind)
  • bonus: salvezi desenul / alegi grosimea liniei
Alte idei rapide: 🐍 „Ghicește numărul" (programul alege 1–100, tu ghicești, îți spune mai mare/mai mic) · 🍕 calculator de bacșiș/împărțit nota · ⏱ cronometru sau numărătoare inversă · 🌡 convertor de unități (°C↔°F, km↔mile) · 📊 sondaj cu butoane care numără voturile. Alege ce te distrează — dacă îți place tema, o duci până la capăt.

Etapele proiectului — livrează pe rând

  1. Schița pe hârtie. Desenează fereastra: ce widget-uri, unde. Decide layout-ul (pack sau grid).
  2. Interfața „moartă". Creează fereastra și toate widget-urile, așezate corect — încă fără să facă nimic. Rulează și verifică aspectul.
  3. Un buton viu. Scrie prima funcție-reacție și l-o legi prin command=. Testează-l singur.
  4. Restul logicii. Completează toate reacțiile: citire cu .get(), calcul, afișare cu .config() sau messagebox.
  5. Rezistența la erori. Adaugă try/except și mesaje de eroare — aplicația nu trebuie să crape la date greșite.
  6. Finisaje. Titlu de fereastră, spațiere (padx/pady), texte clare. Testează cu un coleg care n-a mai văzut-o.
Livrabile: fișierul .py care rulează, plus 2–3 capturi de ecran ale aplicației în funcțiune. Cod curat: funcții cu nume clare, fără repetiții (folosește bucla pentru butoane, ca la calculator).

Barem de evaluare — 100 de puncte

CriteriuPunctaj
Fereastra pornește și afișează widget-urile corect (layout curat)25 p
Butoanele reacționează — evenimentele funcționează25 p
Citirea din casete și logica dau rezultate corecte25 p
Tratarea erorilor (date greșite, ÷ 0) cu messagebox15 p
Cod curat, fără repetiții + aspect îngrijit10 p
Recapitulare a tot anul: proiectul tău atinge decizii (M02), funcții (M05), fișiere (M10), obiecte (M11) și interfețe (M12). E dovada că poți construi un program REAL, de la zero.
← anteriorModul 11a · Tipul struct (C++) urmează →Modul 13 · Recapitulare finală