[3] Sta posle skole - QT

[3] Sta posle skole - QT

offline
  • Srđan Tot
  • Am I evil? I am man, yes I am.
  • Pridružio: 12 Jul 2005
  • Poruke: 2483
  • Gde živiš: Ljubljana

Sadržaj
Uvod
Qt
Grafički interfejs
Opcije i grananje u CMake
Zaključak


Uvod
U C++ ne postoji neka standardna biblioteka za rad sa prozorima. Svaka platforma ima nešto svoje, većina okruženja za razvoj podržavaju to što se razvojnom timu svidelo i slično. Naravno, ne postoji ni najbolja biblioteka za rad sa prozorima... svaka ima svoje dobre i loše strane. Ako razvijate samo za jedan operativni sistem i u jednom okruženju za razvoj, tada uglavnom nema nekih velikih problema oko izbora biblioteke. Jednostavno koristite to što vam je već ponuđeno. Mi u ovom projektu imamo problem jer želimo da svako može da iskompajlira aplikaciju, želimo da podržimo što više operativnih sistema i što više alata za razvoj. Da bi rešili taj problem, moramo koristiti bbiblioteku koja podržava sve to. Jedna od biblioteka koja će nam odgovarati je Qt.

Qt
Qt nije samo biblioteka za rad sa prozorima. Qt nam omogućava i da svuda na isti način dostupamo do datoteka, da koristimo internet, da puštamo zvuk i video, da čitamo i pišemo podatke u bazu, i još dosta drugih stvari. Qt smo izabrali jer je dovoljno da samo jednom napišemo kod i taj kod će se bez ikakvih promena lepo kompajlirati i na svim popularnim desktop operativnim sistemima. U poslednje vreme, Qt polako prelazi i na mobilne uređaje što znači da ćemo uskoro moći da imamo jedan kod koji radi i na računarima i na mobilnim telefonima, tabletima i sličnim mobilnim uređajima.

Da bismo mogli da razvijamo aplikacije u Qt, moramo instalirati Qt SDK koji možete preuzeti besplatno: http://qt.nokia.com/downloads
Korisnici 32bitnog Mac OS X će morati sami da iskompajliraju ceo Qt. Kod možete preuzeti ovde: http://releases.qt-project.org/qt4/source/qt-every.....8.2.tar.gz
Korisnici Linux operativnih sistema mogu instalirati Qt preko svog package management sistema. U većini distribucija je dovoljno da instalirate qt paket (qt je već instaliran ako imate KDE okruženje).

Ako ste Qt instalirali preko Qt SDK installera, onda ste završili, a ako ste ga ručno iskompajlirali ili instalirali preko package management sistema onda je potrebno instalirati i program za uređivanje Qt koda i izgleda prozora. Taj program se zove QtCreator i možete ga preuzeti sa iste lokacije kao i SDK: http://qt.nokia.com/downloads
Linux korisnici mogu da instaliraju paket qtcreator.

Napomena za Linux korisnike koji imaju instaliran neko od GTK desktop okruženja (Gnome, Xfce, LXDE,...): Qt na vašem sistemu neće instalirati još gomilu KDE biblioteka. Kada instalirate Qt, dobijete samo Qt. Izgled Qt aplikacija se praktično neće razlikovati od GTK aplikacija jer Qt zna da koristi GTK za crtanje kada se nalazi u GTK okruženju (aplikacija će imati skin koji ste izabrali, koristiće izabrane ikonice, font će biti dobar, itd...)

Grafički interfejs
Prvo što ćemo napraviti za našu aplikaciju je izgled prozora. Izgled se snima u datoteke s ektenzijom ui, i možemo ga napraviti iz QtCreatora. Potrebno je iz menija File izabrati opciju New File or Project.... U sledećem prozoru na levoj strani treba izabrati Qt, a na desnoj Qt Designer Form. U sledećih par koraka se izabere šta želimo da napravimo (Main Window) i gde će datoteka biti snimljena. Na kraju ćemo dobiti nešto što izgleda ovako:


Samo uređivanje prozora se vrši sistemom drag&drop. Dodatne osobine svakog elementa je moguće postavljati u editoru koji se nalazi u donjem desnom delu ekrana. Ovog puta ćemo samo na brzinu proleteti kroz kreiranje prozora, a u nekim od narednih tekstova ćemo se detaljno pozabaviti tom temom.

