1. Prima fereastra Tkinter
Tk, iar fiecare element vizual este un widget — obiect dintr-o clasa derivata din Widget.- Import biblioteca
- Creeaza fereastra radacina:
root = tk.Tk() - Configureaza fereastra (titlu, dimensiuni)
- Adauga widget-uri in fereastra
- Porneste bucla de evenimente:
root.mainloop()
import tkinter as tk root = tk.Tk() # creaza fereastra principala root.title("Prima mea fereastra") # seteaza titlul barei root.geometry("400x250") # latime x inaltime in pixeli root.resizable(False, False) # blocheaza redimensionarea # widget-urile se adauga INAINTE de mainloop() root.mainloop() # porneste bucla - ULTIMA linie!
isinstance(root, tk.Tk) => True
root.title() => "Prima mea fereastra"
Label.cget('text') => 'Test' Entry.cget('width') => 20
Tkinter OK: Label, Entry, Button create cu succesmainloop() blocheaza executia si asteapta evenimente. Programul ramane activ pana utilizatorul inchide fereastra.2. Widget-urile fundamentale: Label, Entry, Button
- Label — afiseaza text sau imagine (read-only)
- Entry — camp de text pe un singur rand (input)
- Button — buton cu actiune la click
import tkinter as tk root = tk.Tk() root.title("Demo Widgets") root.geometry("300x200") # Label -- eticheta cu text lbl = tk.Label(root, text="Introduceti numele:", font=("Arial", 12), fg="navy") lbl.pack(pady=10) # Entry -- camp de introducere text camp_nume = tk.Entry(root, width=25, font=("Arial", 11)) camp_nume.pack(pady=5) # Label rezultat -- initial gol lbl_rez = tk.Label(root, text="", font=("Arial", 12), fg="green") lbl_rez.pack(pady=5) # Functia callback -- apelata la click pe buton def saluta(): nume = camp_nume.get() # citeste textul din Entry if nume.strip(): lbl_rez.config(text=f"Buna ziua, {nume}!") else: lbl_rez.config(text="Scrieti un nume mai intai!") # Button -- command= fara () -- trecem referinta, nu apelul btn = tk.Button(root, text="Saluta", command=saluta, bg="#4CAF50", fg="white", font=("Arial", 11, "bold")) btn.pack(pady=10) root.mainloop()
camp_nume.get() cu "Maria" scris => 'Maria' label afiseaza: 'Buna ziua, Maria!' camp gol + click: label afiseaza: 'Scrieti un nume mai intai!' entry.insert(0, "text initial") => insereaza la pozitia 0 entry.delete(0, END) => entry.get() => '' label.config(text=...) => modifica textul labelului dinamic
command=saluta — fara paranteze. Daca scriem command=saluta(), functia se executa imediat la creare, nu la click.3. Gestionarea layout-ului: pack, grid, place
# pack(): parametri frecventi tk.Label(root, text="Sus").pack(side=tk.TOP, pady=5) tk.Label(root, text="Jos").pack(side=tk.BOTTOM, pady=5) tk.Button(root, text="Stanga").pack(side=tk.LEFT, padx=5) tk.Button(root, text="Dreapta").pack(side=tk.RIGHT, padx=5) # fill=X -> se intinde pe orizontala # fill=BOTH + expand=True -> umple tot spatiul
# grid(): row=rand, column=coloana, indexare de la 0 tk.Label(root, text="Inaltime (cm):").grid( row=0, column=0, sticky="e", padx=5, pady=5) tk.Entry(root, width=10).grid( row=0, column=1, padx=5, pady=5) tk.Label(root, text="Greutate (kg):").grid( row=1, column=0, sticky="e", padx=5, pady=5) tk.Entry(root, width=10).grid( row=1, column=1, padx=5, pady=5) tk.Button(root, text="Calculeaza").grid( row=2, column=0, columnspan=2, pady=10) # sticky="e" -> aliniere la dreapta in celula # columnspan=2 -> celula se intinde pe 2 coloane
# place(): pozitionare exacta in pixeli tk.Button(root, text="Absolut").place( x=50, y=80, width=100, height=40) # sau relative (0.0=stanga/sus, 1.0=dreapta/jos) tk.Label(root, text="Centru").place( relx=0.5, rely=0.5, anchor="center") # place() nu e recomandat pt UI redimensionabile
pack(side=LEFT, padx=5) -> 3 butoane aliniate orizontal pack(pady=10) -> spatiu 10 pixeli sus si jos grid(row=0, column=0) -> pozitionare in tabel grid(sticky="e") -> aliniere la dreapta in celula grid(columnspan=2) -> celula pe 2 coloane place(x=50, y=80) -> coordonate absolute in pixeli place(relx=0.5, rely=0.5, anchor="center") -> centrat relativ
4. StringVar — variabile reactive
textvariable= atunci cand valoarea se schimba. Implementeaza pattern-ul Observer.import tkinter as tk root = tk.Tk() root.title("StringVar Demo") root.geometry("350x180") # Variabila reactiva mesaj_var = tk.StringVar() mesaj_var.set("Astept input...") # Label legat la variabila -- se actualizeaza automat lbl_live = tk.Label(root, textvariable=mesaj_var, font=("Arial", 13), fg="darkblue") lbl_live.pack(pady=15) entry_var = tk.StringVar() camp = tk.Entry(root, textvariable=entry_var, font=("Arial", 11), width=25) camp.pack(pady=5) def actualizeaza(): text = entry_var.get() mesaj_var.set(f"Ai scris: '{text}'") # Label se actualizeaza AUTOMAT -- fara .config() explicit tk.Button(root, text="Actualizeaza", command=actualizeaza).pack(pady=8) root.mainloop()
sv = StringVar(); sv.set('test'); sv.get() => 'test'
sv.set('altceva'); sv.get() => 'altceva'
iv = IntVar(); iv.set(42); iv.get() => 42
Label(textvariable=sv) se actualizeaza automat
cand sv.set('actualizat automat') este apelat
-- fara apel explicit la .config().5. Aplicatie completa: Calculator IMC
import tkinter as tk # --- Logica business --- def calculeaza_imc(h_str, g_str): try: h = float(h_str) / 100 g = float(g_str) if h <= 0 or g <= 0: return "Valori invalide!" imc = g / (h ** 2) if imc < 18.5: status = "Subponderal" elif imc < 25: status = "Normal" elif imc < 30: status = "Supraponderal" else: status = "Obez" return f"IMC = {imc:.2f} ({status})" except ValueError: return "Introduceti numere valide!" root = tk.Tk() root.title("Calculator IMC") root.geometry("320x220") root.resizable(False, False) tk.Label(root, text="Inaltime (cm):").grid(row=0, column=0, sticky="e", padx=10, pady=8) entry_h = tk.Entry(root, width=12) entry_h.grid(row=0, column=1, padx=10, pady=8) tk.Label(root, text="Greutate (kg):").grid(row=1, column=0, sticky="e", padx=10, pady=8) entry_g = tk.Entry(root, width=12) entry_g.grid(row=1, column=1, padx=10, pady=8) def pe_click(): rez = calculeaza_imc(entry_h.get(), entry_g.get()) lbl_rez.config(text=rez) tk.Button(root, text="Calculeaza IMC", command=pe_click, bg="#2196F3", fg="white").grid(row=2, column=0, columnspan=2, pady=12) lbl_rez = tk.Label(root, text="---", font=("Arial", 13, "bold"), fg="darkgreen") lbl_rez.grid(row=3, column=0, columnspan=2, pady=8) root.mainloop()
calculeaza_imc(170, 65) => IMC = 22.49 (Normal) calculeaza_imc(175, 90) => IMC = 29.39 (Supraponderal) calculeaza_imc(160, 45) => IMC = 17.58 (Subponderal) calculeaza_imc(abc, 65) => Introduceti numere valide!
6. OOP in Tkinter si echivalentul C++ EXCLUSIV INTENSIV
Tkinter este implementat complet in paradigma OOP. Intelegerea ierarhiei de clase te ajuta sa extinzi widget-urile si sa compari cu modelul C++.
object→BaseWidget→Widget→Label,Button,Entry...- Fiecare widget mosteneste:
pack(),grid(),place(),config(),destroy() - Fiecare suprascrie constructorul cu parametrii specifici
import tkinter as tk class LabelColorat(tk.Label): def __init__(self, parinte, text, tip="info", **kwargs): culori = {"info": "#dbeafe", "ok": "#dcfce7", "eroare": "#fee2e2"} bg = culori.get(tip, "white") super().__init__(parinte, text=text, bg=bg, font=("Arial", 11), padx=8, pady=4, **kwargs) root = tk.Tk() LabelColorat(root, "Operatie reusita!", tip="ok").pack(pady=5) LabelColorat(root, "Eroare de calcul!", tip="eroare").pack(pady=5) root.mainloop()
#include <iostream> #include <string> using namespace std; // Clasa de baza -- echivalent tk.Widget class Widget { protected: string text; public: Widget(string t) : text(t) {} virtual void show() const { cout << "Widget: " << text << endl; } }; // Clasa derivata -- echivalent tk.Label class Label : public Widget { public: Label(string t) : Widget(t) {} void show() const override { cout << "Label: [" << text << "]" << endl; } }; // Clasa derivata -- echivalent tk.Button class Button : public Widget { public: Button(string t) : Widget(t) {} void click() const { cout << "Click: " << text << endl; } void show() const override { cout << "Button: [" << text << "]" << endl; } }; int main() { Label l("Salut, GUI!"); Button b("Calculeaza IMC"); l.show(); b.show(); b.click(); return 0; }
Label: [Salut, GUI!] Button: [Calculeaza IMC] Click: Calculeaza IMC
| Concept | Python Tkinter | C++ |
|---|---|---|
| Clasa de baza | tk.Widget | class Widget |
| Mostenire | class X(tk.Widget) | class X : public Widget |
| Suprascriere | def show(self): | void show() const override |
| Constructor | def __init__(self,...) | Widget(string t):text(t){} |
| Metoda virtuala | implicit (toate metodele) | explicit: virtual |