Liikkuva ympyrä

Tämä esimerkki on tarkoitettu avuksi tämän kierroksen projektin toteuttamista varten. Se löytyy hakemistosta examples/12/moving_circle2.

Ohjelmassa käytetään luokkaa QGraphicsScene, jonka avulla voidaan piirtää erilaisia muotoja. Tässä tapauksessa sitä käytetään ympyrän piirtämiseen, ja projektissa voit käyttää sitä esimerkiksi suorakulmioiden piirtämiseen.

Ohjelmassa on myös käytetty ajastinta, jonka avulla voi tehdä jonkin toiminnon toistuvasti (esim. kerran sekunnissa). Tässä esimerkissä ympyrä tekee aina pienen liikkeen kerrallaan, kunnes se törmää piirtoalueen reunaan.

Alla tutustutaan niihin ohjelman ominaisuuksiin, jotka ovat oleellisia projektin kannalta.

Piirtoalue ja liikkuminen

Käyttöliittymässä on widgetti graphicsView, jolle QGraphicsScene-olio asetetaan. Edelleen ympyrä lisätään QGraphicsScene-oliolle. Ympyrä liikkuu diagonaalisesti annettuihin suuntiin, jotka voivat olla oikea/vasen sekä ylös/alas. Jos ympyrä osuu liikkumisalueensa (QGraphicsScene) reunaan, sen liike pysähtyy, kunnes käyttäjä antaa sellaisen uuden suunnan, johon liikkuminen on mahdollista.

Koodissa olevien sijaintitietojen ymmärtämiseksi voit tutkia seuraavaa kuvaa.

Ohjelman vakioiden ja muuttujien havainnollistaminen

Kuvassa olevat koordinaatit tarkoittavat valkoisen suorakulmion (piirtoalueen) kulmien koordinaatteja. Kuvassa näkyviä muuttujia (top_margin ja left_margin) ei tarvita piirtämisessä, mutta kuva on sopiva paikka havainnollistaa, mitä niillä tarkoitetaan.

Ympyrää pystyy liikuttamaan myös suoraan ylöspäin (pohjoiseen) ja suoraan alaspäin (etelään). Tämä liike on toteutettu näppäinkomentojen avulla. Esimerkissä diagonaalinen liike tapahtuu automaattisesti (ajastimen avulla) ja pystysuora liike käyttäjän säätelemällä tavalla.

Näppäinkomennolla on myös mahdollista vaihtaa ympyrän väri punaisesta siniseen ja takaisin.

Painonapit vs. valintanapit

Esimerkkiohjelmassa on sekä painonappeja (push button) että valintanappeja (radio button) suunnan valitsemista varten. Valintanapit ovat tähän tarkoitukseen sopivampia. Painonapit ovat mukana, koska saatat tarvita niitä projektin toteuttamisessa. Esimerkissä tulee lisäksi esiin, miten tehty valinta vaikuttaa ohjelman toimintaan. Erityiset attribuuttien is_down_ ja is_right_ arvoja on käytetty tähän tarkoitukseen.

Huomaa, että connect-komentoja ei tarvita siihen, että nämä widgetit saadaan toimimaan yhtenäisesti. (Ohjelmassa on kuitenkin yksi connect-komento muuhin tarkoitukseen.)

Nappien käyttökelpoisuus/käyttökelvottomuus

Graafisen käyttöliittymän käyttäjänä olet huomannut, että nappulat voivat toisinaan olla sellaisessa tilassa, että et voi klikata niitä tai klikkaamisella ei ole mitään vaikutusta. Tässä esimerkissä move-nappula on käyttökelvoton (disabled), jos ympyrä liikkuu jo tai jos ympärä osuu liikkumisalueensa reunaan. Tällaisissa tapauksissa on kutsuttu funktiota setDisabled tai setEnabled. Kyseisten funktioiden kutsuja voit löytää useimmista MainWindow-luokan metodeista.

Projektissakaan kaikki toiminnot eivät ole koko ajan mahdollisia. Sellaiset widgetit kannattaa asettaa käyttökelvottomiksi, joiden määräämiä toimintoja ei voi kyseisellä hetkellä tehdä. Näppäinkomentojen tapauksessa voit tulostaa varoituksen, jos komentoa yritetään suorittaa epäsopivassa tilanteessa.

Ajastin

Esimerkkiohjelmassa käytetään ajastinta (timer) samaan tapaan kuin edellisen kierroksen harjoituksessa. Tosin luokan MainWindow rakentajassa ajastin määritellään ei-kertaluonteinen eli sarjaluonteinen (non-single-shot timer), mikä tarkoittaa, että se laukeaa kerran annetulla aikavälillä. (Tässä tapauksessa aikaväli on 1000 millisekuntia eli yksi sekunti.)

Itse asiassa ajastimen asettaminen sarjaluonteiseksi on turhaa, sillä tämä ominaisuus on oletuksena. Asiaan on kuitenkin hyvä kiinnittää huomiota, ja voit kokeilla, miten ajastimen tyypin muuttaminen vaikuttaa ympyrän liikkumiseen.

Liikkuvan ympyrän esimerkissä aikakatkaisusignaali (timeout signal) kytketään funktioon circle_move. Kyseisessä funktiossa ajastin pysäytetään tarvittaessa. Tämä onnistuu helpoimmin parametrittomilla funktioilla.