Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

Widgets and Layouts/ro

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Widgeturi și layout-uri

Widget-uri

Widgeturile sunt elemente primare pentru crearea de interfețe grafice în Qt. Widgeturile pot afișa date și informații, să primească input sau să servească drept container pentru alte widgeturi care pot fi grupate împreună. Un widget care nu este inclus într-un widget părinte se numește fereastră.

http://doc.qt.nokia.com/4.7-snapshot/images/parent-child-widgets.png

Clasa QWidget oferă funcționalitățile de bază pentru afișarea și manevrarea a evenimentelor de input. Toate elementele interfeței grafice sunt fie subclase ale QWidget, fie sunt utilizate în relație cu subclase ale QWidget. Crearea unor widgeturi particularizate se realizează prin moștenirea clasei QWidget și/sau reimplementarea funcțiilor virtuale de manevrare a evenimentelor.

Pentru redarea grafică a widgeturilor se folosesc stiluri. Acestea sunt clase care încapsulează aspectul grafic al unui obiect de interfață. Widgeturile de bază utilizează clasa QStyle pentru a obține un aspect echivalent cu aspectul obiectelor de interfață din sistemul de operare folosit.

Layout-uri

Layout-urile reprezintă un mod elegant și flexibil prin care putem aranja automat widgeturile copii într-un widget container. Fiecare widget raportează layout-ului necesitățile sale legate de dimensiune prin proprietățile sizeHint și sizePolicy, iar layout-ul le distribuie în concordanță cu spațiul disponibil.

http://doc.qt.nokia.com/4.7-snapshot/images/qgridlayout-with-5-children.png http://doc.qt.nokia.com/4.7-snapshot/images/qformlayout-with-6-children.png

Un alt motiv pentru a folosi layouturi este că ele asigură adaptarea automată a interfeței la diferite fonturi, limbi și platforme. Dacă utilizatorul schimbă fontul sistemului, ferestrele aplicației vor răspunde imediat și se vor redimensiona dacă este necesar. Iar dacă se traduce interfața grafică în alte limbi, clasele de layout vor lua în considerare conținutul tradus al widgeturilor pentru a evita trunchierea textului.

Alte clase care asigură servicii asemănătoare layout-urilor sunt QSplitter, QScrollArea, QMainWindow și QMdiArea. Toate aceste clase asigură un layout flexibil pe care un utilizator îl poate manipula. De exemplu QSplitter furniează o bară de separație pe care un utilizator printr-o operație de drag poate redimensiona widgeturi, iar QMdiArea oferă suport pentru o interfață MDI.

Clase de widgeturi

Toate interfețele grafice sunt compuse din widgeturi și layout-uri și toate actiunile au ca puntct de pornire widgeturile. De aceea este necesar să cunoaștem widgeturile disponibile atunci când dorim să proiectăm o aplicație.

În cele ce urmează voi prezenta widgeturile de bază, alături de o scurtă descriere:
  • QCheckBox - este un checkbox care are două stari : On(marcat) și Off (nemarcat). În mod obişnuit este folosit pentru a reprezenta anumite setări într-o aplicație care pot activate sau dezactivate fără a afecta alte setări. Dar pot fi implementate și altfel de comportamente. De exemplu putem grupa logic mai multe astfel de widgeturi folosindu-ne de QButtonGroup, astfel încât doar unul dintre checkbox-uri va putea să fie selectat.

http://doc.qt.nokia.com/4.7-snapshot/images/checkboxes-exclusive.png http://doc.qt.nokia.com/4.7-snapshot/images/checkboxes-non-exclusive.png

  • QComboBox - este un widget care combină un buton cu o listă de tip popup. Astfel se poate prezenta o listă de opțiuni într-un mod in care să ocupe cât mai puțin spațiu din fereastră. Un combobox este un widget de selecție prin care se afișează elementul curent și poate afișa o listă de tip popup a elementelor posibile. Acest widget poate fi editabil, permițând utilizatorului să modifice fiecare element și poate conține atât imagini cât și text.

http://doc.qt.nokia.com/4.7-snapshot/images/qstyle-comboboxes.png

  • QCommandLinkButton - este un widget asemănător cu un buton de comandă similar butonului de comandă introdus în Vista. Ca aspect este similar cu un QPushButton, dar permite și inserarea de text descriptiv. În mod implicit, acest widget conține și o imagine reprezentând o săgeată.

