GUI-sovellus Qt:lla

Edellisellä ohjelmointikurssilla olemme jo tehneet graafisia käyttöliittymiä käyttäen Pythonin Tkinter-kirjastoa. Samoin kuin Pythonissa, C++:ssakin on useita eri kirjastoja käyttöliittymien toteuttamiseen. Tälle opintojaksolle on valittu graafisten käyttöliittymien toteuttamiseen C++:n Qt-kirjasto. (Qt on kirjasto ja Qt Creator ohjelmointiympäristö, jossa ko. kirjastoa on kätevä käyttää.)

Edellisellä ohjelmointikurssilla opimme, että kaikki käyttöliittymäkomponentit, kuten myös itse käyttöliittymäikkuna, ovat olioita. Lisäksi opimme, että graafisissa käyttöliittymissä on nk. tapahtumakäsittelijä, joka seuraa esim. hiiren klikkauksia käyttöliittymässä. Qt toimii täsmälleen samoilla periaatteilla. Siksi nyt tarvitseekin opetella vain, minkälaisia olioita Qt:ssa on valmiiksi toteutettuna ja miten niitä käytetään.

Tutustumme Qt:hen siten, että luot ensin Qt Creatorissa uuden projektin, johon Qt Creator toteuttaa pohjaksi tyhjän käyttöliittymäikkunan. Katsomme, minkälaista koodia tämä pohja sisältää. Kahdessa seuraavassa materiaaliosiossa tarkastellaan esimerkkinä harjoituksen templates/12/colorpicker_designer koodipohjaa, joka sisältää myös yksinkertaista toiminnallisuutta. (Muista kopioida koodi hakemistoon student/12/colorpicker_designer.) Qt:n tärkeimmät mekanismit selitetään näiden kahden ohjelman avulla.

Projektin luominen graafisella käyttöliittymällä

Luo uusi Qt Creator -projekti, johon tulee graafinen käyttöliittymä:

  1. Käynnistä Qt Creator kuten tavallisesti virtuaalityöpöydän yläpalkin valikosta: Applications > Programming > Qt Creator.

  2. Uuden projektin luonti lähtee käyntiin saman kaavan mukaisesti kuin aina ennenkin: File > New File or Project... tai valitsemalla New Project -nappi Qt Creatorin pääikkunasta.

  3. Tästä eteenpäin projektin muodostaminen etenee osittain eri tavoin kuin mihin on totuttu. Projektin tyypiksi valitaankin New Project -ikkunassa tällä kertaa: Applications > Qt Widgets Application (aiemminhan on aina valittu Non-Qt Project > Plain C++ Project).

  4. Valitse projektikansio totuttuun tapaan Introduction and Project Location -ikkunassa. Voit antaa projektille nimeksi vaikkapa eka_gui (tarkoituksena on tehdä vain tyhjä käyttöliittymän tähän projektiin).

  5. Tee Kit Selection normaalisti, sillä virtuaalityöpöytäkoneille ei ole käytössä muita kehitysympäristöjä kuin ehdotetut. Jos olet asentanut Qt Creatorin omalle koneellesi, tässä voi olla muitakin valintoja, toimi siinä tapauksessa kuten olet aina ennenkin toiminut.

  6. Seuraavaksi avautuu Class Information -ikkuna, joka on kaikkein merkittävin muutos aiempaan verrattuna. Suorita valinnat seuraavan kuvan mukaisesti:

    Kuvakaappaus Class Information -ikkunasta

    Huomaa, kuinka tiedostojen nimet päivittyvät automaattisesti, kun valitset käyttöliittymäluokallesi nimen kohdassa “Class name”.

  7. Project Management -ikkunassa kannattaa valita Add to Version Control -kentälle arvo “<None>”. Tämän jälkeen voit painaa Finish-nappia.

  8. Projekti on nyt luotu ja Qt Creator on muodostanut automaattisesti projektitiedoston, lähdekooditiedostojen rungot sekä .ui-päätteisen tiedoston, joka kuvaa Qt Designerissa muodostetun käyttöliittymän. Mikäli nimesit käyttöliittymäluokkasi nimellä MainWindow, kuten oli ehdotettu, Qt Creator loi tiedostot:

    main.cpp
    mainwindow.cpp
    mainwindow.hh
    mainwindow.ui
    eka_gui.pro
    

    Mutta niistä lisää hetken kuluttua.

  9. Ennen varsinaisen koodauksen aloittamista, muista käydä lisäämässä .pro-tiedostoon rivi:

    CONFIG += c++14
    

    myöhempien ongelmien välttämiseksi.

  10. Voit kääntää ja suorittaa Qt Creatorin generoiman käyttöliittymän rungon normaaliin tapaan run-nappia (vihreä kolmio) painamalla.

Ohjelma ei varsinaisesti vielä tee mitään mielenkiintoista, koska valmiiksi generoitu koodi ei sisällä muuta kuin tyhjän pääikkunan, johon ohjelmoija voi muodostaa haluamansa käyttöliittymän.

