Elemi alkalmazások fejlesztése IV. Adatbáziskezelő alkalmazás készítése C++/Qt ben I.

Hasonló dokumentumok
Elemi alkalmazások fejlesztése IV.

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

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

Elemi alkalmazások fejlesztése III

Elemi alkalmazások fejlesztése III

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

Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Adatbázis-kezelés elemi eszközökkel. A MySQL adatbázis-kezelő

A gyakorlat során MySQL adatbázis szerver és a böngészőben futó phpmyadmin használata javasolt. A gyakorlat során a következőket fogjuk gyakorolni:

Eseményvezérelt alkalmazások fejlesztése I 7. előadás. Adatbázis-kezelés elemi eszközökkel. Giachetta Roberto

Elemi alkalmazások fejlesztése III. A Qt assistant elindítása. Ajánlott ir odalom. A Qt assistant nyitó ablaka

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

Tartalomjegyzék. Tartalomjegyzék 1. Az SQL nyelv 1 Az SQL DDL alapjai 2

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

Elemi alkalmazások fejlesztése III.

Elemi alkalmazások fejlesztése III.

Adatbázisok* tulajdonságai

SQL ALAPOK. Bevezetés A MYSQL szintaxisa Táblák, adatok kezelésének alapjai

8. Gyakorlat SQL. DDL (Data Definition Language) adatdefiníciós nyelv utasításai:

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

Elemi alkalmazások fejlesztése III

Adatbázis rendszerek SQL nyomkövetés

Adatbázis Rendszerek II. 5. PLSQL Csomagok 16/1B IT MAN

Elemi alkalmazások fejlesztése III. SDI alkalmazás készítése Qt-ben I.

Elemi adatbázis kezelés

Adatbázis-kezelés ODBC-vel

Elemi alkalmazások fejlesztése III.

Adatbázis Rendszerek II. 8. Gyakorló környezet

Adatbázis-kezelés API hívásokkal. Adatbázis-kezelés ODBC-vel. Adatbázis-kezelés SQL parancsokkal. Adatbázis-kezelés ODBC-vel.

Készítette: Szabóné Nacsa Rozália

Adatbázisok webalkalmazásokban

Alkalmazások fejlesztése III. Qt 4 /C++ alapú grafikus alkalmazás Bevezetés I.

Adatbázis-kezelés ODBC driverrel

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

CREATE TABLE student ( id int NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name varchar(100) NOT NULL, address varchar(100) NOT NULL )

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

Elemi alkalmazások fejlesztése I.

Adatbázis-lekérdezés. Az SQL nyelv. Makány György

Java és web programozás

Gyakorlás: Hozzunk létre egy Alkalmazottak táblát AZO szám, Részleg szöveg, Munkakör szöveg és BelépésDátuma dátum típussal.

Az SQL*Plus használata

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

OO PDO. Tehát PDO használatával, könnyen átállhatunk egy másik adatbáziskezelőre, anélkül hogy a kódot teljes egészében újraírnánk.

SQL PÉLDATÁR. készült a PTE TTK Iskolai informatika III. kurzus teljesítésére

A relációs adatbáziskezelés szabványos nyelve Két fő csoportba sorolhatók az utasításai

Java és web programozás

Adatbázis-kezelés. Harmadik előadás

SQL jogosultság-kezelés. Privilégiumok Grant és Revoke Grant Diagrammok

Elemi alkalmazások fejlesztése III.

LBRA6i integrált rendszer

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

Adatbáziskezelés php-ben MySQL adatbáziskezelı rendszert használva

Adatbázis Rendszerek II. 1. SQL programozási felületek 39/1B IT MAN

Adatbázis Rendszerek II. 2. Gyakorló környezet

3. Osztályok II. Programozás II

Felhasználói segédlet a Scopus adatbázis használatához

PHP-MySQL. Adatbázisok gyakorlat

Adatbázis Rendszerek I. 10. SQL alapok (DML esettanulmány)

Elemi alkalmazások fejlesztése IV.

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

A gyakorlat során MySQL adatbázis szerver és a böngészőben futó phpmyadmin használata javasolt. A gyakorlat során a következőket fogjuk gyakorolni:

Adatbázisok. 9. gyakorlat SQL: SELECT október október 26. Adatbázisok 1 / 14

munkafüzet open eseményéhez

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

ADATBÁZIS-KEZELÉS - BEVEZETŐ - Tarcsi Ádám, ade@inf.elte.hu

Téradatbázisok használata QGIS-ből A DB kezelő modul 2.2 verzió

A lista eleme. mutató rész. adat rész. Listaelem létrehozása. Node Deklarálás. Létrehozás. Az elemet nekünk kell bef zni a listába

Az SQL nyelv Structured Query Language (Struktúrált lekérdező nyelv)

Excel ODBC-ADO API. Tevékenységpontok: - DBMS telepítés. - ODBC driver telepítése. - DSN létrehozatala. -Excel-ben ADO bevonása

Dr. Pál László, Sapientia EMTE, Csíkszereda WEB PROGRAMOZÁS 4.ELŐADÁS. Adatbázis alapú alkalmazások készítése PHP-ben

Vizuális programozás gyakorlat

Táblakezelés: Open SQL Internal table. Tarcsi Ádám: Az SAP programozása 1.

Java programozási nyelv 11. rész Adatbázis-programozás

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

B I T M A N B I v: T M A N

Megtanuljuk, hogyan lehet egy web-alkalmazással adatbázishoz csatlakozni Pontosan megnézzük a PHP lehetőségeit o MySQL-hez o Oracle-höz

ADATBÁZISOK gyakorlat: SQL 2. rész SELECT

Hozzunk létre két rekordot a táblában, majd véglegesítsünk (commit):

Adattípusok. Max. 2GByte

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

Adattípusok. Max. 2GByte

Bevezetés: az SQL-be

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

Elemi alkalmazások fejlesztése III

QLabel *label = new Qlabel("Hello Qt!",0);

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

Felhasználói segédlet a Scopus adatbázis használatához

Adatbázis Rendszerek I. 9. SQL alapok (DDL esettanulmány)

ADATBÁZISKEZELÉS ADATBÁZIS

Felhasználói segédlet a Web of Knowledge / Web of Science adatbázis használatához

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

Adatbázisok II. rész

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

Tervezőeszközök, fejlesztőeszközök használata Qt alapú alkalmazásoknál. Saját vezérlő használata tervezőben (worldclocks)

Access adatbázis elérése OLE DB-n keresztül

Budapest, március. ELTE Informatikai Kar

Adatbázis Rendszerek II. 2. Ea: Gyakorló környezet

Egyetemi könyvtári nyilvántartó rendszer

Thermo1 Graph. Felhasználói segédlet

Adatbázis használata PHP-ből

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

Átírás:

Tartalomjegyzék Adatbáziskezelő alkalmazás készítése C++/Qt ben I...3 A MySQL adatbáziskezelő használatba vétele...3 Az alkalmazás adatbázisa...4 A Qt/Sql modul...5 Az adatbázis és az alkalmazás összekapcsolása...5 A QsqlQuery osztály...5 Rekordok listázása: DiakQuery (gyakorló feladat)...6 Új projekt létrehozása...6 A projekt elemei:...6 src.pro...6 connection.cpp...6 main.cpp...7 Fordítás/Futtatás...7 A QSqlCursor osztály...8 Rekordok listázása: DiakCursor (gyakorló feladat)...8 A projekt felépítése:...8 main.cpp...8 Fordítás/futtatás...8 Rekord módosítása: DiakUpdate (gyakorló feladat)...9 main.cpp...9 Fordítás/Futtatás...10 Rekord törlése: DiakDelete (gyakorló feladat)...10 main.cpp...10 Fordítás/Futtatás...11 Rekord beszúrása: DiakInsert (gyakorló feladat)...11 main.cpp...11 Fordítás/Futtatás...11 Rendezés: DiakOrder (gyakorló feladat)...11 main.cpp...12 Fordítás/Futtatás...12 A QDataTable osztály...12 Tábla karbantartása: DiakDataTable (gyakorló feladat)...12 A projekt felépítése:...13 main.cpp...13 Fordítás/futtatás...13 Feladat: EafAdmin projekt...14 Az alkalmazás menüpontjai...14 src.pro...15 Az EafAdmin osztály...15 eafadmin.h...15 eafadmin.cpp...17 A főprogram: main.cpp...20 Fordítás/Futtatás...21 Az adatbázis kapcsolat megvalósítása...21 1. oldal

A főprogram kiegészítése az adatbázis kapcsolattal...21 src.pro...21 main.cpp (módosítás)...21 A diak táblát karbantartó programrész megvalósítása (Táblák/Diák menüpont)...22 A diak_id (sorszám) automatikus kiosztása...22 A DiakDataTable osztály elkészítése...23 src.pro...23 diakdattable.h...23 diakdattable.cpp...23 A slottabladiak() módosítása (eafadmin.cpp)...24 Fordítás/Futtatás...24 Ellenőrzött adatbevitel biztosítása...25 diakdattable.h (módosítás)...25 diakdattable.cpp (módosítás)...25 Szabóné Nacsa Rozália email: nacsa@inf.elte.hu honlap: people.inf.elte.hu/nacsa 2004. október A munkafüzet programjai letölthetők a people.inf.elte.hu/nacsa/eaf4/projects címről. 2. oldal

Adatbáziskezelő alkalmazás készítése C++/Qt-ben I. Ebben a munkafüzetben feltételezzük, hogy Ön ismeri az EAF projekt specifikációját. A MySQL adatbáziskezelő használatba vétele Az alkalmazás elkészítéséhez rendelkeznünk kell egy adatbáziskezelővel, és futnia kell egy, az adatbáziskezelőt kiszolgáló szervernek. Ebben a munkafüzetben a MySQL adatbáziskezelőt használjuk. A MySQL adatbáziskezelő és kapcsolódó dokumentumai letölthetők a www.mysql.com weboldalról, vagy installálás után megtekinthetők a /usr/share/doc/mysql_xxxx alkönyvtárban. Az alábbi rövid ismertető csak ízelítőt ad a MySQL használatához, munkafüzet révén nem vállalja fel a MySQL részletekbe menő ismertetését. A MySQL adatbáziskezelőt a MySQL programcsomagok letöltése után, a szuper user módban kiadott /usr/bin/mysql_install_db paranccsal installálhatjuk Az adatbázis használatához futnia kell az MySQL szervernek. A szervert a szuper user módban kiadott safe_mysqld (SuSE 9.1 ben mysqld_safe) paranccsal indíthatjuk el. Ha a szerver nem indul el, akkor nézze meg, jó e a /var/lib/mysql könyvtár és a benne található fájlok jogosultsága. (Group: Read/Write, User: mysql, Group: mysql legyen a beállítás) shell> su Password: jelszó begépelése shell> /usr/bin/safe_mysqld & [1] 11444 shell> Starting mysqld daemon with databases from /var/lib/mysq l shell> exit exit shell> Az adatbáziskezelő szolgáltatásait csak az arra jogosult regisztrált felhasználók vehetik igénybe. Felhasználók regisztrálásához szuper user módban kell lennünk. Új felhasználó regisztrálása történhet például a GRANT utasítás segítségével az alábbiak szerint: shell> mysql --user=root mysql mysql> GRANT ALL PRIVILEGES ON *.* TO hallgato@localhost -> IDENTIFIED BY 'hallgató_jelszava' WITH GRANT OPTION; mysql> GRANT ALL PRIVILEGES ON *.* TO hallgato @"%" -> IDENTIFIED BY 'hallgató_jelszava ' WITH GRANT OPTION; A fenti regisztrációval bejegyeztünk egy szuper jogokkal rendelkező hallgato felhasználót, aki az adatbáziskezelő szolgáltatásait a 'hallgató_jelszava' jelszó megadásával veheti igénybe. (Részletesebb leírást talál a /usr/share/doc/mysql... alkönyvtárban fellelhető dokumentáció Adding New Users to MySQL fejezetében (4.3.5), melynek feldolgozását önálló munkára ajánljuk.) Regisztrált felhasználó terminálról az alábbi parancsokkal veheti igénybe az adatbáziskezelő szolgáltatásait. shell>/usr/bin/mysql -u hallgato -p shell>hallgato_jelszava mysql> Valamilyen mysql parancs, pontosvesszovel lezárva 3. oldal

Az alkalmazás adatbázisa Az alkalmazás a projekt specifikációban megismert eaf adatbázist kezeli. A minta adatbázist a feladatspecifikációnak megfelelően az alábbi Sql parancsokkal hoztuk létre. create database eaf; use eaf; create table felev (felev_id int(4) not null unique, szam int(4) not null, kezdet varchar(20) not null, fsz int(4), max int(4), primary key (szam,kezdet)); create table csoport (csoport_id int(4) not null primary key, nev varchar(20), max int(4), gyakvez_id int(4), felev_id int(4)); create table gyakvez (gyakvez_id int(4) not null primary key, nev varchar(30)); create table diak (diak_id int(4) not null primary key, azon varchar(20) unique, nev varchar(30)); create table tag (diak_id int(4) not null, csoport_id int(4) not null, pont1 int(4), pont2 int(4), pont3 int(4), pont4 int(4), primary key (diak_id, csoport_id)); create table zh (zh_id int(4) not null primary key, max int(4), ido varchar(20), felev_id int(4)); create table potzh (potzh_id int(4) not null primary key, max int(4), ido varchar(20), felev_id int(4)); create table jelentkezes (zh_id int(4) not null, diak_id int(4) not null, eredm int(1), primary key (zh_id,diak_id)); create table kezdet (kezdet_id int(4) not null primary key, kezdet varchar(20)); insert into kezdet (kezdet_id,kezdet) values (1,"2001/2002-1"); insert into kezdet (kezdet_id,kezdet) values (2,"2001/2002-2"); insert into kezdet (kezdet_id,kezdet) values (3,"2002/2003-1"); insert into kezdet (kezdet_id,kezdet) values (4,"2002/2003-2"); insert into kezdet (kezdet_id,kezdet) values (5,"2003/2004-1"); insert into kezdet (kezdet_id,kezdet) values (6,"2003/2004-2"); create table sequence (tablename varchar(10) not null primary key, sequence int(4)); insert into sequence (tablename,sequence) values ("felev",0); insert into sequence (tablename,sequence) values ("csoport",0); insert into sequence (tablename,sequence) values ("gyakvez",0); insert into sequence (tablename,sequence) values ("diak",0); insert into sequence (tablename,sequence) values ("zh",0); insert into sequence (tablename,sequence) values ("potzh",0); Az egyes táblákban szereplő azonosítóknak (táblanév_id) egyedieknek kell lennie. A sequence táblában tartjuk nyilván, hogy az általunk kezelt táblában éppen hol tartunk a számok kiosztásában. A kezdet tábla tartalmazza azokat a féléveket, amelyekkel egyáltalán dolgozni szeretnénk. Ezt a táblát azért vezettük be, hogy az adott félév különböző szintű féléveinek (EAF1,..., EAF4) bevitelekor ne kelljen minden alkalommal begépelni a félévet azonosító, meglehetősen hosszú karaktersorozatot. 4. oldal

