- TIE-0240x
- 10. Harjoitustyön aloitus
- 10.2 Kertaus: signaalit ja slotit
Kertaus: signaalit ja slotit¶
Tämän materiaalin kirjoittamisessa on käytetty seuraavia lähteitä:
Jos signaalit ja slotit ovat ruosteessa tai aivan uusi konsepti, niihin tutustuminen kannattaa aloittaa Ohjelmointi 2:n materiaalista Qt:n alkeista.
Signaalit ja slotit¶
Signaalit ja slotit ovat QT:n tapa toteuttaa olioiden välinen kommunikaatio. Signaali lähetetään tai "emitoidaan" kun jokin tapahtuma tapahtuu. Esimerkiksi, kun käyttöliittymässä käyttäjä painaa nappulaa (QPushButton
widget), nappula kertoo muille ohjelman widgeteille ja olioille, että sitä on painettu lähettämällä signaalin (emit clicked()
). Slot on funktio, jota kutsutaan vastauksena lähetettyyn signaaliin. Esimerkiksi, slot findClicked()
suoritetaan vastauksena napinpainallukseen.
Kaikki QObject
-luokan tai jonkun sen aliluokan aliluokat voivat sisältää signaaleja ja sloteja. Käytännössä vaaditaan kaksi asiaa, jotta signaalit ja slotit toimivat oikein. Kaikkien signaaleja ja sloteja sisältävien luokkien täytyy:
- mainita
Q_OBJECT
makro esittelynsä alussa - alla periytettyjä
QObject
sta
Oliot lähettävät signaalin kun niiden tila muuttuu tavalla, joka on mahdollisesti kiinnostavaa muille olioille. Olioiden ei tarvitse tuntea toisiaan. Itse asiassa, olion tarvitsee vain lähettää signaali. Se ei tiedä eikä välitä siitä, ottaako joku lähetetyn signaalin vastaan. Vastaavasti, slot ei tiedä, onko siihen kytketty signaaleja. Qt:n signaali ja slot -mekanismi pitää aina huolen siitä, että jos signaali on kytketty slotiin, sitä kutsutaan automaattisesti signaalin parametrein.
Yksi signaali voidaan kytkeä niin moneen slotiin kuin tarpeellista. Jos signaali on kytketty useampaan slotiin, niitä kutsutaan signaalin lähetyksen jälkeen siinä järjestyksessä, kuin missä ne on kytketty. Vastaavasti, useampi signaali voi olla kytketty samaan slotiin. Slotia kutsutaan, kun jokin signaaleista lähetetään. Signaali voi olla kytketty myös toiseen signaaliin, jolloin ensimmäisen lähettäminen aiheuttaa myös toisen lähetyksen.
Signaalit¶
Qt:n widgeteillä on valmiiksi toteutettuja signaaleita. Uusia voi määritellä luokan rajapinnan signals
osiossa.
signals:
void amount(const int count, const ObjectType type);
Signaaleja ei pidä toteuttaa. Meta-objektikääntäjä moc generoi ne automaattisesti. Signaalilla ei voi olla paluuarvoa. Se on aina void
.
Slotit¶
Slotît ovat C++ funktioita, joita voi kutsua siinä missä mitä tahansa muutakin funktiota. Slotit voivat olla myös virtuaalisia. Tämän lisäksi niillä on erityisominaisuus eli se, että niihin voidaan kytkeä signaaleja. Uusia sloteja voi määritellä luokan rajapinnan slots
osiossa.
public slots:
void setvalue( int value );
bool doAction();
Ohjelmoijan tehtävä on määritellä slotit (ne ovat C++:n funktioita). Aivan kuin funktiot, slotit voivat olla joko julkisia (public) tai yksityisiä (private).
Signaalin kytkeminen slotiin¶
Signaalit ja slotit kytketään toisiinsa funktiolla QObject::connect()
. Syntakseja on kaksi, joista suositeltavampi on ns. funktoripohjainen syntaksi:
connect( sender, &Sender::changeSignal,
receiver, &Receiver::updateSlot);
jossa sender
on osoitin QObject
olioon, joka lähettää signaalin ja receiver
on osoitin QObject
olioon, jonka slotiin signaali kytketään. Toinen ja neljäs parametri ovat signaali ja sitä vastaava slot. Suurin hyöty tästä syntaksista on käännösaikainen tyyppitarkistus ja lambdojen käyttömahdollisuus connectissa.
Toinen vaihtoehto kytkeä signaali slotiin on SIGNAL ja SLOT makrot. Tätä usein kutsutaan vanhaksi syntaksiksi.
connect( sender, SIGNAL( changeSignal(int)),
receiver, SLOT( updateSlot(int)));
jossa SIGNAL ja SLOT makrot muuttavat parametrinsa stringeiksi. Tyyppitarkistus jää ajonaikaiseksi, mutta tällä syntaksilla voi kytkeä C++ funktioita QML funktioihin.
Meta-objektijärjestelmä¶
Qt:n meta-objektijärjestelmä mahdollistaa mm. signaalit ja slotit . Se perustuu kolmeen asiaan:
# Luokka QObject
tarjoaa kantaluokan, jonka avulla oliot voivat hyödyntää meta-objektijärjestelmää
# Q_OBJECT
-makro luokan esittelyn alussa mahdollistaa meta-objektiominaisuuksien, kuten signaalien ja slotien, käytön
# Meta-Objektikääntäjä (moc) tarjoaa jokaiselle QObject
-luokan aliluokalle meta-objektiominaisuuksien tarvitseman koodin. Moc toimii seuraavasti: Se lukee C++ lähdekooditiedoston. Jos koodissa on yksi tai useampia luokkia, joiden esittelyssä on Q_OBJECT
makro, moc tuottaa uuden C++ lähdekooditiedoston, joka sisältää näillä luokille meta-objektikoodin. Tämä generoitu lähdekooditiedosto tyypillisesti käännetään ja linkataan luokan toteutukseen mukaan.
QObject
ia on mahdollista käyttää kantaluokkana ilman Q_OBJECT
-makroa ja siten ilman meta-objektikoodia. Tällöin mitkään meta-objektijärjestelmän ominaisuudet, mukaanlukien signaalit ja slotit eivät ole käytettävissä. Meta-objektijärjestelmä katsoo aliluokan, jolla meta-objektiominaisuuksia ei ole, vastaavan läheisintä edeltäjäänsä. Tämän vuoksi QObjectin
aliluokkien on hyvä sisältää Q_OBJECT
makron, vaikkei se käyttäisi signaaleja, sloteja tai muita meta-objektiominaisuuksia.