QT model view Juha Järvensivu juha.jarvensivu@tut.fi 2008
Johdanto Model, View ja Delegaatit kommunikoivat singaaleista koostuvien rajapintojen avulla Malli informoi data muutoksista View informoi käyttäjän toimista (esim datan valinta) Delegaatti informoi edit statuksesta
Geneeriset tietotyypit QModelIndex Indeksi jonka avulla näkymä kysyy dataa mallilta (malli luo käytettävät indeksit) QVariant Malli ja näkymä käsittelevät dataa variant tyyppeinä
Model index Tietorakenne, jolla viitataan dataan Sisältää pointterin modeliin, joka indeksin on luonut Temporary references Näkymä ja delegaatit käsittelevät modelin dataa indeksien avulla (QModelIndex) QModelIndex indexa = model->index(0, 0, QModelIndex()); QModelIndex indexb = model->index(1, 1, QModelIndex()); QModelIndex indexc = model->index(2, 1, QModelIndex());
Persistent model index QPersistentModelIndex Käytetään QModelIndexin tilalta, jos tarvetta säilöä indeksiä pitkäksi aikaa
QVariant Model ja view käsittelevät dataa varianttyyppeinä QT:n data tyypit voidaan muuntaa varianttyyppisiksi Oletusrakentaja generoi Null-variantin QVariant v(123); int x = v.toint();
QVariant Variantti sisältää yleensä yhden arvon (esim int, string), mutta myös multivariantit ovat mahdollisia QVariantList = QList<QVariant> QVariantList vlist; QVariant v(vlist);
Metatyypin rekisteröinti Myös omia tietotyyppejä voidaan muuttaa variant muotoon, kunhan ne rekisteröidään metaobject-järjestelmään struct MyStruct { int i;... }; Q_DECLARE_METATYPE(MyStruct) MyStruct s; QVariant var; var.setvalue(s);
Datan lukeminen variantista Perustyypit voidaan muuttaa to-metodilla (esim v.toint()) Muut tyypit template metodilla int i = var.value<int>(); MyCustomStruct c; if (v.canconvert<mycustomstruct>()) { c = v.value<mycustomstruct>(v); }
QAbstractItemModel
QAbstractItemModel Standardi rajapinta, jonka kautta näkyvät käyttävät mallin dataa Esittää datan hierarkisena taulukkorakenteena Malli informoi näkymää muutoksista signal-slot mekanismin avulla QModelIndex index = model->index(row, column,...);
Read only model Toteutettava rajapinta: QModelIndex index(int r, int c, QModelIndex parent); QModelIndex parent(qmodelindex ind); Int rowcount(); Int columncount(); QVariant data(qmodelindex ind);
Editable model Toteutettava lisäksi: bool setdata(qmodelindex ind, QVariant data, int role) ItemFlags Flags(QModelIndex ind) Lisäksi tapahtuneista muutoksista tulee informoida näkymiä signaaleilla emit datachanged(qmodelindex topleft, QModelIndex bottomright)
Resizable model Toteutettava lisäksi: insertrows(int row, int count, QModelIndex parent) insertcolumns(int column, int count, QModelIndex parent) removerows(int row, int count, QModelIndex parent) removecolumns(int column, int count, QModelIndex parent)
insertrows - toteutus Ennen datan lisäämistä tulee kutsua: begininsertrows(qmodelindex parent, int first, int last) Lisäyksen jälkeen tulee kutsua: endinsertrows()
Mallin toteutus Käyttötarpeesta riippuen malli voidaan myös toteuttaa seuraavien luokkien avulla: QAbstractListModel (vain rowcount ja data) QAbstractTableModel (rowcount, columncount, data) Tai käyttää kirjaston valmista QStandardItemModel-luokkaa
QAbstractItemView
Yleistä Näkymä Toteuttaa yleisen layoutin, navigoinnin itemien välillä ja datan valinnan Delegaatti Toteuttaa yksittäisen itemin ulkoasun
QAbstractItemView Toteutettava rajapinta: QRect visualrect(qmodelindex ind); QRegion visualregionforselection(qitemselection s); Int horizontaloffset(); QModelIndex indexat(qpoint p); Bool isindexhidden(qmodelindex ind); scrollto() setselection() verticaloffset()
Delegaatti QAbstactItemView* pview; QAbstractItemDelegate pdelegate; pview->setitemdelegate(pdelegate, icolumn);
QAbstractItemDelegate Toteutettava rajapinta: void paint(qpainter p, QStyleOptionViewItem option, QModelIndex ind) QSize sizehint(qstyleoptionviewitem option, QModelIndex ind)
Role arvo Määrittelee mitä tietoa ollaan hakemassa Qt::ItemDataRole Qt::DisplayRole (näytettävä teksti) Qt::DecorationRole (ikoni) Qt::ToolTipRole (toltipteksti) Qt::StatusTipRole (status palkissa näytettävä teksti) Qt::WhatsThisRole (pikaohje) QVariant data(qmodelindex ind, int role);
Omien role-arvojen määrittäminen modeliin #define NAME_ROLE Qt::UserRole+1; #define DIRECTOR_ROLE Qt::UserRole+2; #define PRODUCER_ROLE Qt::UserRole+3; #define WRITER_ROLE Qt::UserRole+4; class CMovie { public: QString name() const; QString director() const; QString producer() const; QString writer() const ; QStringList actorlist() const; }; class CMovieModel { QList<CMovie> m_data; };
Omien role-arvojen määrittäminen modeliin QVariant CMovieModel::data(QModelIndex ind, int role) { QVariant result; if(ind.isvalid()) { switch(role) { case Qt::DisplayRole: case NAME_ROLE : result = QVariant( m_data[ind.row()].name() ); break; case WRITER_ROLE : result = QVariant( m_data[ind.row()].writer() ); break; case DIRECTOR_ROLE : result = QVariant( m_data[ind.row()].director() ); break; } } } return result;
QItemSelectionModel Pitää kirjaa valituista itemeistä Liittyy yhteen modeliin, mutta voidaan antaa usealle näkymälle
QItemSelectionModel QAbstactItemModel* pmodel; QItemSelectionModel* selectionmodel(pmodel); QAbstractItemView* pview1; pview1->setmodel(pmodel); pview1->setselectionmodel(pmodel); QAbstractItemView* pview2; pview2->setmodel(pmodel); pview2->setselectionmodel(pmodel);
Filter
Filtterit Käyttötarkoituksia: Näyttää vain osan mallin datasta käyttäjälle Järjestää datan alkuperäisestä poikkeavaan järjestykseen Toteuttaa saman rajapinnan kuin model (QAbstractItemModel)
QAbstractProxyModel Toteutettava rajapinta: QModelIndex mapfromsource(qmodelindex source) QModelIndex maptosource(qmodelindex source) Peritty QAbstractItemModel kantaluokasta
QSortFilterProxyModel QTreeView *treeview = new QTreeView; MyItemModel *sourcemodel = new MyItemModel(this); QSortFilterProxyModel *proxymodel = new QSortFilterProxyModel(this); proxymodel->setsourcemodel(sourcemodel); treeview->setmodel(proxymodel);
QSortFilterProxyModel void setfilter(qstring writer) { m_writer = writer;} bool MySortFilterProxyModel::filterAcceptsRow(int sourcerow, const QModelIndex &sourceparent) const { QModelIndex ind = sourcemodel()->index(sourcerow, 0, sourceparent); QString s = sourcemodel()->data(ind,writer_role).tostring(); } return (s == m_writer);
Lähteet Throlltech http://trolltech.com/products/qt QT Model-View programming http://doc.trolltech.com/4.3/model-viewprogramming.html