A Qt/Sql modul A Qt installálásakor számos modul alapértelmezésben beépül a könyvtárunkba. Ezen hasznos modulok egyike az adatbáziskezelést támogató Sql modul. A Qt/Sql modulban az alábbi osztályok találhatók: QSql, QSqlDriverPlugin, QSqlFieldInfo, QSqlQuery, QSqlCursor, QSqlEditorFactory, QSqlForm, QSqlRecord, QSqlDatabase, QSqlError, QSqlIndex, QSqlRecordInfo, QSqlDriver, QSqlField, QSqlPropertyMap, QSqlResult. Az itt felsorolt osztályok közül számunkra a legfontosabbak a felhasználói felületet kezelő Sql osztályok (User Interface Layer), valamint az adatbázis elérését biztosító osztályok (SQL API Layer). A felhasználói felületet kezelő Sql osztályok: QSqlEditorFactory, QSqlForm, QSqlPropertyMap, QDataTable, QDataBrowser, QDataView Az adatbázis elérését biztosító Sql osztályok: QSqlDataBase, QSqlCursor, QSqlQuery, QSqlError, QSqlField, QSqlFieldInfo, QSqlIndex, QSqlRecord, QSqlRecordInfo A QSqlQuery osztályban közvetlen SQL parancsokat adhatunk ki, a QSqlCursor osztály maga építi fel az Sql parancsokat az egyes beállításoknak megfelelően. Az adatbázis és az alkalmazás összekapcsolása Alkalmazásunkban az adatbázis kezelése előtt kapcsolatot kell kiépíteni az alkalmazás és az adatbázis között. A kapcsolat kiépítése három lépésből áll: 1. az adatbázist kezelő meghajtó (driver) aktivizálása (adddatabase) 2. a kapcsolat adatainak beállítása (setdatabasename, setusername, setpassword, sethostname) 3. a kapcsolat megnyitása (open) A QsqlQuery osztály A QSqlQuery osztályban közvetlenül adhatunk ki tiszta Sql parancsokat. A QSqlQuery osztály rendelkezik olyan függvényekkel, amelyekkel kiadhatunk lekérdező parancsokat, bejárhatjuk a lekérdezés eredményét (next, prev, first, last, seek), lekérdezhetjük az eredmény adatait (value). Lekérdezéskor kiadhatunk adatkezelő utasításokat ( pl. SELECT, INSERT, UPDATE és DELETE), de végrehajthatunk adat definiáló utasításokat is ( pl. CREATE TABLE ). Ha az Sql utasítás végrehajtása sikeres, akkor az adott QSqlQuery példány állapota active ( az isactive() függvény visszatérési értéke TRUE), egyébként az adott QSqlQuery példány állapota inactive ( az isactive() függvény visszatérési értéke FALSE). Minden egyes Sql utasítás végrehajtása után, az adatok kiolvasása előtt rá kell pozicionálnunk egy érvényes rekordra (az isvalid() függvénynek TRUE értéket kell visszaadnia). A lekérdezésre kapott válasz rekordjai között az alábbi függvények segítségével navigálhatunk: next(), prev(), first(), last(), seek(int) Ha a lekérdezés active, és érvényes rekordra mutat, akkor az adatot a value() függvénnyel olvashatjuk ki a rekordból. Minden Sql adat QVariant típusú, ezért olvasásnál/írásnál végre kell hajtanunk a megfelelő típus konverziókat. A QSqlQuery használatához szükségünk van a qsqlquery.h header fájlra. Keresse meg az SQL modul és a QSqlQuery osztály részletes leírását a Qt súgójában! 5. oldal

Rekordok listázása: DiakQuery (gyakorló feladat) Gyakorló feladat: Készítsünk egy nagyon egyszerű alkalmazást, amely megjeleníti az adatbázisunk diak tábláját. A feladatot a QSqlQuery osztály segítségével oldjuk meg. Új projekt létrehozása Hozzunk létre egy üres KDevelop/Qt/C++ projektet 1. Ha az Ön által használt fejlesztőeszközben nincs ilyen lehetőség, akkor készítsen el egy tetszőleges Qt alapú projektet, és törölje a projekt automatikusan generált.h és.cpp fájljait. Ezzel létrehozunk egy olyan környezet, amelybe már beilleszthetjük a saját forrásainkat. (Az EAF3 SDI alkalmazás készítése Qt ben I. munkafüzetének végén talál egy másik technikát is egy alkalmazás projekt összeállítására.) A projekt elemei: src.pro main.cpp connection.h connection.cpp src.pro SOURCES += diakquery.cpp \ connection.cpp HEADERS += connection.h TEMPLATE = app CONFIG += release \ warn_on \ thread \ qt TARGET =../bin/diakquery //A Kdevelop3 által készített projekt leíró fájl Az src.pro projekt leíró fájlt a Kdevelop3 hozza létre és tartalmát a projekt alakítgatása során automatikusan aktualizálja. connection.h #define DB_SOURCE_DRIVER "QMYSQL3" #define DB_SOURCE_DBNAME "eaf" #define DB_SOURCE_USER "nacsa" #define DB_SOURCE_PASSWD "1234" #define DB_SOURCE_HOST "localhost" bool createconnections(); connection.cpp #include <qsqldatabase.h> #include "connection.h" 1 KDevelop2: Project/New/Qt/Qt SDI KDevelop3: Project/New/C++/QMake project/application 6. oldal