Prvo što ćemo uraditi je brisanje menija i status bara tako što ćemo ih naći u listi u gornjem desnom uglu, kliknuti desnim klikom, i izabrati Remove. Sada imamo prazan prozor i treba nam nešto u šta će korisnik moći da upiše formulu. Za unos teksta imamo više kontrola, a nama odgovara Plain Text Edit jer omogućava unos teksta u više redova i ne nudi ništa specijalno osim toga. U listi kontrola nađemo Plain Text Edit i prevučemo je negde na gornju polovini prozora (nemojte brinuti ako kontrola izgleda premalo, to ćemo srediti kasnije). Treba nam i jedno dugme da korisnik može da zahteva izračunavanje upisanog izraza. Dugmići se po pravilu postavljaju u donji desni ugao prozora i stalo su tamo. Da bi postigli takav efekat, moraćemo da dodamo još 2 dodatne kontrole osim dugmeta. Prvo ćemo u donju polovinu prozora postaviti kontrolu Horizontal Layout. Ta kontrola se neće videti kada budemo pokrenuli aplikaciju, i služi samo da organizuje položaje kontrola koje se nalaze u njoj. Na osnovu imena zaključujemo da će sve kontrole koje stavimo u nju biti poređane horizontalno jedna pored druge. Zatim prenesemo kontrolu Push Button u kontrolu koju smo malopre kreirali. Videćete da je dugme dobilo širinu kontrole u kojoj se nalazi i da ne izgleda baš prirodno. Da bi rešili taj problem, prevući ćemo kontrolu Horizontal Spacer baš ispred dugmeta. Ta kontrola popunjava prazan prostor, a ostale kontrole uzimaju onoliko prostora koliko im zaista treba. Ostala nam je još samo jedna stvar da bi završili pravljenje izgleda, a to je da za ceo prozor kažemo da se organizuje vertikalno. To ćemo uraditi tako što ćemo selektovati prozor i u toolbaru kliknuti na dugme Lay Out Vertically. Ako ste sve odradili kako treba, videćete nešto ovako:


Pre nego što krenemo dalje, ostalo nam je još da podesimo imena kontrola i tekstova koje će prikazivati. Davanje imena kontrola nije obavezno jer Qt Creator pri kreiranju svake kontrole već postavi neko standardno ime, ali je vrlo dobra praksa da sami postavite ime jer ćete kasnije u kodu lakše naći komponentu koja vam treba po imenu. Da krenemo od početka. Kod glavnog prozora ćemo samo postaviti tekst koji se nalazi u polju windowTitle na Digitron. To je tekst koji će se pokazati na prozoru. Sledeća kontrola je polje za upis izraza. Njoj ćemo samo postaviti objectName na txtFunc. Na kraju, dugmetu ćemo promeniti objectName na btnCalc, a text na Izračunaj.

Ostalo nam je još samo da podesimo šta će se desiti kada korisnik klikne na dugme. Qt koristi sistem signala i slotova. Svaka akcija aktivira određeni signal u komponenti... primera radi, kada kliknemo na dugme aktivira se signal clicked(). Slotovi su funkcije koje se mogu pozvati u slučaju da se određeni signal desi. Možda je takav koncept na početku komplikovan (posebno ako ste do sada pravili samo konzolne aplikacije), ali će vam posle par projekata sve biti kristalno jasno. Naš trenutni cilj je da napravimo da se klikom na dugme btnCalc pokrene funkcija calculate() koju ćemo kasnije napisati u kodu za glavni prozor. Da bi smo dobili mogućnost uređivanja signala i slotova, moramo kliknuti na dugme Edit Signals/Slots u toolbaru. U ovom modu, kontrole promene boju kada pređemo mišem preko njih da bi znali čiji signal ćemo obraditi. Postavimo miša preko dugmeta, pritisnemo dugme na mišu kao da želimo da pomerimo kontrolu i pomerimo pokazivač na prazan deo prozora tako da dobijemo liniju na čijem kraju je znak za masu tj.uzemljenje. Na taj način smo otvorili editor koji nam omogućava da izaberemo za koji signal kontrole btnCalc želimo da pokrenemo koji slot glavnog prozora. Pošto editor ne zna za slotove koje ćemo kasnije dodati u kodu, moramo da mu pomognemo. Klikom na dugme Edit... na strani glavnog prozora dobijamo listu njegovih slotova i signala samogućnošću uređivanja. U delu za slotove dodamo calculate(). Po zatvaranju tog prozora se vraćamo nazad na prozor u kojem na levoj strani treba da izaberemo signal clicked(), a na desnoj slot calculate().

