joi, 16 aprilie 2020

Qt - Saptamana a 9-a

Bun venit la o noua intalnire cu Qt-ul

Suntem in saptamana a 9-a, ne ocupam de capitolul al 8-lea din manualul nostru de Qt. Azi discutam un exemplu in care doua clase de obiecte din fereastra principala isi comunica una alteia o valoare prin semnale.

Va rog sa deschideti cartile la pagina 103, Cap 8, acolo unde atragem atentia asupra unor, repet UNOR, probleme care apar cand aplicatiile incep sa creasca in dimensiuni. Este adevarat, subiectul face parte, si este tratat pe larg in cursul de ingineria programarii.

Cu acest capitol doar va pun in tema cu unele probleme care apar la aplicatiile Qt, dar nu mar refer la acele incurcaturi de la compilare care se rezolvau cu Clean All , QMake , BuildAll. Despre rezolvarea lor stiti deja.

Pentru cei care nu au cartea, voi selecta paginile si va trimit un .pdf din acest capitol.

Pls. asteptati e-mail.

Incepem proiectul din Cap 8, file -> New Project ->  -> Empy Qt Project.
samd pina la Finish.

Apoi dam click pe Finish.

In Qt Creator vom adauga cele doua clase ale proiectului, una este o versiune a vechii clase LCDRange, ea va fi indicatorul care misca tunul din joc pe verticala, celalalt va fi un Widget dummy, grafic dar cu grafica nedesenata inca, careia ii testam doar mecanismul de comunicare. Clasa o vom numi cannon (sau cannonfield).
Va trebui ca atunci cand umblu la reglajul unghiului tunuletzului sa i se transmita corect acest unghi (stiti ca widget-urile LCDRange le-am facut capabile sa transmita un semnal mai departe... lectia anterioara).

Exemplul facea parte dintr-o serie (BSD licentiata) de exemple Qt 3, convertite de noi la Qt4 si apoi la Qt5.

Cam asa arata IDE -ul proiectul inainte de a incepe scrierea codului:

 Ide-ul gata de lucru:

Adaugam intai ceea ce e necesar in fiserul .pro al proiectului:


Atentie: Nu va furati caciula, daca lucrati doar pe Platforma Windows, fisierul .pro generat automat are mai putine randuri, adaugati ceea ce lipseste, altfel proiectul nu va fi portabil si veti gasi un mesaj ciudat: de ex cs lipseste clasa QApplication (de fapt lipsesc core gui widgets din Qt, din fisierul .pro).

Adaugati o sursa, care va fi main.cpp:

Apasati Next si Finish.

Adaugam acum cele doua clase ale proiectului (Bine, in teorie, cineva care e sef peste proiect are o diagrama UML a tuturor claselor proiectului, fiecare clasa are chiar si o fisa cu tot ce este in ea...etc):

De data aceasta, (de doua ori la rand), alegeti cate o Class-a C++, vezi img.
Clasele noastre sunt: LCDRange si Cannon. 
Si in final proiectul va arata cam ca in aceasta imagine:

Sa vedem ce contin clasele noastre, incepem cu clasa Cannon a tunuletelor,
si iata declaratia de clasadin fisierul cannon.h.
Este o clasa noua de obiecte derivate din QWidget, care sunt obiecte Qt cu sloturi si semnale (au macroul acela, stiti voi ... se vede de altfel).

Intrebare de control: Ce trebuia vazut aici?

Avem un constructor (cu keyword-ul explicit, ca sa nu se construiasca obiecte din ce nu ne trebuie), o informatie privata care este unghiul sub care sta tunul (ultima). doua functii pentru a face set si get unghiului si , nou, un semnal angleChanged, inventat de noi, care semnaleaza schimbarea unghiului.
Metoda int angle(...), un gett-er, este deja scrisa in declaratia clsei, restul le implementam in fisierul .cpp. 

Reglajul tunului si tunul insusi vor comunica in bucla, prin semnale, unul cu altul, astfel ca orice s-ar intampla cu unul sau cu altul, (setare, corectura de valoare) celalalt sa indice corect valoarea, a.i. ele sa ramana sincronizate. ce mai tura vura, sa arate ambele acelasi unghi, fiecare in felul sau.

Implementarea clasei:

Metoda de "interogare" a atributului angle (unghiul) fiind implementata,
adaugam in fisierul .cpp cu implementarea urmatoarele:
- constructorul, el doar pune unghiul la valoarea 45 de grade
-metoda de setare, e interesant ce face... observati ?

Intrebari de control:
a) Ce descoperiti noul la sfarsitul metodei de setare ?
b) Oare ce face repaint() ? Caror obiecte apartine ?
c) Oare ce EMITE instructiunea emit ? Acum ? Dar in general ?

Nu va dati seama ? Comentati-le in cod, cu // de ex in fata lor, si observati apoi diferenta.

Clasa, veche, LCDRange este declarata asa cum o vedeti:

Clasa LCDRange, declarata...

Intrebare de control: Puteti descrie in cuvinte din ce este alcatuita ?
Daca cineva var dicta, sau v-ati dicta dvs insiva, propriile cuvinte, (non cod, doar descrierea) ati putea rescrie declaratia clasei ?

Implementarea ei ocupa ceva mai mult loc:
Dar nu ar trebui sa fie nimic nou.

Intrebare de control: daca scriu in Qt trei stringuri succesive, pe linii succesive, fara elemente de separare intre ele, ce se intampla cu dansele?

Acum implementam programul principal, cu clasa lui de fereastra:
- Remarcati ce am in fereastra programuli principal: Trei elemente, date private
1) Butonul.
2) Afisajul
3) Tunul



- Remarcati folosirea obiectelor in constructorul clasei private:
Fiecare este instantiat (creat cu new), apoi pus la treaba. Si se fac si conexiunile:
a) cand LCDRange-ul , controlul, schimba unghiul atunci se va schimba unghiul si la tunul (cannon) propriuzis.
b) cand dintr-un motiv sau altul tunul isi schimba (singur) unghiul, acest lucru se va arata si pe afisaj.


Resize si main sunt cum le stiati...

Nota: Widget-ul grafica care este tunuletul nu este implementat complet, deocamdata nu facem decat sa verificam mecanismul care ii va transmite unghiul de pe panoul sau de control.

Altfel, daca nu am face verificarea acum, mai tarziu, cand vom implementa si partea grafica, iar tunuletul nu s eva ridica cum trebuie, la unghiul stabilit,
ei bine, atunci nu vom mai sti: i se transmite corect unghiul si grafica are o greseala sau nu i se transmite si grafica e bine implementata ?

Dar daca rulam:
Se vede imediat ca desi tunuletul nu este desenat si avem doar un print in mod grafic, in loc de un desen, unghiul se transmite corect de la afisaj la clasa cannon.

Pauza....

1)In urmatoarele doua ore,care formeaza laboratorul, sunteti invitati ca de obicei la a scrie cu mana proprie tot codul, intelegand cum este scris si gandindu-va la fiecare cuvant ce inseamna !
2) studiati si clasele de obiecte implicate, incercand sa intelegeti cum si de unde a aflat programatorul care a scris aplicatia care sunt metodele cu care sa lucreze. Un F1 (sau Fn+F1 - adica Help) dat pe fiecare nume de clasa implicata, va arata declaratia clasei.

Astept ca de obicei arhiva cu cod.



Sa aveti sarbatori pline de lumina !

Niciun comentariu:

Trimiteți un comentariu