bool createconnections() QSqlDatabase *source = QSqlDatabase::addDatabase( DB_SOURCE_DRIVER); source >setdatabasename( DB_SOURCE_DBNAME ); source >setusername( DB_SOURCE_USER ); source >setpassword( DB_SOURCE_PASSWD ); source >sethostname( DB_SOURCE_HOST ); if (! source >open() ) qwarning( "Az adatbázist nem sikerült megnyitni: " + source >lasterror().drivertext() ); qwarning( source >lasterror().databasetext() ); return FALSE; return TRUE; A kapcsolatot a createconnections() metódussal valósítjuk meg. Először aktivizáljuk a meghajtót, azaz meghívjuk a QSqlDatabase::addDatabase() metódusát, melynek átadjuk a használni kívánt meghajtó nevét (QMYSQL3). Utána megadjuk az adatbázis nevét (setdatabasename), a felhasználó nevét (setusername) és jelszavát (setpassword), valamint a host nevet (sethostname). Befejezésül megnyitjuk az adatbázist (open()). main.cpp #include <qapplication.h> #include <qsqldatabase.h> #include <qsqlquery.h> #include "connection.h int main( int argc, char *argv[] ) QApplication app( argc, argv, FALSE ); if ( createconnections() ) QSqlQuery query( "SELECT nev, azon FROM diak;"); if ( query.isactive() ) while ( query.next() ) qdebug(query.value(0).tostring() + ": " + query.value(1).tostring() ); return 0; Az adatbázis kapcsolat kiépítése után (creteconnections()) létrehozzuk a QSqlQuery osztály egy példányát (query). Már a példányt létrehozó kunstruktorban megadjuk a végrehajtandó Sql parancsot (SELECT...). Ha a lekérdezés sikeres volt (query.isactive() == TRUE), akkor rendre rápozicionálunk az eredmény egyes rekordjaira (query.next()), és a value() függvényt használva, a szükséges konverzió után megjelenítjük a lekérdezett rekordok megfelelő adatait (query.value(0), query.value(1)) a debug ablakban. Fordítás/Futtatás Vigyen fel néhány rekordot a diák táblába és kísérletezzen egy kicsit az Sql lekérdezésekkel. Az eredmény listát az stderr ablakban találja meg. 7. oldal

A forrás letölthető a people.inf.elte.hu/nacsa/eaf4/projects/diakquery címről. A QSqlCursor osztály A QSqlCursor osztály magasabb szintű hozzáférést biztosít az Sql tábláinkhoz, mint a QSqlQuery osztály, ezért amikor a QSqlCursor osztályt használjuk elvileg nem kell ismernünk az Sql utasításokat. A QSqlCursor osztályban egyszerre mindig csak egy rekorddal foglalatoskodhatunk. Csak egyetlen egy rekordra adhatunk ki Insert, Delete vagy Update utasítást. Használat előtt az adatbázis kapcsolatot a QSqlQuery hez hasonlóan itt is ki kell építenünk. A QSqlCursor használatához szükségünk van a qsqlcursor.h header fájlra. Keresse meg a QSqlCursor osztály részletes leírását a Qt súgójában! Rekordok listázása: DiakCursor (gyakorló feladat) Gyakorló feladat: Készítsünk egy nagyon egyszerű alkalmazást, amely megjeleníti az adatbázisunk diak tábláját. A feladatot a QSqlCursor osztály segítségével oldjuk meg. A projekt felépítése: main.cpp main.cpp connection.h (ugyanaz, mint a DiakQuery példában) connection.cpp ( ugyanaz, mint a DiakQuery példában ) #include <qapplication.h> #include <qsqldatabase.h> #include <qsqlcursor.h> #include "connection.h" int main( int argc, char *argv[] ) QApplication app( argc, argv ); if ( createconnections() ) QSqlCursor cur( "diak"); cur.select(); //cur.select("diak.nev LIKE 'K%'"); while ( cur.next() ) qdebug( cur.value( "nev" ).tostring() + ": " + cur.value( "azon" ).tostring() ); return 0; Az adatbázis kapcsolat kiépítése után (creteconnections()) létrehozzuk a diák táblánkat reprezentáló QSqlCursor osztály egy példányát (cur). A cur.next() metódus segítségével végigmegyünk a diak tábla egyes rekordjain, megjelenítjük a diák nevét és azonosítóját. Vegyük észre, hogy itt az adatokra a mező nevével (nem pedig indexszel) hivatkozunk. 8. oldal

Fordítás/futtatás Vigyen fel néhány rekordot a diák táblába, és kísérletezzen egy kicsit az Sql lekérdezésekkel. A forrásprogram letölthető a people.inf.elte.hu/nacsa/eaf4/projects/diakcursor címről. Rekord módosítása: DiakUpdate (gyakorló feladat) A QSqlCursor osztályt használva ha az osztály által reprezentált tábla rendelkezik a rekordjait egyértelműen megkülönböztető elsődleges kulccsal automatikusan beszúrhatunk (insert), törölhetünk (delete), vagy módosíthatunk(update) egy egy rekordot. (Ha a táblázat rekordjait nem tudjuk kulccsal egyértelműen megkülönböztetni, akkor csak a QSqlQuery osztályt tudjuk használni.) Minden egyes QSqlCursor típusú objektumnak van egy saját segéd puffere, melyet a szerkesztő műveletek (insert, update and delete) használnak. A szerkesztés során először lekérdezzük a megfelelő pufferre mutató pointert, kitöltjük a pufferben az egyes mezőket, majd meghívjuk a szükséges metódusokat (insert(), delete(), update()). A program működését a szerkesztés különböző fázisaiban (primeinsert(); beforeupdate(); stb.) kibocsátásra kerülő szignálokhoz rendelt slotokkal befolyásolhatjuk. A primeinsert(), primeupdate(), primedelete() függvények amellett, hogy visszaadják a belső segéd pufferük címét, a segéd puffer mezőit a műveletnek megfelelő kezdőértékkel is feltöltik. A primeinsert() kinullázza a mezőket, a primeupdate() kitölti az aktuális rekord adataival, a primedelete() pedig az elsődleges kulcs mezőt tölti ki az aktuális rekord adatai alapján. Gyakorló feladat: A diak tábla egy rekordjának módosítása. Tekintsük a következő táblát! mysql> select * from diak; diak_id azon nev 1 KPETE Kiss Péter 2 NPETE Nagy Péter 3 NKATA Nagy Katalin 3 rows in set (0.04 sec) Cseréljük ki az 1 es azonosítójú Kiss Péter nevét Kovács Péterre. (A projekt ugyanaz, mint az előző példában, csak a main.cpp változik.) main.cpp int main( int argc, char *argv[] ) QApplication app( argc, argv ); if ( createconnections() ) QSqlCursor cur( "diak"); cur.select("diak_id=1"); if (cur.next()) QSqlRecord *buffer = cur.primeupdate(); buffer >setvalue( "nev", "Kovács Péter"); cur.update(); 9. oldal

