Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1.  1. Mallinna liikennevalot UML-tilakonekaaviona esim käyttäen kaavionpiirto-ohjelmaa. Voit olettaa, että tilakoneeseen tulee tapahtuma "30 sekuntia kulunut"  jolloin valoja voi vaihtaa. Voit halutessasi mallintaa myös liikennevalojen välitilat joissa keltainen valo on päällä. http://en.wikipedia.org/wiki/UML_state_machine
  2.  2. Toteuta tilakoneesi tehtävästä 1 switch-case rakenteella tai if-lauseilla. Voit käyttää koodin kirjoittamiseen esimerkiksi http://ideone.com/ -ympäristöä. Kieleksi voi valita esim. C++11
    Esimerkki tällä tavalla toteutetusta tilakoneesta löytyy sivulta Yksinkertainen Caps Lock -tilakonemalli tai osoitteesta http://en.wikipedia.org/wiki/Event-driven_finite-state_machine
  3.  3. Tee Qt Creatorissa uusi käyttöliittymäsovellus. Muunna tehtävän 2 tilakone Qt-sovellukseksi.
    - Kopioi C++-sovelluksesi tapahtumankäsittelijäfunktio mainwindow.cpp:hen MainWindown alaiseksi funktioksi.
    - Kopioi enum-määrittelysi (tilat ja tapahtumat) mainwindow.h -tiedostoon ennen class MainWindow : public QMainWindow riviä eli varsinaisen luokkamäärittelyn ulkopuolelle
    - Lisää käyttöliittymään textbrowser-ikkuna ja tulosta tilakoneen tulosteet seuraavalla addText -funktiolla cout-käskyjen sijaan. (Lisää allaoleva funktio omaan sovellukseesi, lisää funktion esittely .h -tiedostoon,  ja mukauta tarvittaessa textBrowser-elementin nimi, jos olet muuttanut sitä)

    void MainWindow::addText(QString text) {
     QString currentText=ui->textBrowser->toPlainText();
     QString newText=currentText+"\n"+text;
     ui->textBrowser->setText(newText);

    }
    - Kopioi vanhan main-funktiosi sisältö MainWindow::MainWindow(QWidget *parent) -konstruktoriin.

  4.  4. Lisää tehtävän 3 tilakoneeseesi QTimer-ajastin joka kutsuu ("tikkaa") tilakonetta säännöllisin väliajoin, esim. sekunnin välein. ks. QTimerillä toimiva Caps Lock -esimerkki. Tapahtumia on mahdollista käsitellä joka kerralla, kun tapahtumankäsittelijä käynnistyy, mikäli tapahtuma-jäsenmuuttujaan on asetettu tapahtuma.
    QTimerin käyttö edellyttää muutoksia ohjelmaan:

    - QTimer-olio lähettää signaaleja, joilla ei ole parametreja. Tämän takia tilakoneen nykyinen tila pitää välittää tapahtumankäsittelijälle toisella tapaa: Esittele tilakoneen tilaa ilmaiseva muuttuja, entisen main-funktion sijaan, mainwindow.h:ssa luokan jäsenmuuttujana. (Caps Lock -esimerkissä CapsState -tyyppinen muuttuja) Tällöin se on saatavilla kaikille luokan funktioille, ja sen arvo säilyy koko ohjelman suorituksen ajan.

    - QTimer osaa kutsua vain slot-funktioita, joten lisää mainwindow.h:hon private slots: otsikko, ja siirrä tapahtumankäsittelijän esittely sinne.

    - Myös tapahtumat välitetään tässä mallissa tilakoneelle jäsenmuuttujan avulla. (Caps Lock -esimerkissä Event-tyyppinen muuttuja)

    - Lisää enumeraatioon, jossa mahdollisten tapahtumien valikoima on määritelty, erityinen NO_EVENT -arvo, ja tilakoneeseesi tälle tapahtumalle käsittelijä, joka ei tee mitään.

    - Lisää tilakoneesi kaikkien muiden tapahtumien käsittelyihin tapahtuma-jäsenmuuttujan nollaaminen NO_EVENT -arvoon.

    - Lisää #include <QTimer> mainwindow.cpp:n alkuun jotta voit käyttää QTimer-luokkaa

    - Tee MainWindow-luokan konstruktorissa/rakentimessa QTimer-olio, joka kutsuu kasitteleTapatuma()-slotia sekunnin välein

    - Nyt voit muuttaa tilakoneen tilaa muuttamalla tapahtuma-jäsenmuuttujan arvoa ohjelman ollessa käynnissä.
    Lisää jokaista tapahtumaasi kohti yksi tapahtumanlaukaisijafunktio (slot) mainwindow.cpp:hen (ja sen esittely mainwindow.h:hon private slots: otsikon alle). Nimeä funktio kunkin tapahtuman mukaan:

    void MainWindow::keyApressed(){
        currentEvent=KEY_A_PRESSED;
    }

    Voit tämän jälkeen muuttaa tilaa esimerkiksi ajastamalla QTimer::singleShot -funktion kutsumaan ylläolevanlaista funktiota (slotia)
     QTimer::singleShot(3000,this,SLOT(keyApressed()));

    Kutsu kaikkia tapahtumanlaukaisijoitasi ajastetusti MainWindow::MainWindow-konstruktorista singleShot-kutsujen avulla. Huomaa, että singleShot laukeaa millisekunteina sen kutsumahetkestä, eli seuraava laukaisee tapthtumanlaukaisijoita sekunneilla 3,4,5,6 ja 7 koko sovelluksen käynnistyksestä:

     QTimer::singleShot(3000,this,SLOT(keyApressed()));
     QTimer::singleShot(4000,this,SLOT(capsLockPressed()));
     QTimer::singleShot(5000,this,SLOT(keyApressed()));
     QTimer::singleShot(6000,this,SLOT(capsLockPressed()));
     QTimer::singleShot(7000,this,SLOT(keyApressed()));


    Vaihtoehtoisesti voit toki lisätä sovellukseen jokaista tapahtumaa kohti painikkeita, joilla käyttäjä voi vapaasti laukoa tapahtumia silloin, kun haluaa. (Kytke tällöin painikkeiden clicked-signaalit omiin tapahtumanlaukaisijafunktioihisi, singleShotin käyttämisen sijaan.)



  5.  5. Mallinna kerrostalon hissi UML-tilakonekaaviona esim käyttäen kaavionpiirto-ohjelmaa. Sisällytä toiminnallisuuteen ainakin perustoiminnallisuus eli esim. kaikkien kerrosten painikkeet ja näytöt, jotka kertovat hissin tilasta.

...