Time smo završili uređivanje izgleda prozora, ali priča se još uvek ne završava jer sada moramo napisati i kod koji će znati da pročita tu datoteku koju smo napravili i da od nje napravi prozor. Qt ima jednostavan sistem za automatizaciju celog procesa, i sve što moramo da odradimo je da napišemo klasu za glavni prozor, a ona će se pobrinuti za učitavanje ostalih kontrola:
class MainWindow : public QMainWindow {     Q_OBJECT     public:     explicit MainWindow(QWidget *parent = 0);     ~MainWindow(); private slots:     void calculate(); private:     Ui::MainWindow *ui;     calculator calc; }; MainWindow::MainWindow(QWidget *parent) :     QMainWindow(parent),     ui(new Ui::MainWindow) {     ui->setupUi(this); } MainWindow::~MainWindow() {     delete ui; } void MainWindow::calculate() {     QMessageBox msgBox;     calc.calculate(ui->txtFunc->toPlainText().toStdString());     if (!calc.getError().empty())         msgBox.warning(this, this->windowTitle(), QString::fromStdString(calc.getError()));     else         msgBox.warning(this, this->windowTitle(), ui->txtFunc->toPlainText() + "=" + QString::number(calc.getResult())); }
Cela "magija" za učitavanje se nalazi u toj jednoj liniji u konstruktoru. Ta linija će učitati ostale komponente i omogućiti nam dostup do njih preko promenljive ui.

U kodu smo definisali i slot calculate() koji će se pozvati na klik dugmeta. U toj funkciji vidite kako se dostupa do kontrola koje smo pre definisali (koristimo txtFunc da iz nje dobijemo tekst koji je korisnik upisao).

Ostaje nam još samo da napišemo app klasu koja će našem projektu omogućiti da otvori digitron u grafičnom okruženju:
class app { public:    int run(int argc, char *argv[]); }; int app::run(int argc, char *argv[]) {     QApplication a(argc, argv);     MainWindow w;     w.show();         return a.exec(); }
Verovatno ste primetili da smo u run metodi dodali i parametre koje ćemo proslediti iz glavnog programa. To je zato što Qt ume da na osnovu parametara promeni neke svoje unutrašnje promenljive i da radi malo drugačije, ali to za sada nije bitno. Kod je prilično jednostavan... kreira se objekat za aplikaciju, a zatim i naš glavni prozor, i zatim puštamo aplikaciju da radi sve dok je korisnik ne zatvori.