return 0; Az adatbázis kapcsolat kiépítése után (createconnections()) létrehozzuk a diak táblánkat reprezentáló QSqlCursor osztály egy példányát (cur), majd az adatbázisbeli táblából kiválasztjuk az 1 es azonosítójú diákot (cur.select("diak_id=1")). Ezután rápozicionálunk a kiválasztott rekordra (cur.next()), lekérjük az update segéd puffer címét (QSqlRecord *buffer = cur.primeupdate()), majd a kívánt értékek beállítása után (setvalue()), a segéd puffer tartalma alapján módosítjuk az adatbázisbeli táblát (update()). (Vegyük észre, hogy a primeinser() az aktuális rekord alapján kitölti a segéd puffer (buffer) egyes mezőit, így csak a módosítandó értéket kell beállítanunk.) Fordítás/Futtatás A forrásprogram letölthető a people.inf.elte.hu/nacsa/eaf4/projects/diakupdate címről. Rekord törlése: DiakDelete (gyakorló feladat) Gyakorló feladat: A diak tábla egy rekordjának törlése. Tekintsük a következő táblát! mysql> select * from diak; diak_id azon nev 1 KPETE Kovács Péter 2 NPETE Nagy Péter 3 NKATA Nagy Katalin 3 rows in set (0.04 sec) Töröljük ki az 2 es azonosítójú rekordot. (A projekt ugyanaz, mint az előző példában, csak a main.cpp változik.) main.cpp int main( int argc, char *argv[] ) QApplication app( argc, argv ); if ( createconnections() ) QSqlCursor cur( "diak"); cur.select("diak_id=2"); if (cur.next()) cur.primedelete(); cur.del(); return 0; 10. oldal

Az adatbázis kapcsolat kiépítése után (createconnections()) létrehozzuk a diak táblánkat reprezentáló QSqlCursor osztály egy példányát (cur), majd az adatbázisbeli táblából kiválasztjuk az 2 es azonosítójú diákot (cur.select("diak_id=2")). Ezután rápozicionálunk a kiválasztott rekordra (cur.next()), majd a kitöltjük a segéd pufferben az elsődleges kulcs értékét (cur.primedelete()), és meghívjuk a QSqlCursor::del() metódust.(vegyük észre, hogy a törlő parancs (del) kiadása előtt a primedelete() hívással töltöttük ki a segéd puffer (buffer) elsődleges kulcsát az aktuális rekord alapján.) Fordítás/Futtatás A forrásprogram letölthető a people.inf.elte.hu/nacsa/eaf4/projects/diakdelete címről. Rekord beszúrása: DiakInsert (gyakorló feladat) Gyakorló feladat: Egy rekord beszúrása a diak táblába. Tekintsük a következő táblát! mysql> select * from diak; diak_id azon nev 1 KPETE Kovács Péter 3 NKATA Nagy Katalin 2 rows in set (0.00 sec) Szúrjunk be 2 es diak_id vel egy új diákot a táblába Kiss Katalin néven. (A projekt ugyanaz, mint az előző példában, csak a main.cpp változik.) main.cpp int main( int argc, char *argv[] ) QApplication app( argc, argv ); if ( createconnections() ) QSqlCursor cur( "diak"); QSqlRecord *buffer = cur.primeinsert(); buffer >setvalue( "diak_id", 2); buffer >setvalue( "azon", "KKATA"); buffer >setvalue( "nev", "Kiss Katalin"); cur.insert(); return 0; Az adatbázis kapcsolat kiépítése után (createconnections()) létrehozzuk a diak táblánkat reprezentáló QSqlCursor osztály egy példányát (cur), majd az adatbázisbeli táblából kiválasztjuk az 2 es azonosítójú diákot (cur.select("diak_id=2")). Ezután lekérjük a segéd puffer címét (primeinsert()), kitöltjük az egyes mezőket, majd beszúrjuk a rekordot az adat táblába. (Vegyük észre, hogy a primeinsert() kinullázza a segéd puffer (buffer) mezőit!) 11. oldal

Fordítás/Futtatás A forrásprogram letölthető a people.inf.elte.hu/nacsa/eaf4/projects/diakinsert címről. Rendezés: DiakOrder (gyakorló feladat) Gyakorló feladat: A diak tábla rendezett megjelenítése. Tekintsük a következő táblát! mysql> select * from diak; diak_id azon nev 1 KPETE Kovács Péter 2 NPETE Nagy Péter 3 NKATA Nagy Katalin 3 rows in set (0.17 sec) Listázzuk ki név mező szerint, és azon belül az azon mező szerint növekvő sorrendbe rendezve a diak tábla rekordjait. (A projekt ugyanaz, mint az előző példában, csak a main.cpp változik.) main.cpp Fordítás/Futtatás int main( int argc, char *argv[] ) QApplication app( argc, argv ); if ( createconnections() ) QSqlCursor cur( "diak"); QStringList orderfields = QStringList() << "nev" << "azon"; QSqlIndex order = cur.index(orderfields); cur.select(order); while (cur.next()) qdebug(cur.value("nev").tostring() + " ( " + cur.value("azon").tostring() + " )"); return 0; A forrásprogram letölthető a people.inf.elte.hu/nacsa/eaf4/projects/diakorder címről. A QDataTable osztály A QDataTable osztállyal kényelmesen karbantarthatjuk egy QSqlCursor objektummal reprezentált táblázatot. Ehhez az adatbázisbeli táblánkat (diak) hozzárendeljük egy QSqlCursor objektumhoz, majd a QSqlCursor objektumunkat hozzárendeljük egy QDataTable objektumhoz. A hozzárendelések után automatikusan kiadhatjuk a legalapvetőbb adatbáziskezelő műveleteket (insert, update, delete). A QDataTable használatához szükségünk van a qdatatable.h header fájlra. 12. oldal

Keresse meg a QDataTable osztály részletes leírását a Qt súgójában! Tábla karbantartása: DiakDataTable (gyakorló feladat) Gyakorló feladat: Készítsünk egy egyszerű alkalmazást, amellyel megoldhatjuk a diak tábla karbantartását (Beszúrás, Törlés, Módosítás). A feladatot a QDataTable osztály alkalmazásával oldjuk meg. A projekt felépítése: main.cpp main.cpp connection.h (ugyanaz, mint a DiakQuery példában) connection.cpp ( ugyanaz, mint a DiakQuery példában ) #include <qapplication.h> #include <qsqldatabase.h> #include <qsqlcursor.h> #include <qdatatable.h> #include "connection.h" int main( int argc, char *argv[] ) QApplication app( argc, argv ); if ( createconnections() ) QSqlCursor diakcursor( "diak"); QDataTable *diaktable = new QDataTable(&diakCursor, TRUE); app.setmainwidget(diaktable); //diakcursor.setmode( QSqlCursor::ReadOnly ); diaktable >refresh(); diaktable >show(); return app.exec(); return 0; Az adatbázis kapcsolat kiépítése után (creteconnections()) létrehozzuk a diák táblánkat reprezentáló QSqlCursor osztály egy példányát (diakcursor) úgy, hogy már létrehozásnál megadjuk annak a táblának a nevét, amelyet ezzel a diakcursor ral reprezentálunk. Ezután létrehozunk egy QDataTable típusú objektumot diaktable néven, a létrehozás pillanatában megadva, hogy ezzel a táblázattal a diakcursor által reprezentált ( diak ) táblát szeretnénk kezelni. A QdataTable konstruktorának második TRUE paramétere azt jelzi, hogy a táblázat oszlopait az adatbázisbeli tábla alapján kell elkészíteni. A diaktable vezérlőelemet nevezzük ki mainwidget nek. A refesh() függvénnyel feltöltjük a táblázatot, majd azonnal meg is jelenítjük azt. (show()). Fordítás/futtatás Az alkalmazást futtatva figyelje meg a QDataTable szolgáltatásait. Vegye észre, hogy a numerikus típusú mezők alapértelmezésben számláló mezőben szerkeszthetők. Nézze meg, mi történik, ha létező kulccsal (diak_id) szeretne bevinni rekordot. Figyelje meg, mikor kerül be az új rekord az adatbázisba. Keresse meg a Qt súgójában a setmode() függvényt, és próbálja meg változtatgatni az adatkezelés módját. Figyelje meg, mi történik? 13. oldal

