Adatok speciális megjelenítése

Hasonló dokumentumok
Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Adatkezelés speciális eszközökkel. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése I 10. előadás. Adatbázis-kezelés modell/nézet architektúrában. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Adatbázis-kezelés modell/nézet architektúrában

Adatbáziskezelés M/V architektúrában

Elemi alkalmazások fejlesztése IV. Adatbázis-kezelő GUI alkalmazás készítése 3. Összetett tábla karbantartása

Elemi alkalmazások fejlesztése III.

Alkalmazások fejlesztése III. Qt 4 /C++ alapú MDI alkalmazás: Számlakészítő program 2/3

3. Beadandó feladat dokumentáció

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET Core) Cserép Máté

Adabáziselérés ODBC-n keresztül utasításokkal C#-ban

Elemi alkalmazások fejlesztése IV.

3. Beadandó feladat dokumentáció

MySql elindítása. Elemi alkalmazások fejlesztése IV. Feladat. Az alkalmazás adatbázisa

2. Beadandó feladat dokumentáció

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET)

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET) Cserép Máté.

INFORMATIKAI ALAPISMERETEK

Tartalomjegyzék 2. RENDSZER FELÉPÍTÉSE... 3

2. Beadandó feladat dokumentáció

Java Programozás 9. Gy: Java alapok. Adatkezelő 5.rész

Egységes és objektumközpontú adatbázis-kezelés (2. rész)

Adatbázis kezelés Delphiben. SQL lekérdezések

BME MOGI Gépészeti informatika 7.

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Adatbázis-kezelés ActiveX vezérl kkel 2.rész

az adatbevitel szabályozása, alapok

SQL*Plus. Felhasználók: SYS: rendszergazda SCOTT: demonstrációs adatbázis, táblái: EMP (dolgozó), DEPT (osztály) "közönséges" felhasználók

Bevezetés a Programozásba II 8. előadás. Polimorfizmus Giachetta Roberto

Általános szoftver architektúrák

MS ACCESS 2010 ADATBÁZIS-KEZELÉS ELMÉLET SZE INFORMATIKAI KÉPZÉS 1

A jobboldalon a pnlright egy Stacked Widget Állítsuk be az első lapot és nevezzük el pnldraw-ra:

Swing GUI készítése NetBeans IDE segítségével

A gyakorlat során az alábbi ábrán látható négy entitáshoz kapcsolódó adatbevitelt fogjuk megoldani.

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Fogalmak: Adatbázis Tábla Adatbázis sorai: Adatbázis oszlopai azonosító mező, egyedi kulcs Lekérdezések Jelentés Adattípusok: Szöveg Feljegyzés Szám

SEGÉDLET ADATKEZELÉS MS EXCEL-BEN. Tároljuk az adatokat Excel munkalapon. Megjegyzés: A feladatokat MS Office Excel ban oldottuk meg.

Programozási technológia

Változáskezelés Verzió Dátum Változás Pont Cím Oldal Kiadás: Verzió: 2.0. Oldalszám: 2 / 8

Objektumorientált programozás C# nyelven

Adatintegritás ellenőrzés Felhasználói dokumentáció verzió 2.0 Budapest, 2008.

3. Ezután a jobb oldali képernyő részen megjelenik az adatbázistábla, melynek először a rövid nevét adjuk meg, pl.: demo_tabla

Két csomag elemeiből lehet a felületet elkészíteni: awt: heavy weight komponensek; swing: light weight komponensek (időben később).

A feladatok megoldásához felhasználandó osztályok leírásait az alábbi URL-en találja meg:

Java programozási nyelv 5. rész Osztályok III.

OOP: Java 8.Gy: Abstract osztályok, interfészek

Programozás II gyakorlat. 7. Példák a polimorfizmus alkalmazásaira

Elemi alkalmazások fejlesztése III.

C# Nyelvi Elemei. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Nyelvi Elemei / 18

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Programozás II gyakorlat. 6. Polimorfizmus