http://www.qttutorial.com/wp-content/uploads/2011/01/commandlinkbutton_thumb.jpg

  • QDateEdit - este un widget bazat pe widgetul QDateTimeEdit dedicat pentru editarea datelor. Multe din funcțiile sale sunt deja implementate în QDateTimeEdit.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-dateedit.png

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-datetimeedit.png

  • QDial - furnizează un control similar unui vitezometru sau potențiometru. Este folosit în situațiile în care utilizatorul trebuie să introducă o valoare într-un anumit interval. QDial mostenește clasa QAbstractSlider, iar multe dintre comportamentele sale sunt similiare cu cele ale unui slider.

http://doc.qt.nokia.com/4.7-snapshot/images/plastique-dial.png

  • QDoubleSpinBox - furnizează un spinbox care poate lua și valori raționale. Aceste valori pot fi date fie de la tastatura prin introducere directă sau cu ajutorul tastelor de mișcare, fie prin mouse prin click pe butoanelor de Up și Down.
  • QFocusFrame - furnizează o ramă care poate fi plasată înafara zonei desenabile a unui widget.
  • QFontComboBox - este un combobox care permite selectarea unui font. Combobox-ul este populat cu o listă alfabetică a fonturilor.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-fontcombobox.png

  • QLCDNumber - afișează un număr într-un format LCD. Afișarea se poate face în sistemele de numerație zecimal, hexazecimal, octal sau binar.

http://doc.qt.nokia.com/4.7-snapshot/images/cde-lcdnumber.png

  • QLabel - este un widget prin care putem afișa un text sau o imagine. Nu este implementată nici un fel de interacțiune cu utilizatorul. Aspectul vizual al unui QLabel poate fi configurat prin diverse căi și poate fi stabilită o cheie mnemonică de focus pentru un alt widget. Un label poate conține următoarele tipuri de conținut :

[[Image:tabel%2520QLabel.JPG]] Tabelul 1. Tipuri de conținut pentru QLabel

  • QLineEdit - este un editor text care permite unui utilizator să introducă și să editeze pe o singură linie text normal cu ajutorul unor funcții precum Undo, Redo, Cut ,Paste și Drag-and-Drop. Prin apelarea funcției void setEchoMode (EchoMode) QLineEdit va permite doar introducerea de caractere, nu și ștergerea lor. Lungimea textului introdus poate fi limitat prin apelul metodei void setMaxLength(int). Textul introdus poate fi constrâns să corespundă unui anumit tip de conținut prin intermediul unui validator sau cu o mască pentru input.

http://doc.qt.nokia.com/4.7-snapshot/images/windows-lineedit.png

  • QMenu - furnizează un meniu pentru a fi utilizat în bare de meniuri sau în calitate de meniu contextual sau meniu de tip popup. El poate fi un meniu de tip pull-down într-o bară de meniuri sau poate fi un meniu contextual de sine stătător. Un QMenu poate fi adăugat la un QMenuBar prin apelul funcției addMenu. Meniurile contextuale pot fi invocate printr-o combinație de taste sau făcând click dreapta. Pot fi executate fie asincron prin metoda popup(), fie sincron prin metoda exec().

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-menu.png

  • QProgressBar - furnizează o bară de progres orizontală sau verticală. Ea este folosită pentru a da o indicație a progresului unei operații și pentru a asigura utilizatorul că aplicația încă rulează.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-progressbar.png

  • QPushButton - este un buton de comandă și este unul dintre cele mai folosite widgeturi în orice interfață grafică. Butoanele tipice sunt Ok, Apply, Cancel, Close, Yes, No și Help. Un QPushButton este rectangular și afișează un text care descrie acțiunea pe care o efectuează. Pe lângă acest text, opțional putem seta și o imagine pe care să o afișăm.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-pushbutton.png

  • QRadioButton - furnizează un buton radio cu o etichetă text. Are două stări: On(marcat) și Off(nemarcat).Într-o grupare de butoane radio, un singur buton radio poate fi marcat;dacă un utilizator marchează alt buton radio, butonul radio marcat anterior va fi deselectat. Implicit, butoanele radio sunt autoexclusive. Butoanele care aparțin de același părinte vor forma un grup.