Qt, opcije i grananja u CMake
CMake ima prilično dobru podršku za Qt. Zna da koristi Qt datoteke, da kreira dodatne datoteke koje su potrebne da bi Qt aplikacija mogla da se kompajlira, zna sam da pronađe direktorijum u kojem je Qt instaliran (pod uslovom da je instaliran na standardnim lokacijama), itd.
U prethodnom tekstu smo već napravili jednu implementaciju digitrona koja je interfejs prikazivala u konzoli. Sada smo dodali još i grafički prikaz i bilo bi dobro da prilikom pripremanja projekat možemo da izaberemo koji mod želimo. CMake nam omogućava da dodamo promenljive koje se mogu menjati pre nego što se projekat napravi i mogućnost da u zavisnosti od tih opcija uključi različite datoteke u projekat.
Sledi CMakeLists.txt datoteka koja će omogućiti izbor između konzolnog ili grafičkog prikaza, i, uslučaju da je izabran grafički prikaz, postaviti sve što treba da Qt aplikacija može da se iskompajlira:
cmake_minimum_required (VERSION 2.6) project (calc) option(calc_GUI "Napravi GUI aplikaciju" FALSE) set(calc_SRCS calc.cpp calculator.cpp) if(calc_GUI)   find_package(Qt4 REQUIRED)   set(QT_USE_QTMAIN TRUE)   include(${QT_USE_FILE})   set(calc_SRCS ${calc_SRCS} app_gui.cpp mainwindow.cpp)   set(calc_UISRCS mainwindow.ui)   qt4_wrap_ui(calc_UIHDRS ${calc_UISRCS})   set(calc_MOCHDRS mainwindow.h)   qt4_wrap_cpp(calc_MOCSRCS ${calc_MOCHDRS}) else(calc_GUI)   set(calc_SRCS ${calc_SRCS} app_console.cpp) endif(calc_GUI) if(calc_GUI AND WIN32)   set(calc_APP WIN32) endif(calc_GUI AND WIN32) add_executable(calc ${calc_APP} ${calc_SRCS} ${calc_MOCSRCS} ${calc_UIHDRS}) if(calc_GUI)   target_link_libraries(calc ${QT_LIBRARIES}) endif(calc_GUI)
Komanda option nam omogućava da dodamo promenljivu čiju vrednost možemo kasnije menjati. Dodali smo promenljivu calc_GUI koja će kontrolisati da li želimo GUI aplikcaiju i njena osnovna vrednost je FALSE što znači da nećemo.
Sledeća novost je komanda set. Ona služi za postavljanje promenljivih koje ne možemo menjati. CMake dolazi sa dosta predefinisanih promenljivih o kojima ćemo govoriti kad na njih naiđemo. U našem slučaju, u promenljivu calc_SRCS dodajemo datoteke potrebne za kompajliranje projekat. Za početak smo dodali samo osnovne datoteke, a kasnije ćemo dodati i datoteke za prikaz podataka... koje datoteke će biti dodane, zavisi od vrednosti promenljive calc_SRCS.
Komande if, else, elseif i endif se koriste za grananje. Uslov koji se postavi na početku komandom if se mora koristiti kod svih ostalih komandi za grananje u tom bloku da bi CMake znao kom bloku pripadaju.
Pogledajmo sada granu koja obrađuje slučaj kada ne želimo GUI aplikaciju. U promenljivu calc_SRCS dodajemo još i datoteku za konzolnu aplikaciju i zovemo funkciju add_executable kao što smo radili i u prošlom primeru. Sve ostale promenljive koje se koriste prilikom poziva te funkcije nemaju nikakvu vrednost i ne utiču na nju.
U slučaju da želimo GUI aplikaciju, poziva se komanda find_package kojoj kažemo da želimo da koristimo Qt4 i da bez njega ne možemo dalje. U slučaju da komanda ne može da nađe Qt, kreiranje paketa će se zaustaviti i moći ćete sami da upišete gde se kod vas na računaru nalazi Qt. Kada je Qt uspešno pronađen, postavljemo promenljivu QT_USE_QTMAIN na TRUE što znači da hoćemo da se u naš program ukompajlira podrška za pokretanje programa preko main funkcije na svim sistemima (Windows, recimo zahteva da se za GUI aplikacije glavna funkcija zove WinMain). Zatim kažemo CMakeu da učita sve potrebne module za pripremu Qt paketa. U promenljivu calc_SRCS dodajemo datoteke za prikaz digitrona u grafičnom modu i onda zahtevamo od CMake da kreira sve dodatne datoteke koje su potrebne za Qt. CMake će od ui datoteke koja sadrži izgled prozora napraviti datoteku s kodom, a od koda koji sadrži signale i slotove pravi dodatne datoteke da bi C++ znao da ih iskompajlira. Pošto je za Windows potrebno na poseban način iskompajlirati program ako ne želimo da se automatski otvori konzolni prozor, postavljamo promenljivu calc_APP na WIN32 što funkciji add_executable kaže da u slučaju GUI aplikacije za WIN32 koristi taj poseban način.
Za sam kraj, pošto koristimo Qt biblioteku, moramo pozvati komandu target_link_libraries koja će povezati našu aplikaciju s Qt bibliotekom.

Da napravimo projekat na iz ove CmakeLists.txt datoteke, pozivamo sledeću komandu:
cmake -i -G "Ime vašeg kompajlera"
Ne zaboravite da možete da promenite vrednost promenljive calc_GUI... ovo je rezultat koji dobijem prilikom pripremanja paketa na Windowsu:


Sve potrebne datoteke oza ovaj projekat možete skinuti ovde: https://www.mycity.rs/must-login.png