A forrásprogram letölthető a people.inf.elte.hu/nacsa/eaf4/projects/diakdatatable címről. Ennyi bevezetés után bátran megpróbálkozhatunk a félév elején ismertetett projekt egy részének elkészítésével. Feladat: EafAdmin projekt Készítsünk adminisztrációs programot az Elemi alkalmazások fejlesztése tárgyhoz. A program elkészítéséhez használja a Qt grafikus fejlesztőeszközt, valamint a MySQL adatbáziskezelőt. Az alkalmazás menüpontjai Menü File Táblák Jelentkezés Értékelés Kimutatás View Help Almenük Exit Diák, Gyakorlatvezető, Félév, Csoport, Zárthelyi, Pótzárthelyi Csoportba, Zárthelyire, Pótzárthelyire Beadandó, Zárthelyi Diák Toolbar, Statusbar About 14. oldal

A projekt felépítése main.cpp eafadmin.cpp eafadmin.h src.pro //A Kdevelop3 projekt leíró fájlja src.pro Ez a projekt leíró fájl Kdevelp 3 esetén automatikusan létrejön. Az EafAdmin osztály TEMPLATE = app CONFIG += release \ warn_on \ thread \ qt TARGET =../bin/eafadmin SOURCES += eafadmin.cpp \ main.cpp \ connection.cpp HEADERS += eafadmin.h \ connection.h IMAGES += jelentkezescsoport.png \ jelentkezespotzh.png \ jelentkezeszh.png \ tablacsoport.png \ tabladiak.png A főablak létrehozásáról részletesebb ismertetőt talál az SDI alkalmazás készítése Qt ben I. munkafüzetben. eafadmin.h #ifndef EAFADMIN_H #define EAFADMIN_H // A QT fejléc fájljai #include <qapp.h> #include <qmainwindow.h> #include <qaction.h> #include <qmenubar.h> #include <qpopupmenu.h> #include <qtoolbar.h> #include <qtoolbutton.h> #include <qstatusbar.h> #include <qwhatsthis.h> #include <qstring.h> #include <qpixmap.h> #include <qmsgbox.h> 15. oldal

class EafAdmin : public QMainWindow Q_OBJECT public: EafAdmin(); ~EafAdmin(); void initactions(); void initmenubar(); void inittoolbar(); void initstatusbar(); bool queryexit(); public slots: /** File menu */ void slotfilequit(); /** Table menu */ void slottabladiak(); void slottablagyakvez(); void slottablafelev(); void slottablacsoport(); void slottablazh(); void slottablapotzh(); /** Jelentkezes menu */ void slotjelentkezescsoport(); void slotjelentkezeszh(); void slotjelentkezespotzh(); /** Ertekeles menu */ void slotertekelesbeadando(); void slotertekeleszh(); /** Kimutatas menu */ void slotkimutatasdiak(); /** toggle the toolbar*/ void slotviewtoolbar(bool toggle); /** toggle the statusbar*/ void slotviewstatusbar(bool toggle); /** shows an about dlg*/ void slothelpabout(); 16. oldal

private: QPopupMenu *filemenu; QPopupMenu *helpmenu; QPopupMenu *viewmenu; QPopupMenu *tablamenu; QPopupMenu *jelentkezesmenu; QPopupMenu *ertekelesmenu; QPopupMenu *kimutatasmenu; QToolBar *toolbar; QAction *filequit; QAction *viewtoolbar; QAction *viewstatusbar; QAction *helpaboutapp; QAction *tabladiak; QAction *tablagyakvez; QAction *tablafelev; QAction *tablacsoport; QAction *tablazh; QAction *tablapotzh; QAction *jelentkezescsoport; QAction *jelentkezeszh; QAction *jelentkezespotzh; QAction *ertekelesbeadando; QAction *ertekeleszh; QAction *kimutatasdiak; ; #endif eafadmin.cpp #include <qaccel.h> #include "eafadmin.h" EafAdmin::EafAdmin() : QMainWindow( 0, "EafAdmin", WDestructiveClose ) setcaption(tr(qstring::fromutf8("elemi Alkalmazások fejlesztése "))); initactions(); initmenubar(); inittoolbar(); initstatusbar(); 17. oldal

viewtoolbar >seton(true); viewstatusbar >seton(true); void EafAdmin::initActions() /** File Menu */ filequit = new QAction(tr("Exit"), tr("e&xit"), QAccel::stringToKey(tr("Ctrl+Q")), this); filequit >setstatustip(tr("quits the application")); filequit >setwhatsthis(tr("exit\n\nquits the application")); connect(filequit, SIGNAL(activated()), this, SLOT(slotFileQuit())); /** Tabla Menu */ tabladiak = new QAction(tr(QString::fromUtf8("Diák")), tr(qstring::fromutf8("&diák")), QAccel::stringToKey(tr("Ctrl+D")), this); tabladiak >seticonset( QIconSet( QPixmap::fromMimeSource( "./images/tabladiak.png" ) ) ); tabladiak >setstatustip(tr(qstring::fromutf8("diák tábla karbantartása"))); tabladiak >setwhatsthis(tr(qstring::fromutf8("diák tábla karbantartása"))); connect(tabladiak, SIGNAL(activated()), this, SLOT(slotTablaDiak()));... //A többi kód letölthető a people.inf.elte.hu/efa4/projects/eafadmin1 címről /** Help Menu */ helpaboutapp = new QAction(tr("About"), tr("&about..."), 0, this); helpaboutapp >setstatustip(tr("about the application")); helpaboutapp >setwhatsthis(tr("about\n\nabout the application")); connect(helpaboutapp, SIGNAL(activated()), this, SLOT(slotHelpAbout())); void EafAdmin::initMenuBar() // menubar entry filemenu filemenu=new QPopupMenu(); filequit >addto(filemenu); // menubar entry tablamenu tablamenu=new QPopupMenu(); tabladiak >addto(tablamenu); tablagyakvez >addto(tablamenu); tablafelev >addto(tablamenu); tablacsoport >addto(tablamenu); tablazh >addto(tablamenu); // menubar entry viewmenu viewmenu=new QPopupMenu(); viewmenu >setcheckable(true); viewtoolbar >addto(viewmenu); viewstatusbar >addto(viewmenu); 18. oldal