http://doc.qt.nokia.com/4.7-snapshot/images/windows-radiobutton.png

  • QScrollArea - permite realizarea unei vizualizari care poate fi derulată (scrolling). El este folosit pentru a afișa conținutul unui widget copil în cadrul unui frame (rame). Dacă widgetul depășeste suprafața frame-ului (ramei) părinte, atunci acest widget ne va furniza bare de derulare (scroll bars) astfel încât tot conținutul widgetului copil să poată fi văzut.

http://doc.qt.nokia.com/4.7-snapshot/images/qscrollarea-twoscrollbars.png

  • QScrollBar - furnizează bare de derulare verticale și orizontale. Ele permit accesarea conținutului unui widget care este prea mare pentru a putea fi afișat în întregime. De asemenea el pot servi de indicator pentru poziția curentă în cadrul widgetului sau pentru mărimea widgetului.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-horizontalscrollbar.png

  • QSizeGrip - ne permite să redimensionăm fereastra principală printr-o operație de drag-and-drop.

http://doc.qt.nokia.com/4.7-snapshot/images/plastique-sizegrip.png

  • QSlider - ne furnizează un slider vertical sau orizontal. Slider-ul este un widget clasic pentru a controla o valoare mărginită.

http://doc.qt.nokia.com/4.7-snapshot/images/windows-slider.png

  • QSpinBox - furnizează un spinbox care poate lua doar valori întregi. Aceste valori pot fi data fie de la tastatura prin introducere directă sau cu ajutorul tastelor de mișcare, fie prin mouse prin apăsarea butoanelor de Up și Down. Valorii afișate i se poate adăuga un prefix și/sau sufix.

http://doc.qt.nokia.com/4.7-snapshot/images/plastique-spinbox.png

  • QTabBar - este o bară tabulară care poate fi folosită, de exemplu într-o fereastră de dialog. QTabBar este foarte ușor de folosit; el desenează tab-urile folosindu-se de una din formele predefinite. Poate fi moștenită dacă ne dorim să conțină funcționalități suplimnetare.

http://doc.qt.nokia.com/4.7-snapshot/images/plastique-tabbar.png

  • QTabWidget - este un widget care se compune din bara tabulară (QTabBar), respectiv o zonă de afișare a tabului curent. În mod normal bara tabulară este plasată deasupra zonei de afișare, dar prin setarea unui nou TabPosition se poate ajunge la o altă configurație. Fiecare tab este asociat unui widget diferit.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-tabwidget.png

  • QTimeEdit - este un widget bazat pe widgetul QDateTimeEdit dedicat pentru editarea orei. Multe din funcțiile sale sunt deja implementate în QDateTimeEdit.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-timeedit.png

  • QToolBox - asigură o coloană de widgeturi suprapuse într-o formă tabulară. Tab-urile sunt dispuse vertical, iar sub tab-ul curent este afișat conținutul widgetului curent. Fiecare tab are o poziție de index în cadrul coloanei de taburi.

http://www.opennet.ru/docs/RUS/qt3_prog/images/fig2.18d.png

  • QToolButton - este un buton de comandă care asigură un acces rapid la comenzi sau opțiuni care este de obicei plasat într-un QToolBar. Îndeosebi de un buton de comandă normal (QPushButton), el arată o imagine, ci nu un text. Butoanele de tip QToolButton sunt în mod normal create atunci când se adaugă noi acţiuni la un QToolBar.

http://doc.qt.nokia.com/4.7-snapshot/images/assistant-toolbar.png

  • QWidget - este clasa moştenită de toate obiectele de interfaţă din Qt. Ea primeşte evenimente de la tastatură, mouse și sistemul de feresetre. Tot ea este responsabilă de reprezentarea grafică a ei. Un widget care nu este inclus într-un widget părinte se numește fereastră. De obicei ferestrele au o ramă și o bară de titlu, deși este posibil să fie create ferestre și fără asemenea decorațiuni prin setarea unor flag-uri de fereastră. Pentru acest tip de widgeturi putem seta un titlu prin void setWindowTitle(const QString &) sau o imagine cu void setWindowIcon(const QIcon &).