Qt:n luomat tiedostot

Tutkitaan Qt Creatorin valmiiksi luomia tiedostoja, jotta saamme käsityksen ohjelman rakenteesta yleisellä tasolla. Edetään seuraavassa järjestyksessä: main.cpp, mainwindow.hh, mainwindow.cpp ja lopuksi mainwindow.ui.

main.cpp

Tiedosto sisältää automaattisesti tuotetun koodin, joka luo MainWindow-tyyppisen olion ja käynnistää käyttöliittymän.

Niin yksinkertaisissa ohjelmissa, mitä tällä kurssilla tehdään, tiedostoa main.cpp ei ole tarpeen muokata.

Funktion viimeisellä rivillä QApplication-oliolle suoritettu exec-metodin kutsu on Qt:n tapa käynnistää tapahtumasilmukka (event loop, main loop), josta oli puhetta jo edellisellä ohjelmointikurssilla Tkinterin yhteydessä.

Muutoin pääohjelmamoduulissa ei ole mitään erityisen kiinnostavaa.

mainwindow.hh

Qt:ssä kaikki käyttöliittymäelementit on periytetty luokasta QObject, jonka julkinen rajapinta tarjoaa joitakin erittäin matalan tason työkaluja käyttöliittymäelementtien (widget) käsittelyyn (esim. käyttöliittymäelementtien keskinäinen kommunikointi signal–slot-mekanismin avulla).

Luokkahierarkia: ``QObject``, ``QWidget``, ``QMainWindow``

Riviohjelmoija päätyy harvemmin hyödyntämään QObject-luokkaa suoraan ja esimerkiksi Qt Creatorin valmiina tuottamassa koodissa se ei näy juuri ollenkaan lukuunottamatta tiedostossa mainwindow.hh olevaa Q_OBJECT-riviä, josta ei tarvitse välittää tässä ja nyt.

Luokasta QObject on periytetty luokka QWidget, joka toimii kantaluokkana kaikille Qt:n käyttöliittymäelementeille (sliderit, painonapit, valikot jne.).

Kun ohjelmoija haluaa luoda oman (yksinkertaisen) käyttöliittymän, hän toteuttaa oman luokan, joka on periytetty QMainWindow-luokasta ja lisää siihen uusia ominaisuuksia, joita toteutettavassa käyttöliittymäelementissä on oltava. Myös QMainWindow on periytetty QWidget-luokasta. Qt Creatorin tuottamasta mainwindow.hh-tiedostosta esimerkiksi näkee, kuinka tämän harjoituskerran käyttöliittymän pääikkuna on toteutettu luokkana MainWindow, joka on periytetty QMainWindow-luokasta. Ohjelmoija voi tarvittaessa muokata automaattisesti tuotettua MainWindow-luokkaa lisäämällä siihen metodeja, jäsenmuuttujia jne.

Tiedoston alussa, ennen luokan määrittelyä näkyy nimiavaruus (namespace) Ui, jonka sisällä on luokka MainWindow. (Nimiavaruuksilla voi määritellä näkyvyysalueita, mutta niiden osaamista ei vaadita tällä kurssilla.) Kun tarkoitetaan nimiavaruuden sisällä olevaa luokkaa, käytetään tarkennetta: Ui::MainWindow. Tämä on eri luokka kuin tiedostossa esiteltävä MainWindow-luokka. Luokka Ui::MainWindow sisältää attribuutteinaan ne widgetit, jotka otat käyttöön mainwindow.ui-tiedostossa. Edelleen varsinaisella MainWindow-luokalla on attribuuttinaan osoitin Ui::MainWindow-olioon, joka löytyy yksityisestä osasta tiedoston loppupuolelta (osoitin *ui). Tämän osoittimen kautta pystyt viittaamaan tarvitsemiisi widgeteihin.

mainwindow.cpp

Tämä tiedosto ei ainakaan vielä sisällä mitään erityisen jännittävää. Sieltä löytyvät mainwindow.hh-tiedostossa määritellyn luokan metodien määrittelyt.

mainwindow.ui

Tiedosto sisältää käyttöliittymän kuvauksen nk. XML-muodossa. Tätä tiedostoa ei ole tarkoitus muokata käsin. Kun tiedosto valitaan joko Projects-listalta tai projektitiedostovalikosta, Qt Creator siirtyy Designer-tilaan, jossa käyttöliittymän elementit, ulkoasu ja osa toiminnallisuudesta voidaan suunnitella hiiren avulla interaktiivisesti. Tutustumme tähän myöhemmässä materiaaliosiossa.

Jos ehdit nyt jo avata tiedoston mainwindow.ui ja siirryit Qt Designeriin, pääset takaisin tuttuun näkymään klikkaamalla vasemman reunan tummasta valikosta Edit-tilan. Edit-tilassa näet, miltä käyttöliittymän XML-kuvaus näyttää.