// menubar entry helpmenu helpmenu=new QPopupMenu(); helpaboutapp >addto(helpmenu); // MENUBAR CONFIGURATION menubar() >insertitem(tr(qstring::fromutf8("&file")), filemenu); menubar() >insertitem(tr(qstring::fromutf8("&táblák")), tablamenu); menubar() >insertitem(tr(qstring::fromutf8("&jelentkezés")), jelentkezesmenu); menubar() >insertitem(tr(qstring::fromutf8("&értékelés")), ertekelesmenu); menubar() >insertitem(tr(qstring::fromutf8("&kimutatás")), kimutatasmenu); menubar() >insertseparator(); menubar() >insertitem(tr(qstring::fromutf8("&view")), viewmenu); menubar() >insertitem(tr(qstring::fromutf8("&help")), helpmenu); void EafAdmin::initToolBar() // TOOLBAR toolbar = new QToolBar( "", this, DockTop ); tablacsoport >addto( toolbar ); tabladiak >addto( toolbar ); jelentkezescsoport >addto( toolbar ); jelentkezeszh >addto( toolbar ); jelentkezespotzh >addto( toolbar ); toolbar >addseparator(); QWhatsThis::whatsThisButton(toolBar); void EafAdmin::initStatusBar() statusbar() >message(tr(qstring::fromutf8("kész")), 2000); bool EafAdmin::queryExit() int exit=qmessagebox::information(this, tr("quit..."), tr(qstring::fromutf8("valóban befejezte a munkát?")), QMessageBox::Ok, QMessageBox::Cancel); return (exit==1); // SLOTOK IMPLEMENTÁCIÓJA void EafAdmin::slotFileQuit() statusbar() >message(tr(qstring::fromutf8("kilépés az alkalmazásból..."))); qapp >quit(); statusbar() >message(tr(qstring::fromutf8("kész."))); void EafAdmin::slotViewToolBar(bool toggle) 19. oldal

statusbar() >message(tr(qstring::fromutf8("eszközgombok ki és bekapcsolása..."))); if (toggle== false) toolbar >hide(); else toolbar >show(); statusbar() >message(tr(qstring::fromutf8("kész."))); void EafAdmin::slotViewStatusBar(bool toggle) statusbar() >message(tr(qstring::fromutf8("eszközgombok ki és bekapcsolása..."))); if (toggle == false) statusbar() >hide(); else statusbar() >show(); statusbar() >message(tr(qstring::fromutf8("kész"))); void EafAdmin::slotHelpAbout() QMessageBox::about(this,tr("About..."), tr(qstring::fromutf8("eafadmin\nversion 1.0 prepared by Szabóné Nacsa Rozália")) ); void EafAdmin::slotTablaDiak() statusbar() >message(tr(qstring::fromutf8("diák tábla betöltése..."))); setcaption(tr(qstring::fromutf8("elemi Alkalmazások fejlesztése: Diák tábla karbantartása "))); QMessageBox::information( this, QString::fromUtf8("Diák tábla karbantartása"), QString::fromUtf8("Elnézést!\nEz a menüpont még nincs megvalósítva!")); statusbar() >message(tr(qstring::fromutf8("kész"))); void EafAdmin::slotTablaGyakvez() statusbar() >message(tr(qstring::fromutf8("gyakvez tábla betöltése..."))); setcaption(tr(qstring::fromutf8("elemi Alkalmazások fejlesztése: Gyakvez tábla karbantartása "))); QMessageBox::information( this, QString::fromUtf8("Gyakvez tábla karbantartása"), QString::fromUtf8("Elnézést!\nEz a menüpont még nincs megvalósítva!")); statusbar() >message(tr(qstring::fromutf8("kész"))); A főprogram: main.cpp #include <qapplication.h> #include <qobject.h> #include "eafadmin.h" int main( int argc, char ** argv ) QApplication a( argc, argv ); EafAdmin * mw = new EafAdmin(); mw >setcaption(qobject::tr(qstring::fromutf8("elemi Alkalmazások fejlesztése "))); 20. oldal

Fordítás/Futtatás mw >show(); a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) ); return a.exec(); Ezzel elkészítettük az alap projektet. Mielőtt folytatná, kérem ellenőrizze, minden rendben működik e. Az alap projekt forrásprogramja letölthető a people.inf.elte.hu/nacsa/eaf4/projects/eafadmin0 címről. Az adatbázis kapcsolat megvalósítása Tegyük alkalmassá projektünket az adatbázis kezelésre. Először illessze be a projektbe a connection.h és connection.cpp fájlokat. A forráskód a munkafüzet DiakQuery példájában található. A főprogram kiegészítése az adatbázis kapcsolattal Illesszük be a connection.h és connection.cpp fájlokat a projektbe. src.pro TEMPLATE = app CONFIG += release \ warn_on \ thread \ qt TARGET =../bin/eafadmin SOURCES += eafadmin.cpp \ main.cpp \ connection.cpp HEADERS += eafadmin.h \ connection.h main.cpp (módosítás) #include <qapplication.h> #include <qobject.h> #include "eafadmin.h" #include "connection.h" int main( int argc, char ** argv ) QApplication a( argc, argv ); if (!createconnections()) return 1; EafAdmin * mw = new EafAdmin(); mw >setcaption(qobject::tr(qstring::fromutf8("elemi Alkalmazások fejlesztése "))); mw >show(); a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) ); return a.exec(); 21. oldal

Ha idáig eljutottunk, akkor már rendelkezünk egy jól előkészített, adatbáziskezelésre is alkalmas alkalmazás kerettel. Mostmár az SQL modul osztályait használva bármely modulból elérhetjük adatbázisunkat, kiadhatunk adatbáziskezelő parancsokat. A diak táblát karbantartó programrész megvalósítása (Táblák/Diák menüpont) Első lépésként elkészítjük a Táblák/Diák menüpontot. Ebben a menüpontban biztosítjuk a diak tábla karbantartását (új diákokat felvétele, adatainak módosítása, diákok törlése). A tábla karbantartásához a QSqlCursor és a QDataTable osztályok szolgáltatásait vesszük igénybe. A diak_id (sorszám) automatikus kiosztása Új diák felvételekor a diak_id azonosítót szeretnénk automatikusan hozzárendelni az újonnan felvett diákhoz. Azt, hogy az adott pillanatban milyen sorszámnál tartunk az adatbázis sequence táblájában találhatjuk meg. (Az automatikus sorszámozás helyett azért választottuk ezt a megoldást, mert ez biztosan működik minden adatbáziskezelőnél.) mysql> select * from sequence; +------------+----------+ tablename sequence +------------+----------+ felev 0 csoport 0 gyakvez 0 diak 4 zh 1 potzh 0 ------------+----------+ 8 rows in set (0.00 sec) Rekord beszúrásakor a beszúrást megelőző (előkészítő) műveleteket a QDataTable osztály primeinsert() szignáljához kötött szlotban adhatjuk meg. A slotprimeinsert() metódusban a sequence táblából lekérjük (és egyben megnöveljük) a diak táblához tartozó aktuális sorszámot, és betöltjük azt az insert művelet segéd 22. oldal