Pe lângă acestea Qt oferă și widgeturi mai complexe precum :

  • QCalendarWidget - furnizează un calendar care permite unui utilizator să selecteze o dată. Acest widget este inițializat cu dată curentă, dar prin intermediul slot-urilor sale putem să schimbăm anul, luna sau ziua. Utilizatorul poate schimba data fie de la tastatură, fie prin mouse. De asemenea se poate impune o constrângere privind data selectată prin proprietățile minimumDate și maximumDate.

http://doc.qt.nokia.com/4.7-snapshot/images/cleanlooks-calendarwidget.png

  • QColumnView - este o implementare de tip model/view a unei coloane de elemente. El afișează un model ca widgeturi de tip QListView pentru fiecare ierarhie din arborele model.

http://doc.qt.nokia.com/4.7-snapshot/images/qcolumnview.png

  • QListView - afișează o listă de elemente care fie este preluată dintr-un model, fie le adăugăm rând pe rând.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-listview.png

  • QTableView - ne dă posibilitatea să afișam niște date în formă tabelară plecând de la un model. Se folosește de arhitectura model/view al lui Qt.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-tableview.png

  • QTreeView - este un widget cu care se pot afișa modele arborescente. Și acesta face uz de arhitectura model/view al lui Qt.

http://doc.qt.nokia.com/4.7-snapshot/images/windowsxp-treeview.png

  • QWebView - este un widget care este folosit pentru a vizualiza și uneori edita documente Web. Ea este principală componentă a modului QtWebKit. Poate fi folosită în diverse aplicații pentru a afișa conținut de pe Internet. Un website poate fi încărcat folosit funcția void load(const QUrl &url;). Alternativ, se mai poate folosi și funcția void setUrl(const QUrl &url;).

http://doc.qt.nokia.com/4.7-snapshot/images/qwebview-url.png

Managementul layout-urilor

Sistemul de layout-uri Qt este responsabil cu aranjarea automată a widgeturilor copil în cadrul unui widget părinte, astfel încât să utilizeze maximul de spațiu. Qt are inclus un set de clase pentru managementul layout-urilor care sunt folosite pentru a descrie cum widgeturile sunt distribuite în cadrul interfeței grafice a unei aplicații. Aceste layout-uri poziționează și redimensionează widgeturile atunci când spațiul disponibil se schimbă, asigurând faptul că widgeturile vor fi în mod constant rearanjate iar interfața grafică va rămâne utilizabilă.

Toate subclasele QWidget pot folosi clase de management al layout-urilor pentru managementul copiilor lor. Funcția void setLayout(QLayout* layout) aplică un layout unui widget. Când un layout este aplicat unui widget în acest mod, el va controla următoarele lucruri:
  • poziționarea widgeturilor copil;
  • dimensiuni implicite potrivite pentru ferestre;
  • dimensiuni minime potrivite pentru ferestre;
  • redimensionare automată;
  • actualizare automată când conținutul se schimbă:
    • dimensiunea fontului, a textului sau a altui conținut din widgeturile copil;
    • afișarea sau ascunderea unui widget copil ;
    • eliminarea unui widget copil.

Cel mai ușor mod de a da unui widget un layout bun este de a folosi un manager de layout gata construit. Aceste clase moștenesc clasa QLayout, care la rândul ei moșteneste clasa QObject (și nu QWidget). Ele pot avea grijă de managementul geometriei al unui set de widgeturi. Pentru a crea layout-uri mai complexe, clasele de management al layout-urilor pot fi imbricate. În mod obișnuit se folosesc una sau mai multe din următoarele layout-uri:

  • QHBoxLayout - așează widgeturile pe un singur rând de la stânga la dreapta ( sau de la dreapta la stânga pentru limbile de la dreapta la stânga);
 QWidget *window = new QWidget;
 QPushButton *button1 = new QPushButton("One");
 QPushButton *button2 = new QPushButton("Two");
 QPushButton *button3 = new QPushButton("Three");
 QPushButton *button4 = new QPushButton("Four");
 QPushButton *button5 = new QPushButton("Five");