Zaključak
Evo... krenuli smo od obične konzolne aplikacije koja je znala da sabira i oduzima 2 broja, i stigli smo do aplikacije koja zna da napravi svoj prozor, da obradi upisan izraz, izračuna njegovu vrednost i prikaže je korisniku u dialogu. Uz to smo sve tako napisali da program može da se iskompajlira na svim popularnim operativnim sistemima bez ikakve promene koda. Ako bismo razvijali ovaj projekat još dalje, mogli bismo da napravimo da se kodovi za prikaz i računanje ne kompajliraju direktno u program, nego da se koriste kao plugini, ali ćemo se ipak zaustaviti ovde Smile
To je za sada kraj, ali ako ima zainteresovanih, možemo uzeti još jedan školski projekat i pokušati da od njega napravimo nešto više. Recimo, u školi se često prave programi za pisanje i čitanje podataka iz niza. Jedan ili više dobrovoljaca bi mogli da napišu program za unos kontakata na način na koji su ih učili u školi. Program bi trebalo da omogući unos recimo imena osobe, adrese, broja telefona i e-mail adrese, trebalo bi da omogući ispis svih unetih osoba, brisanje unetih osoba. Kao bonus bi bilo fino i traženje osoba po unetim informacijama i snimanje/učitavanje podataka. Eto, kad se bude pojavio odgovor u kojem će biti kod za ovaj program, možemo da nastavimo Smile



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Pridružio: 19 Maj 2011
  • Poruke: 297

Svaka ti cast na trudu i vremenu odvojenom za sve ovo.

Nisam upoznat sa QT-om, pa imam jedno pitanje, za windows treba da skinem ovaj paket od 1.7 GB ?



offline
  • Srđan Tot
  • Am I evil? I am man, yes I am.
  • Pridružio: 12 Jul 2005
  • Poruke: 2483
  • Gde živiš: Ljubljana

Predlažem da skineš onaj od 15MB. To je samo installer u kojem možeš da izabereš šta želiš da instaliraš (ono što je selektovano "by default" je uglavnom dovoljno) i on će skinuti samo to. Uz to ćeš dobiti i najnoviju verziju svega Smile

offline
  • Na odmoru xD
  • Na odmoru xD
  • Pridružio: 15 Feb 2012
  • Poruke: 430

Svaka cast na trudu i radu Ziveli Mada meni niko nemoze pomoci kad je u pitanju c++ gui programiranje Bebee Dol Drzacu se ja Lazarus/Delphi ili visual basic.net. Mada probao sam gui programiranje c++ u visual studio i uspeo mi je neki program da saberem dva broja, pa me zanima postojili literatura na engleskom ili srpskom o tome.

offline
  • Pridružio: 26 Avg 2010
  • Poruke: 10362
  • Gde živiš: Hypnos Control Room, Tokyo Metropolitan Government Building

Aleksandr1996 ::Svaka cast na trudu i radu Ziveli Mada meni niko nemoze pomoci kad je u pitanju c++ gui programiranje Bebee Dol Drzacu se ja Lazarus/Delphi ili visual basic.net. Mada probao sam gui programiranje c++ u visual studio i uspeo mi je neki program da saberem dva broja, pa me zanima postojili literatura na engleskom ili srpskom o tome.

http://msdn.microsoft.com/en-us/library/windows/de.....85%29.aspx

offline
  • Pridružio: 19 Maj 2011
  • Poruke: 297

@Sass Drake
Ne treba mu GDI osim ako hoce da crta "rucno" svaku kontrolu ali cisto sumnjam. Ja bih predlozio ovo za pocetak:

http://www.zetcode.com/gui/winapi/

http://www.winprog.org/tutorial/

http://www.relisoft.com/Win32/index.htm

Ko je trenutno na forumu
 

Ukupno su 493 korisnika na forumu :: 43 registrovanih, 4 sakrivenih i 446 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 1567 - dana 15 Jul 2016 19:18

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: A.R.Chafee.Jr., aramis s, Areal84, atrkulja, Bane san, Boris Bosiljčić, comi_pfc, darkangel, Dorcolac, dragon986, Duh sa sekirom, ikan, ILGromovnik, indja2, ivance95, krunomiletic5, Kubovac, kulus, lakiluciano, lelemud, ljs, ljuba, Macak_u_čizmama, mean_machine, milos.cbr, miroslavtm12, misa1xx, Mixelotti, Mlav, ostoja2, panticstefan53, pavle_pzs, pein, perica5, radoznao, royst33, Snorks, Stephanos, tomigun, VP3987, xandar, Zerajic, zlatkoa987