Tämä kurssi on jo päättynyt.

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.

Palautusta lähetetään...