QHBoxLayout '''layout = new QHBoxLayout;
 layout->addWidget(button1);
 layout->addWidget(button2);
 layout->addWidget(button3);
 layout->addWidget(button4);
 layout->addWidget(button5);

 window->setLayout(layout);
 window->show();

http://doc.qt.nokia.com/4.7-snapshot/images/qhboxlayout-with-5-children.png

QVBoxLayout - așează widgeturile pe o singură coloană, de sus în jos.

 QWidget *window = new QWidget;
 QPushButton *button1 = new QPushButton("One");
 QPushButton *button2 = new QPushButton("Two");
 QPushButton *button3 = new QPushButton("Three");
 QPushButton *button4 = new QPushButton("Four");
 QPushButton *button5 = new QPushButton("Five");

QVBoxLayout '''layout = new QVBoxLayout;
 layout->addWidget(button1);
 layout->addWidget(button2);
 layout->addWidget(button3);
 layout->addWidget(button4);
 layout->addWidget(button5);

 window->setLayout(layout);
 window->show();

http://doc.qt.nokia.com/4.7-snapshot/images/qvboxlayout-with-5-children.png

QGridLayout - așează widgeturile într-un tablou bidimensional. Widgeturile pot ocupa mai multe celule.

http://doc.qt.nokia.com/4.7-snapshot/images/qgridlayout-with-5-children.png

  • QFormLayout - pune widgeturile pe două coloane. Prima coloană reprezintă eticheta, iar a doua widgetul propriu-zis.
QFormLayout '''formLayout = new QFormLayout;
 formLayout->addRow(tr("&Name;:"), nameLineEdit);
 formLayout->addRow(tr("&Email;:"), emailLineEdit);
 formLayout->addRow(tr("&Age;:"), ageSpinBox);
 setLayout(formLayout);

http://doc.qt.nokia.com/4.7-snapshot/images/qformlayout-win.png


Atunci când se folosește un layout nu este necesar să specificăm un widget atunci când construim widgeturi copil. Layout-ul va seta drept părinte pentru widgeturile pe care le conține pe widgetul pe care este instalat. Layout-urile se pot imbrica, folosind funcția void addLayout(QLayout layout, int stretch =0). Layout-ul interior va deveni copilul layout-ului în care a fost inserat.

Atunci când se adaugă widgeturi la un layout, acesta va efectua următoarele operațiuni:

  1. Tuturor widgeturilor le va fi alocat un spațiu în concordanță cu proprietățile sale de sizePolicy și sizeHint.
  2. Dacă unul dintre widgeturi are setat un factor de întindere (stretch factor), cu o valoare mai mare decât zero, atunci îi este alocat spațiu în raport cu factorul lor de întindere.
  3. Dacă unul dintre widgeturi are factorul de întindere zero, ele vor căpăta mai mult spațiu dacă alte widgeturi nu doresc acel spațiu. Dintre acestea, spațiu este alocat mai întâi widgeturilor cu valoare de sizePolicy : Expanding.
  4. Dacă vreunui widget îi este alocat mai puțin spațiu decât dimensiunea lor minimă (sau decât dimensiunea minimă recomandată, dacă dimensiunea lor minimă nu este specificată) lui îi va fi alocat spațiu pentru a atinge dimensiunile minime.
  5. Orice widget căruia îi este alocat mai mult spațiu decât dimensiunea lor maximă le este redus spațiu la dimensiunea lor minimă.
Widgeturile sunt în mod normal create fără a-i fi specificat un factor de întindere. Când sunt așezate într-un layout widgeturile primesc un spațiu care va fi în concordanță cu proprietatea lor de sizePolicy sau mărimea minimă recomandată, în funcție de care este mai mare. Factorii de întindere sunt utilizați pentru a schimba cât spațiu primește fiecare widget.
Dacă avem 3 widgeturi care sunt puse într-un layout de tip QHBoxLayout fără însă a specifica vreun factor de întindere vom obține un layout care arată precum mai jos:

http://doc.qt.nokia.com/4.7-snapshot/images/layout1.png

Dar dacă aplicăm un factor de întindere fiecărui widget, atunci ele vor fi redimensionate proporțional cu factorul lor de întindere (dar niciodată nu vor căpăta o dimensiune mai mică decât dimensiunea minimă recomandată):