Widgeteistä¶
Edellä olevassa Colorpicker-ohjelmassa käytettiin vain QLabel
-,
QSlider
- ja QSpinBox
-widgettejä. Qt sisältää kuitenkin paljon
muitakin widgettejä. Kuten ohjelmoinnissa yleisesti, tässäkään
vaihessa ei kurssimateriaaliin ole tarkoitus koota ohjeita niiden
kaikkien käyttämiseen. Sen sijaan harjoittelemme widgettien
käyttämistä seuraavissa harjoitustehtävissä.
Niissä uutena widgettinä tulee esimerkiksi QPushButton
.
Jos aiot jatkaa ohjelmistotekniikan opiskelua tämän opintojakson jälkeenkin, kannattaa tehtävien tekemisen yhteydessä tutustua myös Qt:n dokumentaatioon widgeteistä, josta ajantasaiset tiedot kaikista kirjaston sisältämistä widgeteistä löytyvät.
Parent-child -mekanismi¶
Ensinnäkin parent-child -mekanismi ei liity periytymiseen, vaan ennemminkin muistinhallintaan. Widgetin lapsilla tarkoitetaan widgetin sisällä olevia muita widgettejä. Esimerkiksi dialogin sisällä voi olla painikkeita ja liukusäätimiä.
Parent-child -mekanismi on toteutettu luokkaan QObject
,
joten se koskee muitakin graafisia olioita, ei pelkästään widgettejä.
Kun luodaan olio, jolla on vanhempi, vanhempi lisää uuden lapsiolion
lapsilistaansa.
Kun vanhempi tuhotaan, lapsilista käydään läpi ja tuhotaan myös
kaikki listalta löytyvät lapset.
Jos lapsilla on omia lapsia, myös nämä tulee tuhottua.
Parent-child -mekanismi yksinkertaistaa muistinhallintaa, sillä se vähentää
muistivuotojen vaaraa.
Komentoa delete
tarvitsee kutsua vain niille olioille, jotka on
luotu komennolla new
ja joilla ei ole vanhempia.
Jos lapsi tuhotaan ennen vanhempaansa, Qt poistaa automaattisesti
tuhotun lapsen vanhempansa lapsilistalta.
Vanhemmalla on erityismerkitys widgeteille: lapsi-widgetit näkyvät vanhempansa alueella (sisällä). Kun vanhempi-widget tuhotaan, lapsi-widget poistetaan sekä muistista että näytöltä.
Olioiden nimeäminen Qt:ssa¶
Ohjelman käyttöliittymää on mahdollista muokata suorituksen aikana lisäämällä widgettejä pääikkunan lapsiksi. Tällaisissa tilanteissa ohjelman suorituksen aikana lisätyillä widgeteillä ei välttämättä ole muuttujanimiä. (On myös muita tilanteita, joissa widgeteillä ei ole muuttujanimiä.)
Tällaisten tilanteiden vuoksi Qt:ssa on mahdollista antaa widgeteille
nimi kutsumalla metodia setObjectName
. Tämän jälkeen widgettejä on
mahdollista hakea QObject
-olion erilaisia find
-metodeja
käyttäen.
Tällä kurssilla käytetään pääasiassa Qt Designeria, joka automaattisesti
generoi widget-olioille nimet, esimerkiksi pushButton
, pushButton_2
jne.
Qt Designerissa on kuitenkin mahdollisuus muuttaa näitä generoituja
nimiä valitsemalla changeObjectName
oikealla puolella olevasta
elementtien listasta.
Tällä opintojaksolla emme tarvitse widgeteille asetettuja nimiä muuten, mutta ohjelmien automaattinen arviointi vaatii, että widgeteillä on tietyt nimet. Tämän vuoksi joissakin tehtävänannoissa määritellään, mitkä nimet widgeteille pitää antaa.
Käyttöliittymä Qt Designerilla vs. koodina¶
Tällä opintojaksoilla widgetit on lisätty käyttöliittymään Qt Designerin kautta. Tällä tavalla on kuitenkin joitakin haittapuolia, joita aluksi tarkastellaan noppapeliesimerkin kautta. Noppapeli, jossa käyttäjä voi heittää useampaa noppaa, on tuttu edelliseltä ohjelmointikurssilta.
Kun käyttöliittymässä on nappula Roll, joka käsittelee yhtä aikaa
samalla tavalla useampia QLabel
-olioita, ja toisaalta useampi
samanlaisen toimenpiteen tekevä Keep-nappula, niin kukaan ei halua
muokata ohjelmakoodia, jossa olisi talletettuna QLabel
-olioita ja
QPushButton
-olioita erillisiin muuttujiin (noppa1
, noppa2
,
noppa3
, jne.).
Järkevintä on toteuttaa joukko samalla idealla toimivia olioita
kutsumalla widget-luokan rakentajaa toistorakenteessa, ja
tallentamalla luodut oliot johonkin sopivaan tietorakenteeseen (esim.
vector
tai map
).
Kun toteutimme Tkinter-käyttöliittymiä, tällä tavoin toimiminen oli
luontevaa, koska käyttöliittymä piti joka tapauksessa koota
kirjoittamalla Python-ohjelmakoodia. Tutustuttuamme Qt Designeriin,
saattaa käyttöliittymän kirjoittaminen C++-koodina tuntua tylsältä
vaihtoehdolta. Qt Designeria käyttäen päädytään kuitenkin
tilanteeseen, jossa meillä on joukko olioita, jotka on nimetty tyyliin
button1
, button2
, button3
, jne.
Qt Designeria käyttäessä on hyvä tietää, että layoutin avulla
asemoituihin widgeteihin päästään käsiksi Qt:n layout-olioiden metodia
itemAt
käyttäen. Tällöin voit käsitellä olioita toistorakenteessa,
kun tiedät olioiden indeksit layoutissa.
Tip
Jos layoutin tietyn osan iteroiminen on hankalaa, voit myös tallettaa mihin tahansa sopivaan STL:n säiliöön osoittimet niihin widgetteihin, joita haluat käsitellä ryhmänä (eli keskenään samalla tavalla).
Toinen haittapuoli on se, että Qt Designerilla tehdyt käyttöliittymät eivät skaalaudu oikein, kun ikkunaa suurennetaan tai pienennetään. Tämä näkyy alla olevissa kuvissa.
Jos käyttöliittymä toteutetaan koodissa, niin ui
-päätteistä
tiedostoa ei tarvita lainkaan.
Kaikki widgetit luodaan koodissa kuten mitkä tahansa muutkin oliot.
Tällaista tapaa toteuttaa graafisia käyttöliittymiä harjoitellaan
seuraavalla ohjelmointikurssilla.