Programozási nyelvek Java

Globális operátor overloading

Thermo1 Graph. Felhasználói segédlet

Webes kurzus kezelés folyamata Oktatói felületek

Könyvtári nyilvántartás

Közegek és felületek megadása

és az instanceof operátor

Táblázatos adatok használata

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Programozás I. Első ZH segédlet

Adatbázisok. 8. gyakorlat. SQL: CREATE TABLE, aktualizálás (INSERT, UPDATE, DELETE), SELECT október október 26. Adatbázisok 1 / 17

Elemi alkalmazások fejlesztése IV. Adatbáziskezel alkalmazás készítése QtDesignerben. Készítette: Szabóné Nacsa Rozália

Kilencedik témakör: Lazarus-Firebird. Készítette: Dr. Kotsis Domokos

Egyszerűbb a Google keresőbe beírni a Sharepoint Designer 2007 letöltés kulcsszavakat és az első találat erre a címre mutat.

Bizonylatok felvitele mindig a gazdasági eseménnyel kezdődik, majd ezután attól függően jelennek meg dinamikusan a további adatmezők.

3. modul - Szövegszerkesztés

Alkalmazott Modul III 6. előadás. Objektumorientált programozás: öröklődés és polimorfizmus

Választó lekérdezés létrehozása

Objektumorientált programozás C# nyelven

Elemi adatbázis kezelés

3. Osztályok II. Programozás II

Az MS Excel táblázatkezelés modul részletes tematika listája

Generikus Típusok, Kollekciók

Bevezetés a programozásba előadás: Öröklődés

CLEAN-PRECÍZ Integrált ügyviteli rendszer. T23. Excel tábla egyéni adattartalom beállítása

HVK Adminisztrátori használati útmutató

Java VII. Polimorfizmus a Java nyelvben

C#, OOP. Osztályok tervezése C#-ban

WEBFEJLESZTÉS 2. ADATBÁZIS-KEZELÉS, OSZTÁLYOK

Programozás II. ATM példa Dr. Iványi Péter

Programozás BMEKOKAA146. Dr. Bécsi Tamás 10. Előadás

Objektumorientált programozás C# nyelven

Felhasználó által definiált adattípus

JavaServer Pages (JSP) (folytatás)

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

Objektum elvű alkalmazások fejlesztése Kifejezés lengyel formára hozása és kiértékelése

A feladat lényege egy felhasználói típusnak a zsák típusnak a megvalósítása.

munkafüzet open eseményéhez

Vezérlési szerkezetek

Alkalmazások fejlesztése III. Qt 4 /C++ alapú MDI alkalmazás: Számlakészítő program 3/3

Objektumok inicializálása

Osztályok. 4. gyakorlat

AB1 ZH mintafeladatok. 6. Minősítse az állításokat! I-igaz, H-hamis

OEP Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1. Feladat. Elemzés 1

számított mező, számított tétel

A C# programozási nyelv alapjai

Objektumelvű programozás

Kivételkezelés, beágyazott osztályok. Nyolcadik gyakorlat

van neve lehetnek bemeneti paraméterei (argumentumai) lehet visszatérési értéke a függvényt úgy használjuk, hogy meghívjuk

Átírás:

Adatok speciális megjelenítése

Speciális adatmegjelenítés Az adatok csoportos megjelenítéshez a nézet számos osztályt (QListView, QTableView, QTreeView) biztosít, amelyekből származtatással továbbiakat definiálhatunk. Ezek adatmezőiben az adatelemek értékeinek megjelenési módját a delegált (QAbstractItemDelegate leszármazott) osztályok biztosítják. Az előre definiált delegált osztályok közül az alap megjelenítést a QItemDelegate, a relációk kezelését a QSqlRelationalDelegate, egyedi megjelenítést pedig a QStyledItemDelegate szolgáltatja. QAbstractItemDelegate QItemDelegate QStyledItemDelegate QSqlRelationalDelegate 2