pufferének diak_id mezejébe. A diak_id mezőt a képernyőn nem jelenítjük meg, hiszen a felhasználót valójában nem érdekli ez a technikai kód. Így minden diák más más azonosító sorszámot (diak_id) kap, és a felhasználó az adatbevitel során nem ronthatja el az adatbázis konzisztenciáját. A DiakDataTable osztály elkészítése src.pro TEMPLATE = app CONFIG += release \ warn_on \ thread \ qt TARGET =../bin/eafadmin SOURCES += eafadmin.cpp \ main.cpp \ connection.cpp \ diakdatatable.cpp HEADERS += eafadmin.h \ connection.h \ diakdatatable.h IMAGES += jelentkezescsoport.png \ jelentkezespotzh.png \ jelentkezeszh.png \ tablacsoport.png \ tabladiak.png diakdattable.h #include <qdatatable.h> #include <qsqlcursor.h> class DiakDataTable : public QdataTable Q_OBJECT public: DiakDataTable(QWidget * parent =0, const char * name =0 ); public slots: void slotprimeinsert(qsqlrecord*); private: QSqlCursor *cursor; ; diakdattable.cpp #include "diakdatatable.h" DiakDataTable::DiakDataTable(QWidget * parent, const char * name) : QDataTable( parent, name ) cursor = new QSqlCursor("diak"); setsqlcursor(cursor); //addcolumn( "diak_id", "Kód" ); addcolumn( "azon", "Azonosító" ); addcolumn( "nev", "Név" ); setcolumnwidth(2,200); refresh(); 23. oldal

setconfirmdelete(true); setautoedit(true); // signals and slots connections connect( this, SIGNAL( primeinsert(qsqlrecord*) ), this, SLOT( slotprimeinsert(qsqlrecord*) ) ); void DiakDataTable::slotPrimeInsert(QSqlRecord * buffer) QSqlQuery query; query.exec("update sequence SET sequence = sequence + 1 WHERE tablename ='diak';"); query.exec("select sequence FROM sequence WHERE tablename ='diak';"); if (query.next()) buffer >setvalue("diak_id", query.value(0)); A slottabladiak() módosítása (eafadmin.cpp) A Táblák/diák menüpont kiválasztásakor létrehozzuk az előzőekben megadott osztály egy példányát és ezt jelöljük meg az alkalmazásunk központi párbeszéd ablakának. Ehhez aktualizálnunk kell a slottabladiak() slotot. Fordítás/Futtatás... #include "diakdatatable.h"... void EafAdmin::slotTablaDiak() statusbar() >message(tr(qstring::fromutf8("diák tábla betöltése..."))); setcaption(tr(qstring::fromutf8("elemi Alkalmazások fejlesztése: Diák tábla karbantartása "))); DiakDataTable *diakdatatable = new DiakDataTable(this, "DiakDtatTable"); diakdatatable >show(); setcentralwidget(diakdatatable); statusbar() >message(tr(qstring::fromutf8("kész"))); Fordítás és szerkesztés után indítsa el a programot, majd a menüpontok közül válassza ki a Táblák/Diák menüpontot. Kattintson jobb egérfüllel a megjelenő táblára, majd a felbukkanó helyi menüből válassza ki a kívánt fumkciót: Insert, Update, Delete. Néhány rekord bevitele után egy terminál ablakból nyissa meg az adatbázist, és nézze meg, helyesen működik e a program, valamint a sorszámok kiosztása. Vegye észre, hogy az adatbázist az alkalmazásból és a terminál ablakból is módosíthatja. 24. oldal

mysql> select * from diak; diak_id azon nev 1 KPETE Kiss Péter 2 NPETE Nagy Péter 3 NKATA Nagy Katalin 3 rows in set (0.00 sec) mysql> select * from sequence; +------------+----------+ tablename sequence +------------+----------+... diak 4... Ellenőrzött adatbevitel biztosítása Adatbevitelnél/módosításnál ügyelnünk kell arra is, hogy megmaradjon az adatbázis konzisztenciája. Erre a legelegánsabb megoldás, ha fel sem kínáljuk azokat a műveleteket, amelyeket úgy sem lehetne végrehajtani. Adatbázisunk diák táblájából nem törölhető az a diák, aki már tagja valamely csoportnak, illetve már van valamilyen gyakorlati jegye. Az aktuális soron végrehajtható műveleteket a QsqlRecord curretchanged() szignáljára kötött slotcurretchanged() slot metódusban szabályozzuk. diakdattable.h (módosítás) class DiakDataTable : public QDataTable... public slots: void slotprimeinsert(qsqlrecord*); void slotcurrentchanged(qsqlrecord* buffer); private: void setmode(qsqlrecord* buffer); QSqlCursor *cursor; ; diakdattable.cpp (módosítás) #include "diakdatatable.h" DiakDataTable::DiakDataTable(QWidget * parent, const char * name) : QDataTable( parent, name ) cursor = new QSqlCursor("diak"); setsqlcursor(cursor); //addcolumn( "diak_id", "Kód" ); addcolumn( "azon", "Azonosító" ); addcolumn( "nev", "Név" ); setcolumnwidth(2,200); refresh(); setconfirmdelete(true); 25. oldal

setautoedit(true); // signals and slots connections connect( this, SIGNAL( primeinsert(qsqlrecord*) ), this, SLOT( slotprimeinsert(qsqlrecord*) ) ); connect( this, SIGNAL( currentchanged(qsqlrecord*) ), this, SLOT( slotcurrentchanged (QSqlRecord*) ) ); void DiakDataTable::slotCurrentChanged(QSqlRecord* buffer) setmode(buffer); void DiakDataTable::setMode(QSqlRecord* buffer) if (buffer == 0) return; QSqlQuery query; int count_tag=0; query.exec( "SELECT count(*) FROM tag WHERE diak_id=" + buffer >value("diak_id").tostring() + ";" ); if (query.next()) count_tag = query.value(0).toint(); int count_jelentkezes=0; query.exec("select count(*) FROM jelentkezes WHERE diak_id=" + buffer >value("diak_id").tostring() + ";"); if (query.next()) count_jelentkezes = query.value(0).toint(); if ( count_tag == 0 and count_jelentkezes == 0 ) cursor >setmode( QSqlCursor::Insert QSqlCursor::Delete QSqlCursor::Update ); else cursor >setmode( QSqlCursor::Insert QSqlCursor::Update ); A forrásprogramok letölthetők a people.inf.elte.hu/nacsa/eaf4/projects/eafadmin1 címről. Folytatása következik... 26. oldal