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

Kertaus: Piirtäminen Qt:ssa

Qt:n Graphics View tarjoaa mahdollisuuden hallita ja käsitellä suurta määrää ohjelmoijan määrittelemiä graafisia elementtejä. Graphics View -arkkitehtuuri koostuu skenestä (engl. scene) eli maisemasta, jota esittää QGraphicsScene -luokka sekä näkymässä olevat elementeistä (engl. item), jotka esitetään QGraphicsItem:sta periytetyillä luokilla. Maisema elementteineen tehdään käyttäjälle näkyväksi esittämällä ne QGraphicsView:n määrittämässä näkymässä (engl. view). Yksi maisema voidaan näyttää useammassa näkymässä.

modules/09/figures/scene.png

QGraphicsScene

Maiseman eli QGraphicsScene:n tehtävä on sisältää joukko graafisia elementtejä. Sen vastuulla on:

  • tarjota nopea rajapinta suuren elementtimäärän hallitsemiseen
  • välittää tapahtumat jokaiselle elementille
  • hallita elementtien tilaa (esim. valinta ja fokuksen hallinta)

Maisema toimii elementtien eli QGraphicsItem -olioiden säiliönä. Elemntin saa lisättyä maisemaan kutsumalla QGraphicsScene::addItem().

QGraphicsScene* scene = new QGraphicsScene;
QGraphicsItem* item = new QGraphicsSimpleTextItem( "hei!" );
scene->addItem( item );

Qt tarjoaa joukon valmiiksi totetettuja elementtejä kuten QGraphicsLineItem, QGraphicsPixmapItem ja QGraphicsSimpleTextItem. Omia elementtejä voi toteuttaa periyttämällä QGraphicsItemista:

class MunItem : public QGraphicsItem
{
   public:
       MunItem( QGraphicsItem *parent = nullptr);
       void paint(QPainter *painter,
                  const QStyleOptionGraphicsItem *option,
                  QWidget *widget = nullptr);
       QRectF boundingRect() const;
   private:
       ...

};

Itse toteutetuille elementeille tyypillisesti on tarve toteuttaa oma piirtofunktio paint() sekä elementin ulkoreunat suorakaiteena määrittelevä boundingRect(). Tätä käytetään määrittelemään, tarvitseeko elementti uudelleenpiirtoa. Elementeillä voi olla myös erikseen määritelty muoto shape(), mutta rajaava suorakaide on aina suorakaide.

QGraphicsView

QGraphicsView on widget joka näyttää maiseman sisällön. Näkymällä on vierityspalkit tarvittaessa. Useampi näkymä voi näyttää samaa maisemaa. Näkymä ottaa vastaan näppäimistöltä ja hiireltä tulevia tapahtumia ja muuntaa ne maiseman tapahtumiksi ja lähettää tapahtumat näytettävänä olevalle maisemalle. Seuraava koodi luo maiseman ja näkymän ja asettaa näkymän näyttämään maiseman sisältöä. Lisäksi se asettaa maiseman laajuuden:

QGraphicsScene* scene = new QGraphicsScene;
QGraphicsView* view_ = new QGraphicsView(this);
view_->setScene(scene);
scene->setSceneRect(0, 0, 600, 600);

QGraphicsItem

Kantaluokka QGraphicsItem on kaikkien maisemaan piirrettävien elementtien kantaluokka. Kuten todettua tyypillisiä muotoja varten on tarjolla valmiiksi toteutettuja elementtejä. Kantaluokasta periyttämällä voidaan kuitenkin luoda omia piirrettäviä elementtejä. QGraphicsItem mahdollistaa:

  • Hiireltä tulevien tapahtumien käsittelyn
  • Näppäimistötapahtumien käsittelyn
  • Drag and drop
  • Elementtien kokoamisen ryhmiksi joko asettamalla elementti toisen lapseksi tai käyttämällä QGraphicsItemGroup:ia. Tällainen käsittely on kätevää, kun useita elementtejä halutaan käsitellä yhtenä.
  • Törmäyksen havaitseminen funktioiden shape() ja collidesWith() avulla. Yksinkertaisimmillaan törmäyksen tarkastaminen tarkoittaa sitä, että shape() on toteutettu elementille niin, että se palauttaa elementin tarkan muodon. Tällöin QGraphicsItem hoitaa törmäystarkistukset.

Koordinaattijärjestelmä

Graphics View perustuu karteesiseen koordinaattijärjestelmään. Elementin paikka maisemassa määrittyy sen X- ja Y-koordinaattien mukaan. Qt:n koordinaattijärjestelmän mukaisesti X-akseli kasvaa vasemmalta oikealle ja Y-akseli ylhäältä alas. Näin ollen alkupiste eli 0,0 sijaitsee vasemmassa yläkulmassa.

Käytännössä koordinaattijärjestelmiä on kolme eli jokaiselle osalle omansa. Käytössä on siten: elementtikoordinaatit, maisemakoordinaatit, näkymäkoordinaatit. Näkymäkoordinaatit ovat QGraphicsView:n koordinaatteja. Maisemakoordinaatit ovat maiseman sisällä olevien elementtien paikan määrittäviä koordinaatteja. Jokaiselle elementillä on myös omat koordinaattinsa, jossa 0,0 sijaitsee keskellä elementtiä. Elementtikoordinaateilla on merkitystä omia elementtejä luotaessa, sillä esimerkiksi hiiren klikkaustapahtumien sijainti määritellään niiden avulla. Myös elementin ulkoreunan määräävä suorakaide ja muoto määritellään elementtikoordinaateilla.

Maisema määrittää koordinaattijärjestelmän kaikille maisemassa sijaitseville elementeille. Se kuvaa jokaisen ylimmän tason elementin sijainnin ja luo perustan kaikkien maisemassa tapahtuvien tapahtumien välittämiselle elementeille. Jokaiselle maiseman elementillä on sijainti maisemassa sekä elementtiä rajaava suorakaide eli scenePos(), sceneBoundingRect(). Nämä kuvaavat elementin sijainnin maisemakoordinaateissa sekä alueen, jonka avulla päätellään, mitkä maiseman alueet ovat muuttuneet.

Näkymäkoordinaatit ovat näkymä-widgetin koordiinaatteja.Näytettävissä oleva maisema ei vaikuta tähän koordinaatistoon. Vasen yläkulma on aina 0,0 ja oikea alakulma on aina leveys, korkeus. Kaikki hiireltä tulevat tapahtumat sekä drag&drop-tapahtumat otetaan vastaan näkymäkoordinaateissa ja ne tarvitsee muuntaa maisemaan, jotta elementtien kanssa voidaan toimia.

Palautusta lähetetään...