Qt on alustariippumaton ohjelmistojen ja graafisten käyttöliittymien kehittämiseen tarkoitettu framework. Qt on alunperin norjalaisen Trolltechin tekemä käyttöliittymien ja ohjelmakoodin toteutukseen tarkoitettu työkalu. Qt:stä on ladattavissa sekä maksullinen, että ilmainen versio (LGPL versio). Molemmat voi ladata osoitteesta https://www.qt.io/download
Tämän oppaan tarkoitus on esittää HTTP-protokollan käyttö Qt-sovelluksissa. Jos Qt ohjelmointi ei ole tuttua, kannattaa aluksi tehdä sivustolla mainitut harjoitukset. Harjoitusten koodit löytyvät osoitteesta https://github.com/alaluuk/qt_tutorial.
Qt:ssa on kaksi mahdollisuutta käyttöliittymän luomiseen:
Qt Widget sovelluksissa toteutus kirjoitetaan C++ kielellä. Qt Quick sovellusten toteutukset voidaan kirjoittaa käyttäen C++:aa ja/tai JavaScriptiä.
Tämän oppaan esimerkeissä keskitytään Qt Widget sovellusten tekoon.
Qt Creator on ns. IDE (Integrated Development Environment) eli integroitu kehitysympäristö. Koodin kirjoittamista nopeuttaa, kun opettelee käyttämään editorin pikanäppäimia (quick keys). Alla muutamia hyödyllisimpiä:
Qt:n asennusohjeet löytyvät sivulta https://peatutor.com/c_kieli/qt_asennus.php
Jotta gitin käyttö ryhmässä sujuisi helpommin, kannattaa määrittää build-kansio ohjeessa https://peatutor.com/c_kieli/qt_asennus.php#build annetun mallin mukaisesti.
Kun build kansio määritellään edellisen ohjeen mukaan, Qt-Creator luo projektikansion alle kansion build, joka on kannattaa kirjoittaa .gitignore tiedostoon.
Q_OBJECT on Qt-kirjaston olennainen makro, joka tarjoaa tärkeitä ominaisuuksia C++-luokille. Se on keskeisessä roolissa, kun luodaan luokkia, jotka hyödyntävät Qt:n signal- ja slot-mekanismia, dynaamista ominaisuusjärjestelmää sekä RTTI:tä (Run-Time Type Information).
Kun luokkaan lisätään Q_OBJECT
-makro, se mahdollistaa seuraavat Qt:n tarjoamat ominaisuudet:
Q_OBJECT
mahdollistaa signaalien ja slottien käytön, jotka ovat Qt:n oma tapa käsitellä tapahtumia ja kommunikointia objektien välillä.Q_OBJECT
-makron avulla luokasta tulee metaobjekti, mikä mahdollistaa mm. luokan tyyppitietojen (kuten metodien ja ominaisuuksien) saamisen ajonaikana.
Alla on esimerkki Qt-luokasta, joka hyödyntää Q_OBJECT
-makroa:
#include <QObject>
class MyClass : public QObject {
Q_OBJECT
public:
MyClass(QObject* parent = nullptr) : QObject(parent) {}
signals:
void mySignal();
public slots:
void mySlot();
};
Tässä esimerkissä Q_OBJECT
-makro mahdollistaa MyClass
-luokan käytön signaalien ja slottien kanssa.
On tärkeää muistaa, että jos luokka sisältää Q_OBJECT
-makron, luokan tulee olla peritty QObject
-luokasta, ja sen tulee myös olla erillisenä tiedostona (esim. .cpp tai .h), jotta moc (Meta-Object Compiler) voi käsitellä sen oikein.
Signaalien ja Slottien avulla oliot voivat kommunikoida keskenään ilman perinteisiä callback-funktioita. QObject-luokan connect-funktiolla ensimmäisen olion signaali-funktio voidaan kytkeä toisen olion slot-funktioon.
Signal/Slot on ns. Observer design patternin mukainen toteutus.
Vaikket itse kirjoittaisikaan sovellukseesi signal- ja slot-funktioita, tulet varmaan käyttämään niitä. Esimerkiksi, kun lisäät sovellukseesi Buttonin ja sen klikkaukselle jonkin toiminnan, käytät signal-slot systeemiä. Kun buttonia klikataan kutsutaan signal-funktiota ja tämä funktio connectoidaan slot-funktioon, jossa määritetään mitä buttonin painallus saa aikaan.
Qt-frameworkin oliomallin parent-ominaisuus tarjoaa tehokkaan ja helpon tavan hallita olioiden elinkaarta. Jokainen QObject-pohjainen olio voi saada toisen QObject-olion parentiksi. Systeemi toimii niin, että kun parent olio tuhotaan, myös sen lapsi oliot tuhotaan automaattisesti.
Esimerkiksi sovelluksessa on ikkunat Mainwindow ja LoginForm. MainWindow:sa on painike, jolla avataan LoginForm. Painikkeen clicked tapahtumaan on kirjoitettu koodi:
LoginForm *objectLoginForm = new LoginForm(this); objectLoginForm -> show();Edellä this-osoittimella asetetaan LoginFormin parentiksi MainWindow-olio, jolloin objectLoginForm olion tuhoamisesta ei tarvitse itse huolehtia.
Qt:n MOC (Meta-Object Compiler) tiedosto on automaattisesti luotu tiedosto, joka syntyy Qt:n metaobjektijärjestelmän osana. MOC tiedosto käsittelee C++-luokkia, joissa on Qt:n tarjoamia laajennuksia, kuten signaalit, slotit ja parent-olio.
MOC:n päätehtävänä on tuottaa koodi, joka mahdollistaa Qt:n signals and slots -mekanismin, RTTI:n (Run-Time Type Information) ja dynaamiset propertyt. MOC analysoi C++-lähdekoodin ja tuottaa siitä lähdekooditiedoston, joka lisätään osaksi projektin käännösprosessia.
Tämä mekanismi on keskeinen osa Qt:n dynaamista toiminnallisuutta, ja sen ansiosta Qt voi tarjota kehittyneitä ominaisuuksia, kuten tapahtumakäsittelyä ja GUI-komponenttien kommunikointia.
Ohjelmistokehityksen maailmassa rakennusjärjestelmillä on keskeinen rooli prosessissa, jossa lähdekoodi muunnetaan suoritettaviksi ohjelmiksi. Kaksi suosittua C++-kehityksessä käytettyä rakennusjärjestelmää ovat QMAKE ja CMAKE.
QMAKE on rakennusjärjestelmätyökalu, joka on osa Qt-kehystä, ja sitä käytetään pääasiassa Qt-sovellusten rakentamiseen. Se yksinkertaistaa rakennusprosessia tuottamalla Makefile-tiedostoja projektitiedostojen (.pro-tiedostojen) perusteella. QMAKE automatisoi lähdetiedostojen, otsikkotiedostojen ja muiden resurssien käsittelyn, mikä helpottaa kehittäjiä projektien kääntämisessä eri alustoilla.
Yksi QMAKE:n vahvuuksista on sen tiivis integrointi Qt-kehykseen. Se tarjoaa ennalta määriteltyjä muuttujia ja funktioita, jotka on erityisesti suunniteltu Qt-kehitykseen, mikä mahdollistaa kehittäjille Qt:n ominaisuuksien, kuten käyttöliittymämuotojen ja käännösten, hallinnan helposti.
CMAKE on tehokas, avoimen lähdekoodin rakennusjärjestelmä, joka ei ole sidottu mihinkään tiettyyn kehykseen. Se on suunniteltu erittäin joustavaksi ja alustariippumattomaksi, ja se kykenee tuottamaan alkuperäisiä rakennustiedostoja laajalle valikoimalle käyttöjärjestelmiä ja kääntäjiä. CMAKE käyttää CMakeLists.txt-tiedostoja määritelläkseen rakennusmääritykset ja riippuvuudet.
CMAKE tunnetaan monipuolisuudestaan ja laajasta tuestaan erilaisille työkaluketjuille. Sitä voidaan käyttää projektien rakentamiseen, jotka tukeutuvat useisiin kirjastoihin ja kehyksiin, mikä tekee siitä suositun valinnan monimutkaisille projekteille, jotka vaativat monialustatukea. Lisäksi CMAKE tukee laajaa valikoimaa kolmannen osapuolen moduuleja ja laajennuksia, mikä parantaa sen ominaisuuksia entisestään.
Sekä QMAKE:lla että CMAKE:lla on omat vahvuutensa, ja ne sopivat erilaisiin käyttötapauksiin. QMAKE on ihanteellinen projekteille, jotka nojaavat vahvasti Qt-kehykseen, sillä se tarjoaa sujuvan rakennusprosessin Qt-spesifisten ominaisuuksien avulla. Toisaalta CMAKE on monipuolisempi ja sitä voidaan käyttää laajempaan valikoimaan projekteja, sillä se tarjoaa suurempaa joustavuutta ja tukea eri alustoille ja työkaluketjuille.
Kun valitaan QMAKE:n ja CMAKE:n välillä, kehittäjien tulisi harkita projektinsa erityisvaatimuksia, käyttämiään kehyksiä ja tarvetta monialustatukeen.
Yhteenvetona voidaan todeta, että sekä QMAKE että CMAKE ovat tehokkaita työkaluja, jotka voivat merkittävästi parantaa C++-projektien rakennusprosessia. Niiden erojen ja vahvuuksien ymmärtäminen voi auttaa kehittäjiä valitsemaan oikean työkalun omiin tarpeisiinsa, mikä varmistaa tehokkaamman ja sujuvamman kehitystyönkulun.