- TIE-0240x
- 6. Dynaaminen sitominen ja olioiden omistus
- 6.6 Piirtäminen Qt:ssa
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ä.
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()
jacollidesWith()
avulla. Yksinkertaisimmillaan törmäyksen tarkastaminen tarkoittaa sitä, ettäshape()
on toteutettu elementille niin, että se palauttaa elementin tarkan muodon. TällöinQGraphicsItem
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.