A kiírás egyedi megjelenítése Lehetőségünk van saját delegált osztályok származtatására is, amelyekben az egyedi megjelenítési módok definiáláshoz a paint( ) metódust kell felülírnunk, mivel ez felel az adatelemek értékének kirajzolásáért. a drawdisplay művelettel rajzolhatjuk meg az adatmező felületét a drawfocus művelettel pedig erre rárajzolhatjuk a fókuszt a paint művelet paraméterben megkapja a kirajzoló objektumot (QPainter), a kirajzolási stílust (QStyleOptionViewItem), valamint a kirajzolandó adatot (QModelIndex). A stílusban megfogalmazhatunk különböző módokat (tagolás, igazítás), illetve méretet. A megjelenést táblázat esetén oszloponként is szabályozhatjuk, de hívhatjuk közvetlenül az ősosztályból örökölt műveletet, így az eredeti viselkedést is visszakaphatjuk. 3

Példa class MyDelegate : public QItemDelegate { void paint(qpainter *painter,, const QModelIndex &index) const { if (index.column() == 2) { // kettes oszlopra rajzolunk drawdisplay( ); // adat kirajzolása drawfocus( ); // fókusz kirajzolása else { // a többire az alapértelmezettet QItemDelegate::paint( ); 4

1.Feladat Módosítsuk az épületek kezelését úgy, hogy egy épület adatainak megjelenése minél beszédesebb legyen. (Ennek egyik részletét, hogy a település kód helyett a település neve látszódjon, az idegenkulcs kapcsolat alapján már megoldottuk.) Az épület tengerparttól vett távolságnak (sea_distance) megjelenítésénél vegyük hozzá az m szöveget a számhoz, illetve 1 érték esetén írjuk ki azt, hogy közvetlen. A tengerpartot jellemző egész szám (shore) helyett annak jelentését írjuk ki: homokos (0), sziklás (1), kavicsos (2), apró kavicsos (3) Az épület jellemzésére használt egész számot (features), amelynek bitjei az épület valamilyen tulajdonságának meglétét vagy hiányát kódolják, a meglevő tulajdonságok szöveges leírásainak összefűzésével jelenítjük meg. 5

Adatbázis 6

1.Feladat: tervezés BuildingDelegate QSqlRelationalDelegate + BuildingDelegate(QObject*) + paint(qpainter*, QStyleOptionViewItem&, QModelIndex&) :void {query - valuetofeatures(int) :QString {query BuildingEditorDialog QDialog - _tableview :QTableView* - _model :QSqlRelationalTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* - _submitbutton :QPushButton* - _revertbutton :QPushButton* - _cityeditordialog :CityEditorDialog* + BuildingEditorDialog(QWidget*) + ~BuildingEditorDialog() - setupmodel() :void - setupui() :void «slot» - addbutton_clicked() :void - model_beforeinsert(qsqlrecord&) :void - model_datachanged(qmodelindex&, QModelIndex&) :void - removebutton_clicked() :void - submitbutton_clicked() :void - tableview_doubleclicked(qmodelindex) :void -_cityeditordialog CityEditorDialog QDialog - _listview :QListView* - _model :QSqlTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* + CityEditorDialog(QWidget*) + ~CityEditorDialog() + setmodel(qsqltablemodel*) :void - setupmodel() :void - setupui() :void «slot» - addbutton_clicked() :void - removebutton_clicked() :void 7

1.Feladat: távolság megjelenítése BuildingDelegate::BuildingDelegate(QObject *parent) : QSqlRelationalDelegate(parent){ void BuildingDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { switch (index.column()) { kiírás módja case 4: // tengerpart távolság oszlop adat lekérdezése QString text; int shoredistance = index.data().toint(); if (shoredistance == 1)text = "közvetlen"; else text = QString::number(shoreDistance) + " m"; QStyleOptionViewItem optionviewitem = option; optionviewitem.displayalignment = Qt::AlignRight Qt::AlignVCenter; drawdisplay(painter, optionviewitem, optionviewitem.rect, text); drawfocus(painter, optionviewitem, optionviewitem.rect); kiírás break; 8

1.Feladat: part megjelenítése a szöveget egy listából kérdezzük le case 5: // tengerpart típus oszlop QString text = shorelist().at(index.data().toint()); QStyleOptionViewItem optionviewitem = option; optionviewitem.displayalignment = Qt::AlignLeft Qt::AlignVCenter; drawdisplay(painter, optionviewitem, optionviewitem.rect, text); drawfocus(painter, optionviewitem, optionviewitem.rect); break; QStringList BuildingDelegate::shoreList() const { QStringList list; list.append(trutf8("homokos")); list.append(trutf8("sziklás")); list.append(trutf8("kavicsos")); list.append(trutf8("apró kavicsos")); return list; 9

1.Feladat: jellemzők kiírása case 6: // jellemzők oszlop QString text; if (index.data().isnull() index.data().toint() == 0) { text = "nincsenek"; else { lekérdezett adatok átalakítása text = valuetofeatures(index.data().toint()); QStyleOptionViewItem optionviewitem = option; optionviewitem.displayalignment = Qt::AlignLeft Qt::AlignVCenter; drawdisplay(painter, optionviewitem, optionviewitem.rect, text); drawfocus(painter, optionviewitem, optionviewitem.rect); kiírás break; default: // különben az alapértelmezett kirajzolást végezze QSqlRelationalDelegate::paint(painter, option, index); break; 10

1.Feladat: megvalósítás parti szolgálat kert QString BuildingDelegate::valueToFeatures(int value) const { QString result; if (value % 2 == 1) result += trutf8("főút, "); if ((value >> 1) % 2 == 1) result += trutf8("parti szolgálat, "); if ((value >> 2) % 2 == 1) result += trutf8("úszómedence, "); if ((value >> 3) % 2 == 1) result += trutf8("kert, "); if ((value >> 4) % 2 == 1) result += trutf8("saját parkoló, "); if (result.size() > 0) return result.left(result.size() - 2); else főút return result; úszómedence a jellemzők lekérdezését bitenkénti eltolással oldjuk meg saját parkoló 11

A szerkesztés egyedi megjelenítése A saját, származtatott delegált osztályokkal az adatelemek értékének egy adatmezőben történő megjelenését nemcsak azok kiírási, de szerkesztési módját is egyedire szabhatjuk. a createeditor( ) művelet felelős a szerkesztőmező tetszőleges QWidget-ként való létrehozásáért, amely akkor jelenik meg az adatelem mezőjében, amikor azt szerkeszteni akarjuk a seteditordata( ) felelős azért, hogy a szerkesztőmező widgetjében a megfelelő modellbeli adat értéke jelenjen meg. a setmodeldata( ) felelős a szerkesztőmezőben történt módosítás visszaírásáért a modellbe. A szerkesztést táblázat esetén oszloponként is szabályozhatjuk, de hívhatjuk közvetlenül az ősosztályból örökölt műveletet, így az eredeti viselkedést is visszakaphatjuk. 12

2.Feladat Módosítsuk az épületek kezelését úgy, hogy a tengerpart típusát (homokos, sziklás, kavicsos, apró kavicsos) egy legördülő menü segítségével lehessen kijelölni. Vezessünk be a BuildingDelegate osztályban egy QComboBox típusú egyedi vezérlőt, amely elemeit a parttípusokat tartalmazó konstans lista (shorelist) segítségével töltjük fel. A listában az index segítségével állítjuk a parttípust, így könnyen számolható a legördülő menüben kiválasztott elem (a currentindex segítségével), valamint az adatbázisban visszaírandó érték is. 13

2.Feladat: tervezés BuildingDelegate QSqlRelationalDelegate + BuildingDelegate(QObject*) + paint(qpainter*, QStyleOptionViewItem&, QModelIndex&) :void {query + createeditor(qwidget*, QStyleOptionViewItem&, QModelIndex&) :QWidget * {query + seteditordata(qwidget*, QModelIndex&) :void {query + setmodeldata(qwidget*, QAbstractItemModel*, QModelIndex&) :void {query - shorelist() :QStringList {query - valuetofeatures(int) :QString {query BuildingEditorDialog - _tableview :QTableView* - _model :QSqlRelationalTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* - _submitbutton :QPushButton* - _revertbutton :QPushButton* - _cityeditordialog :CityEditorDialog* QDialog -_cityeditordialog CityEditorDialog QDialog - _listview :QListView* - _model :QSqlTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* + BuildingEditorDialog(QWidget*) + ~BuildingEditorDialog() + addbutton_clicked() :void + removebutton_clicked() :void + submitbutton_clicked() :void + tableview_doubleclicked(qmodelindex) :void + model_beforeinsert(qsqlrecord&) :void + model_datachanged(qmodelindex&, QModelIndex&) :void - setupmodel() :void - setupui() :void + CityEditorDialog(QWidget*) + ~CityEditorDialog() + setmodel(qsqltablemodel*) :void + addbutton_clicked() :void + removebutton_clicked() :void - setupmodel() :void - setupui() :void 14

2.Feladat: szerkesztés létrehozása QWidget* BuildingDelegate::createEditor( Qwidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.column() == 5) { // a tengerpart oszlopnál legördülő menü QComboBox *shorecombobox = new QComboBox(parent); shorecombobox->additems(shorelist()); return shorecombobox; tengerpart fajták listája else return QSqlRelationalDelegate::createEditor(parent, option, index); 15

2.Feladat: szerkesztés megjelenítése void BuildingDelegate::setEditorData( Qwidget *editor, const QModelIndex &index) const { if (index.column() == 5) { int i = index.data().toint(); QComboBox *shorecombobox = qobject_cast<qcombobox*>(editor); shorecombobox->setcurrentindex(i); szerkesztőmező elemének beállítása else QSqlRelationalDelegate::setEditorData(editor, index); 16

2.Feladat: szerkesztés mentése void BuildingDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { if (index.column() == 5) { QComboBox *shorecombobox = qobject_cast<qcombobox *>(editor); model->setdata(index, shorecombobox->currentindex ()); else QSqlRelationalDelegate::setModelData(editor, model, index); adat visszaírása a modellbe 17

3.Feladat Az eddigiek mellett oldjuk meg az épületek jellemzőinek kényelmes szerkesztését. Megjeleníteni az épületek jellemzőit azok felsorolásával már szépen tudjuk, de szerkesztésnél egy egész számot kellett beírni, amelynek 1-es bitjei utalnak a meglévő tulajdonságokra. Javítsunk az épületek jellemzőinek módosításán úgy, hogy ne egy számot kelljen beírni, hanem egy listából lehessen kiválasztani az érvényes jellemzőket. parti szolgálat kert főút saját parkoló úszómedence 18

3.Feladat: tervezés Mivel az adatbázisban továbbra is a szám lesz eltárolva, szükségünk lesz egy egyedi lista vezérlőre (FeatureEditorListWidget), amely elvégzi a szám-szöveg konverziót (setfeatures, getfeatures), biztosítja a szöveges formájú kiírást (getfeaturesstring), listaszerűen jeleníti meg az adatokat. Ezt a QListWidget vezérlőből származtatjuk, amelyben lehetőség van több elem egyidejű kijelölésére, így közvetlenül tárolhatjuk a jellemzők állapotát. Az egyedi vezérlőnket a delegált (BuildingDelegate) segítségével helyezzük a szerkezetbe. 19

3.Feladat: tervezés QListWidget FeatureEditorListWidget BuildingDelegate QSqlRelationalDelegate + FeatureEditorListWidget(QWidget*) + setfeatures(int) :void + getfeatures() :int {query + getfeaturesstring() :QString {query + BuildingDelegate(QObject*) + paint(qpainter*, QStyleOptionViewItem&, QModelIndex&) :void {query + createeditor(qwidget*, QStyleOptionViewItem&, QModelIndex&) :QWidget * {query + seteditordata(qwidget*, QModelIndex&) :void {query + setmodeldata(qwidget*, QAbstractItemModel*, QModelIndex&) :void {query - shorelist() :QStringList {query BuildingEditorDialog - _tableview :QTableView* - _model :QSqlRelationalTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* - _submitbutton :QPushButton* - _revertbutton :QPushButton* - _cityeditordialog :CityEditorDialog* QDialog -_cityeditordialog CityEditorDialog QDialog - _listview :QListView* - _model :QSqlTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* + BuildingEditorDialog(QWidget*) + ~BuildingEditorDialog() + addbutton_clicked() :void + removebutton_clicked() :void + submitbutton_clicked() :void + tableview_doubleclicked(qmodelindex) :void + model_beforeinsert(qsqlrecord&) :void + model_datachanged(qmodelindex&, QModelIndex&) :void - setupmodel() :void - setupui() :void + CityEditorDialog(QWidget*) + ~CityEditorDialog() + setmodel(qsqltablemodel*) :void + addbutton_clicked() :void + removebutton_clicked() :void - setupmodel() :void - setupui() :void 20

3.Feladat: megvalósítás FeatureEditorListWidget::FeatureEditorListWidget(QWidget *parent) : QListWidget(parent) { additem(trutf8("főút")); elemek feltöltése additem(trutf8("parti szolgálat")); additem(trutf8("úszómedence")); additem(trutf8("kert")); additem(trutf8("saját parkoló")); QString FeatureEditorListWidget::getFeaturesString() const { QString result; for (int i = 0; i < 5; i++) if (item(i)->checkstate() == Qt::Checked) result += item(i)->data(qt::displayrole).tostring() + ", "; if (result.size() > 0) return result.left(result.size() - 2); else return "nincsenek"; 21

3.Feladat: megvalósítás void FeatureEditorListWidget::setFeatures(int features) { kijelölés beállítása a bit értéke szerint for (int i = 0; i < 5; i++){ if (((features >> i) % 2 == 1)) item(i)->setcheckstate(qt::checked); else item(i)->setcheckstate(qt::unchecked); int FeatureEditorListWidget::getFeatures() const { int featuresint = 0; for (int i = 0; i < 5; i++) if (item(i)->checkstate() == Qt::Checked) featuresint += pow(2, i); return featuresint; megfelelő hatványozás a beíráshoz 22

Számított adatok megjelenítése Lehetőségünk van a modellben a tényleges adatbázisbeli tartalom mellett, vagy helyett tetszőleges számított adat megjelenítésére. Ehhez egy új, speciális modellt kell származtatnunk, amelyben felüldefiniáljuk az adatlekérdezést végző data(<index>, <szerep>) metódust, amely a pozíció (index) alapján határozza meg a megjeleníteni kívánt adatot valamint az oszlopok számát megadó columncount() metódust, amelynek általában növeljük az értéket Mindkét műveletben hívhatjuk az ősosztályból örökölt műveletet, így az eredeti viselkedést is visszakaphatjuk. 23

Adat-kezelési szerepek A data metódus szerep (role) paramétere mutatja, hogy milyen információ lekérdezése céljából hívják meg a metódust. A leggyakoribb szerepek: Qt::DisplayRole: megjelenítés céljából kért (tárolt vagy számított modellbeli) érték (amelyet tovább változtathatunk a delegáltban) Qt::EditRole: szerkesztés céljából kért (tárolt vagy számított modellbeli) érték, amely általában megegyezik a megjelenítés céljából lekérttel Qt::ToolTipRole: előugró üzenet Qt::TextAligmentRole: szövegigazítás az adathoz Qt::TextColorRole, : különböző megjelenítési beállítások, amelyek szabályozhatóak a modell szintjén, illetve a delegált szintjén is 24

4.Feladat Egészítsük ki az épületek táblát három számított oszloppal, az épületben lévő apartmanok számával, valamint az apartmanok árai közül a legkisebb és a legnagyobbal. Származtatunk a relációs modellből egy egyedi modellt (BuildingTableModel), amelyben felüldefiniáljuk az adatlekérdezést, az oszlopok számát, illetve az új sor beszúrását (az alapértelmezett érékek beszúrása végett). A három új értéket megfelelő lekérdezések segítségével hozzuk létre (pl. ár esetén az apartment és a price tábla alapján). A delegált osztályban az árak megjelenítését kiegészítjük a pénznem megjelölésével is. 25

4.Feladat: tervezés QSqlRelationalTableModel BuildingTableModel + BuildingTableModel(QObject*) + insertrow(int) :void + data(qmodelindex&, int) :QVariant {query + columncount(qmodelindex&) :int {query + onbeforeinsert(qsqlrecord&) :void + ondatachanged(qmodelindex&, QModelIndex&) :void -_model BuildingDelegate QSqlRelationalDelegate + BuildingDelegate(QObject*) + paint(qpainter*, QStyleOptionViewItem&, QModelIndex&) :void {query + createeditor(qwidget*, QStyleOptionViewItem&, QModelIndex&) :QWidget * {query + seteditordata(qwidget*, QModelIndex&) :void {query + setmodeldata(qwidget*, QAbstractItemModel*, QModelIndex&) :void {query - shorelist() :QStringList {query BuildingEditorDialog - _tableview :QTableView* - _model :BuildingTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* - _submitbutton :QPushButton* - _revertbutton :QPushButton* - _cityeditordialog :CityEditorDialog* QDialog + BuildingEditorDialog(QWidget*) + ~BuildingEditorDialog() + addbutton_clicked() :void + removebutton_clicked() :void + submitbutton_clicked() :void + tableview_doubleclicked(qmodelindex) :void - setupui() :void -_cityeditordialog CityEditorDialog QDialog - _listview :QListView* - _model :QSqlTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* + CityEditorDialog(QWidget*) + ~CityEditorDialog() + setmodel(qsqltablemodel*) :void + addbutton_clicked() :void + removebutton_clicked() :void - setupmodel() :void - setupui() :void QListWidget FeatureEditorListWidget + FeatureEditorListWidget(QWidget*) + setfeatures(int) :void + getfeatures() :int {query + getfeaturesstring() :QString {query 26

4.Feladat: megvalósítás QVariant BuildingTableModel::data(const QModelIndex &index, int role) const { if (!index.isvalid()) return QVariant(); // ha nem érvényes az index, üres adatot adunk vissza if (index.column() == 8 && ( role == Qt::DisplayRole role == Qt::EditRole)) { QSqlQuery query; query.exec( "select count(*) from apartment where building_id = " + apartmanok számának meghatározása this->data(this->index(index.row(), 0)).toString()); if (query.next()) return QVariant(query.value(0).toInt()); else return QVariant(0); 27

4.Feladat: megvalósítás else if (index.column() == 9 && ( role == Qt::DisplayRole role == Qt::EditRole)){ // minimum ár QSqlQuery query; minimum ár query.exec("select min(price) from price where apartment_id in (select id from apartment where building_id = " + this->data(this->index(index.row(), 0)).toString() + ")"); if (query.next()) return QVariant(query.value(0).toInt()); else return QVariant("?"); else if (index.column() == 10 && ( role == Qt::DisplayRole role == Qt::EditRole)) { // maximum ár QSqlQuery query; maximum ár query.exec("select max(price) from price where apartment_id in (select id from apartment where building_id = " + this->data(this->index(index.row(), 0)).toString() + ")"); if (query.next()) return QVariant(query.value(0).toInt()); else return QVariant("?"); else return QSqlRelationalTableModel::data(index, role); 28

Számított adatok szerkesztése A táblamodell nemcsak a számított adatok lekérdezését, de szerkesztését is lehetővé teszi. A setdata(<index>, <érték>, <szerep>) művelet felüldefiniálásával az adatok szerkesztését specializálhatjuk, amelyben megadhatjuk a számított adatok módosításának tényleges tevékenységét. A számított oszlopot a szerkesztés előtt szerkeszthetővé kell tenni, ehhez felül kell definiálni az oszlopok állapotjelzőit visszaadó flags(<index>) műveletet. Az adott számított oszlopnak kiválaszthatónak (ItemIsSelectable) és szerkeszthetőnek (ItemIsEditable) kell lennie. 29

5.Feladat Egészítsük ki az épületek táblát egy állapot oszloppal, amely jelöli, hogy van-e tatarozás az épületben. Az állapot normál, ha mindegyik apartman kiadható, lezárt, ha mindegyik apartman tatarozás alatt van, egyébként felújítás alatt. Lehessen állítani az értéket úgy, hogy normál, vagy lezárt állapotba tudjuk helyezni az épületet. Felveszünk egy számított oszlopot, amely az adatot az apartmanok táblából gyűjti. A megjelenítéshez egy legördülő menüt használunk, amely csak két értéket kap meg, nem mind a hármat. Felüldefiniáljuk az adatbeállítást, ahol az értékeket az apartman táblába írjuk. 30

5.Feladat: tervezés QSqlRelationalTableModel BuildingTableModel + BuildingTableModel(QObject*) + insertrow(int) :void + flags(qmodelindex&) :Qt::ItemFlags {query + columncount(qmodelindex&) :int {query + data(qmodelindex&, int) :QVariant {query + setdata(qmodelindex&, QVariant&, int) :bool + onbeforeinsert(qsqlrecord&) :void + ondatachanged(qmodelindex&, QModelIndex&) :void -_model BuildingDelegate QSqlRelationalDelegate + BuildingDelegate(QObject*) + paint(qpainter*, QStyleOptionViewItem&, QModelIndex&) :void {query + createeditor(qwidget*, QStyleOptionViewItem&, QModelIndex&) :QWidget * {query + seteditordata(qwidget*, QModelIndex&) :void {query + setmodeldata(qwidget*, QAbstractItemModel*, QModelIndex&) :void {query - shorelist() :QStringList {query BuildingEditorDialog - _tableview :QTableView* - _model :BuildingTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* - _submitbutton :QPushButton* - _revertbutton :QPushButton* - _cityeditordialog :CityEditorDialog* QDialog + BuildingEditorDialog(QWidget*) + ~BuildingEditorDialog() + addbutton_clicked() :void + removebutton_clicked() :void + submitbutton_clicked() :void + tableview_doubleclicked(qmodelindex) :void - setupui() :void -_cityeditordialog CityEditorDialog QDialog - _listview :QListView* - _model :QSqlTableModel* - _buttonbox :QDialogButtonBox* - _addbutton :QPushButton* - _removebutton :QPushButton* + CityEditorDialog(QWidget*) + ~CityEditorDialog() + setmodel(qsqltablemodel*) :void + addbutton_clicked() :void + removebutton_clicked() :void - setupmodel() :void - setupui() :void QListWidget FeatureEditorListWidget + FeatureEditorListWidget(QWidget*) + setfeatures(int) :void + getfeatures() :int {query + getfeaturesstring() :QString {query 31

5.Feladat: megvalósítás Qt::ItemFlags BuildingTableModel::flags( const QModelIndex& index) const lekérdezzük az alap { állapotjelzőt Qt::ItemFlags flag = QSqlTableModel::flags(index); if (index.column() == 4)// számított oszlop flag = Qt::ItemIsSelectable Qt::ItemIsEditable; return flag; kiválaszthatóvá is, és szerkeszthetővé is tesszük bool BuildingTableModel::setData( const QModelIndex& index, const QVariant& value, int role) { if (index.column() == 4) { if (value.toint() == 0) { apartment táblát kell módosítanunk QSqlQuery query; return (query.exec("update appartment" + "set renovation = 0 where building_id = " + this->data(this->index(index.row(),0)).tostring())); 32