c++ gui programming with qt 3 · 1. qmake –o makefile videoteka.pro 2. nmake 3. quit or: buildor:...

Post on 14-Aug-2020

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

C++ GUI Programming with Qt 3

Rozália Szabó NacsaEötvös Loránd University, Budapest

Faculty of Informatics

nacsa@inf.elte.hu

2

The Task

3

The „Tricks”

ComboBox

Modificationwith controls

Calculated field

Calculatedfield with

„info”

Read Only

4

The Tables

5

Database Managament using API calls

DatabaseDatabase11

Application

API1calls

API1

DatabaseDatabase22

Alkalmazás

API2calls

API2

Database specificfunction calls.

Database specificfunction calls.

6

Database Management using SQL commands

DatabaseDatabase11API1

DatabaseDatabase22

Application

SQLcommands

API2

SQL

SQL

Database specificfunction calls

Database specificfunction calls

Standard QueryLanguage

Standard QueryLanguage

7

Database Management using ODBC

DatabaseDatabase11API1 Application

SQLcommands

ODBCfunction calls

SQL

ODBCfunctions

DatabaseDatabase22API1

SQL

ODBCfunctions

ODBCdriver1

ODBCdriver1

ODBCdriver2

Database specificfunction calls

Database specificfunction calls

Standard QueryLanguage

Standard QueryLanguage

Standard functions

Standard functions

8

Database Management using ODBC

DatabaseDatabase11API1 Application

SQLcommands

ODBCfunction calls

SQL

ODBCfunctions

DatabaseDatabase22API1

SQL

ODBCfunctions

ODBCdriver2

ODBCdriver1

ODBCdriver2

9

videotekavideoteka

Registration

Videoteka„MySQL” driver

DSN (Data Source Name)Driver

10

Vezérlőpult/Felügyeleti eszközök

Registration

11

ODBC datasource

12

13

Identification of„physical”database.

Identification of„physical”database.

14

15

Available Drivers in Qt

•QDB2 - IBM DB2 Driver (v7.1 and higher) •QIBASE - Borland Interbase Driver •QMYSQL3 - MySQL Driver•QOCI8 - Oracle Call Interface Driver, version 8 and 9 •QODBC3 - Open Database Connectivity Driver•QPSQL7 - PostgreSQL v6.x and v7.x Driver •QSQLITE - SQLite Driver •QTDS7 - Sybase Adaptive Server and Microsoft SQL Server Driver

•QDB2 - IBM DB2 Driver (v7.1 and higher) •QIBASE - Borland Interbase Driver •QMYSQL3 - MySQL Driver•QOCI8 - Oracle Call Interface Driver, version 8 and 9 •QODBC3 - Open Database Connectivity Driver•QPSQL7 - PostgreSQL v6.x and v7.x Driver •QSQLITE - SQLite Driver •QTDS7 - Sybase Adaptive Server and Microsoft SQL Server Driver

16

Qt / SQL module

DBMS classes canbe found in SQL

Module .

DBMS classes canbe found in SQL

Module .

17

Database Related Classes

QSqlQueryQSqlQuery QSqlCursorQSqlCursor

QDataTableQDataTableQTableQTable

„Represent” data„Represent” data

„Display” data„Display” data

18

19

Creating the „Videoteka” project

File/NewFile/New

20

Creating the Main Window

File/NewFile/New

21

Wizard: Choose menus and toolbars

We don’t needthese „services”.

We don’t needthese „services”.

22

Wizard: Setup Toolbar

23

Wizard: Finish

24

Previewing the Project

Ctrl+TCtrl+T

1. qmake –o Makefile videoteka.pro2. nmake3. quit

1. qmake –o Makefile videoteka.pro2. nmake3. quit OR: BuildOR: Build

25

The Starting Project

26

Adding main program to the project

File/NewFile/New

27

The generated main program

28

Compile & Run

1. qmake –o Makefile videoteka.pro2. nmake3. quit

1. qmake –o Makefile videoteka.pro2. nmake3. quit

29

Connecting to the Database

connection.cppconnection.cpp

connection.hconnection.h

main.cppmain.cpp

30

Adding Source File to the Project

File/NewFile/New

File/Save as …File/Save as …

31

Adding Header File to the Project

File/NewFile/New

File/Save as …File/Save as …

32

Database Connection: connection.h, connection.cpp

#define DB_SOURCE_DRIVER "QODBC3"#define DB_SOURCE_DBNAME „videoteka"#define DB_SOURCE_USER "nacsa"#define DB_SOURCE_PASSWD "1234"#define DB_SOURCE_HOST "localhost"bool createConnections();

#define DB_SOURCE_DRIVER "QODBC3"#define DB_SOURCE_DBNAME „videoteka"#define DB_SOURCE_USER "nacsa"#define DB_SOURCE_PASSWD "1234"#define DB_SOURCE_HOST "localhost"bool createConnections();

#include <qsqldatabase.h>#include "connection.h"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( „Failed to open database: " +source->lastError().driverText() );qWarning( source->lastError().databaseText() );return FALSE;

}return TRUE;

}

#include <qsqldatabase.h>#include "connection.h"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( „Failed to open database: " +source->lastError().driverText() );qWarning( source->lastError().databaseText() );return FALSE;

}return TRUE;

}

1.Activate driver2.Set connection’s properties3.Open connection

1.Activate driver2.Set connection’s properties3.Open connection

connection.hconnection.h

connection.cppconnection.cpp

Only the driver has tobe modified changingthe databaseenvironment.

Only the driver has tobe modified changingthe databaseenvironment.

33

Database Connection: main.cpp

. . .#include <qsqldatabase.h>#include "connection.h. . .int main( int argc, char *argv[] ) {

. . .if ( createConnections() ) {

// We have opened the database connections.// Ready to perform SQL commands

}return 0;

}

. . .#include <qsqldatabase.h>#include "connection.h. . .int main( int argc, char *argv[] ) {

. . .if ( createConnections() ) {

// We have opened the database connections.// Ready to perform SQL commands

}return 0;

}

main.cppmain.cpp

34

35

Creating New Action – Tables/Customers

36

tableCustomersAction: Properties

37

tableFilmsAction: Properties

38

tableRentsAction: Properties

39

Adding Actions to the Menu

Drag & DropDrag & Drop

40

Creating CustomersForm

File/NewFile/New

41

Drag & Drop & . . .Drag & Drop & . . .

42

Data Table Wizard: Choose Database & Table

1

23

43

Data Table Wizard: Choose Database & Table

customersfilmsrentssequence

customersfilmsrentssequence

44

Data Table Wizard: Displayed Fields

nameaddresscode

nameaddresscode

45

Data Table Wizard: Table Properties

46

Data Table Wizard: SQL

You can add a valid WHERE clause here.

You can add a valid WHERE clause here.

47

48

Double Click ontable to edit it.

Double Click ontable to edit it.

49

Bringing up the CustomersForm

CustomersFormCustomersForm

50

Creating a New Slot

Function: slotTableCustomers()Return type: voidSpecifier: virtualAccess: publicType: slot

Function: slotTableCustomers()Return type: voidSpecifier: virtualAccess: publicType: slot

51

Connections

Sender: tableCustomersActionSignal: activated()Receiver: MainFormSlot:slotTableCustomers()

Sender: tableCustomersActionSignal: activated()Receiver: MainFormSlot:slotTableCustomers()

52

Further Slots

Function: slotTableFilms()Return type: voidSpecifier: virtualAccess: publicType: slot

Function: slotTableFilms()Return type: voidSpecifier: virtualAccess: publicType: slot

Function: slotTableRents()Return type: voidSpecifier: virtualAccess: publicType: slot

Function: slotTableRents()Return type: voidSpecifier: virtualAccess: publicType: slot

53

Further Connections

Sender: tableFilmsActionSignal: activated()Receiver: MainFormSlot:slotTableFilms()

Sender: tableFilmsActionSignal: activated()Receiver: MainFormSlot:slotTableFilms()

Sender: tableRentsActionSignal: activated()Receiver: MainFormSlot:slotTableRents()

Sender: tableRentsActionSignal: activated()Receiver: MainFormSlot:slotTableRents()

54

Implementation: slotTableCustomers

void MainForm::slotTableCustomers(){

statusBar()->message(tr(QString::fromUtf8("Loading Table of Customers . . .")));setCaption(tr(QString::fromUtf8("Videoteka: Table of Customers ")));CustomersForm *customersForm = new CustomersForm(this, "CustomersForm");customersForm->show();setCentralWidget(customersForm);statusBar()->message(tr(QString::fromUtf8("Ready")));

}

void MainForm::slotTableCustomers(){

statusBar()->message(tr(QString::fromUtf8("Loading Table of Customers . . .")));setCaption(tr(QString::fromUtf8("Videoteka: Table of Customers ")));CustomersForm *customersForm = new CustomersForm(this, "CustomersForm");customersForm->show();setCentralWidget(customersForm);statusBar()->message(tr(QString::fromUtf8("Ready")));

}

mainform.ui.h

55

Implementation: slotTableFilms()

void MainForm::slotTableFilms(){

QMessageBox::information( this, "Videoteka Manager","Sorry! Not implemented yet." );

}

void MainForm::slotTableFilms(){

QMessageBox::information( this, "Videoteka Manager","Sorry! Not implemented yet." );

}

mainform.ui.h

Implementation: slotTableRents()

void MainForm::slotTableRents(){

QMessageBox::information( this, "Videoteka Manager","Sorry! Not implemented yet." );

}

void MainForm::slotTableRents(){

QMessageBox::information( this, "Videoteka Manager","Sorry! Not implemented yet." );

}

mainform.ui.h

56

DataTable: Signals

57

New Slot: slotPrimeInsert()

Function: slotPrimeInsert(QSqlRecord*)Return type: voidSpecifier: virtualAccess: publicType: slot

Function: slotPrimeInsert(QSqlRecord*)Return type: voidSpecifier: virtualAccess: publicType: slot

Edit/Slots …

58

Connection

Sender: dataTableSignal: primeInsert(QSqlRecord*)Receiver: MainFormSlot:slotPrimeInsert(QSqlRecord*)

Sender: dataTableSignal: primeInsert(QSqlRecord*)Receiver: MainFormSlot:slotPrimeInsert(QSqlRecord*)

59

Implementation

void CustomersForm::slotPrimeInser( QSqlRecord *buffer ){

QSqlQuery query;query.exec("UPDATE sequence SET sequence = sequence + 1 WHERE tablename

='customers';");query.exec("SELECT sequence FROM sequence WHERE tablename ='customers';");if (query.next()) {buffer->setValue("customer_id", query.value(0));

}}

void CustomersForm::slotPrimeInser( QSqlRecord *buffer ){

QSqlQuery query;query.exec("UPDATE sequence SET sequence = sequence + 1 WHERE tablename

='customers';");query.exec("SELECT sequence FROM sequence WHERE tablename ='customers';");if (query.next()) {buffer->setValue("customer_id", query.value(0));

}}

customerform.ui.h

60

Controlling Data Entry

61

Slot: slotCurrentChanged()

Function: slotCurrentChanged(QSqlRecord*)Return type: voidSpecifier: virtualAccess: publicType: slot

Function: slotCurrentChanged(QSqlRecord*)Return type: voidSpecifier: virtualAccess: publicType: slot

62

Function: setMode()

Function: setMode(QSqlRecord*)Return type: voidSpecifier: virtualAccess: protectedType: function

Function: setMode(QSqlRecord*)Return type: voidSpecifier: virtualAccess: protectedType: function

Edit/Slots …

63

Implementation: slotCurrentChanged(), setMode()

void CustomersForm::slotCurrentChanged( QSqlRecord * buffer ){

setMode(buffer);}

void CustomersForm::setMode( QSqlRecord * buffer ){

if (buffer == 0) return;QSqlQuery query;int count_rent=0;query.exec( "SELECT count(*) FROM rents WHERE customer_id=" +

buffer->value("customer_id").toString() + ";" );if (query.next())

count_rent = query.value(0).toInt();if ( count_rent == 0)

dataTable->sqlCursor ()->setMode( QSqlCursor::Insert | QSqlCursor::Delete | QSqlCursor::Update );

elsedataTable->sqlCursor ()->setMode( QSqlCursor::Insert | QSqlCursor::Update );

}

void CustomersForm::slotCurrentChanged( QSqlRecord * buffer ){

setMode(buffer);}

void CustomersForm::setMode( QSqlRecord * buffer ){

if (buffer == 0) return;QSqlQuery query;int count_rent=0;query.exec( "SELECT count(*) FROM rents WHERE customer_id=" +

buffer->value("customer_id").toString() + ";" );if (query.next())

count_rent = query.value(0).toInt();if ( count_rent == 0)

dataTable->sqlCursor ()->setMode( QSqlCursor::Insert | QSqlCursor::Delete | QSqlCursor::Update );

elsedataTable->sqlCursor ()->setMode( QSqlCursor::Insert | QSqlCursor::Update );

}

customerform.ui.h

64

Compile & Run

65

Compile & Run

66

67

ComboBox

Modificationwith controls

Calculated field

Calculatedfield with

„info”

Read Only

68

Classes

QSqlCursor

FilmSqlCursorQDataTable

FilmDataTable

QMainWindow

Videoteka

main.cpp

69

Classes

QSqlCursor

FilmSqlCursorQDataTable

FilmDataTable

QMainWindow

Videoteka

main.cpp

70

FilmSqlCursor - Definition

#include <qsqlcursor.h>

class FilmSqlCursor : public QSqlCursor {public:

FilmSqlCursor();protected:

QVariant calculateField(const QString &name);

};

#include <qsqlcursor.h>

class FilmSqlCursor : public QSqlCursor {public:

FilmSqlCursor();protected:

QVariant calculateField(const QString &name);

};

filmsqlcursor.h

Protected virtual function which is called whenever a field needs to be calculated. If calculated fields are being used, derived classes must reimplement this function.

Protected virtual function which is called whenever a field needs to be calculated. If calculated fields are being used, derived classes must reimplement this function.

71

FilmSqlCursor - Implementation#include "filmsqlcursor.h"

FilmSqlCursor::FilmSqlCursor(): QSqlCursor("films"){

QSqlFieldInfo available("available", QVariant::Int);append(available);setCalculated(available.name(),TRUE);

}

QVariant FilmSqlCursor::calculateField(const QString &name){

if (name == "available") {QSqlQuery query;int available=0;query.exec("SELECT (amount - rented) FROM films WHERE film_id=" +

field("film_id")->value().toString() + ";");if (query.next())

available = query.value(0).toInt();return QVariant(QString::number(available));

}return QVariant(QString::null);

}

#include "filmsqlcursor.h"

FilmSqlCursor::FilmSqlCursor(): QSqlCursor("films"){

QSqlFieldInfo available("available", QVariant::Int);append(available);setCalculated(available.name(),TRUE);

}

QVariant FilmSqlCursor::calculateField(const QString &name){

if (name == "available") {QSqlQuery query;int available=0;query.exec("SELECT (amount - rented) FROM films WHERE film_id=" +

field("film_id")->value().toString() + ";");if (query.next())

available = query.value(0).toInt();return QVariant(QString::number(available));

}return QVariant(QString::null);

}

filmsqlcursor.cpp

The field „available” is a calculated field.

The field „available” is a calculated field.

72

Classes

QSqlCursor

FilmSqlCursorQDataTable

FilmDataTable

QMainWindow

Videoteka

main.cpp

73

Preparing FilmDataTable Class

File/New/C++ Cource FileSave As:filmdatatable.cpp

File/New/C++ Cource FileSave As:filmdatatable.h

74

FilmDataTable: Definitionclass FilmSqlCursor;

class FilmDataTable : public QDataTable{

Q_OBJECTpublic:

FilmDataTable(QWidget * parent =0 , const char * name =0 );void paintField(

QPainter * p, const QSqlField* field, const QRect & cr, bool );

public slots:void slotPrimeInsert(QSqlRecord*);void slotCurrentChanged(QSqlRecord* buffer);void slotBeforeUpdate(QSqlRecord* buffer);

private:void setMode(QSqlRecord* buffer);

private:FilmSqlCursor *cursor;QSqlPropertyMap *propMap;FilmSqlEditorFactory *editorFactory;

};

class FilmSqlCursor;

class FilmDataTable : public QDataTable{

Q_OBJECTpublic:

FilmDataTable(QWidget * parent =0 , const char * name =0 );void paintField(

QPainter * p, const QSqlField* field, const QRect & cr, bool );

public slots:void slotPrimeInsert(QSqlRecord*);void slotCurrentChanged(QSqlRecord* buffer);void slotBeforeUpdate(QSqlRecord* buffer);

private:void setMode(QSqlRecord* buffer);

private:FilmSqlCursor *cursor;QSqlPropertyMap *propMap;FilmSqlEditorFactory *editorFactory;

};

filmdatatable.h

#include <qdatatable.h>#include <qpainter.h>#include <qsqleditorfactory.h>#include <qsqlpropertymap.h>

#include <qdatatable.h>#include <qpainter.h>#include <qsqleditorfactory.h>#include <qsqlpropertymap.h>

75

FilmDataTable: Constructor /Basics

FilmDataTable::FilmDataTable(QWidget * parent, const char * name) :QDataTable( parent, name )

{cursor = new FilmSqlCursor();setSqlCursor(cursor);//addColumn( "film_id", "Id" );addColumn( "title", tr(QString::fromUtf8("Title")) );addColumn( "type", tr(QString::fromUtf8("Type")) );addColumn( "amount", tr(QString::fromUtf8("Amount")) );addColumn( "rented", tr(QString::fromUtf8("Rented")) );addColumn( "available", tr(QString::fromUtf8("Available")) );//setColumnWidth(1,200);refresh();setConfirmDelete(TRUE);setAutoEdit(TRUE);. . .

}

FilmDataTable::FilmDataTable(QWidget * parent, const char * name) :QDataTable( parent, name )

{cursor = new FilmSqlCursor();setSqlCursor(cursor);//addColumn( "film_id", "Id" );addColumn( "title", tr(QString::fromUtf8("Title")) );addColumn( "type", tr(QString::fromUtf8("Type")) );addColumn( "amount", tr(QString::fromUtf8("Amount")) );addColumn( "rented", tr(QString::fromUtf8("Rented")) );addColumn( "available", tr(QString::fromUtf8("Available")) );//setColumnWidth(1,200);refresh();setConfirmDelete(TRUE);setAutoEdit(TRUE);. . .

}

filmdatatable.cpp

#include "filmdatatable.h"#include "filmsqlcursor.h"#include <qmessagebox.h>

#include "typepicker.h"#include "readonlyedit.h"

#include "filmdatatable.h"#include "filmsqlcursor.h"#include <qmessagebox.h>

#include "typepicker.h"#include "readonlyedit.h"

76

FilmDataTable: Constructor /Property & Factory

FilmDataTable::FilmDataTable(QWidget * parent, const char * name) :QDataTable( parent, name )

{. . .propMap = new QSqlPropertyMap();propMap->insert( "TypePicker", "type" );installPropertyMap( propMap );

editorFactory = new FilmSqlEditorFactory();installEditorFactory( editorFactory );

. . .

}

FilmDataTable::FilmDataTable(QWidget * parent, const char * name) :QDataTable( parent, name )

{. . .propMap = new QSqlPropertyMap();propMap->insert( "TypePicker", "type" );installPropertyMap( propMap );

editorFactory = new FilmSqlEditorFactory();installEditorFactory( editorFactory );

. . .

}

filmdatatable.cpp

#include "filmdatatable.h"#include "filmsqlcursor.h"#include <qmessagebox.h>

#include "typepicker.h"#include "readonlyedit.h"

#include "filmdatatable.h"#include "filmsqlcursor.h"#include <qmessagebox.h>

#include "typepicker.h"#include "readonlyedit.h"

77

FilmDataTable: Constructor / Connections

FilmDataTable::FilmDataTable(QWidget * parent, const char * name) :QDataTable( parent, name )

{. . .// signals and slots connectionsconnect( this, SIGNAL( primeInsert(QSqlRecord*) ),

this, SLOT( slotPrimeInsert(QSqlRecord*) ) );connect( this, SIGNAL( currentChanged(QSqlRecord*) ),

this, SLOT( slotCurrentChanged(QSqlRecord*) ) );connect( this, SIGNAL(beforeUpdate(QSqlRecord*) ),

this, SLOT(slotBeforeUpdate(QSqlRecord*) ) );}

FilmDataTable::FilmDataTable(QWidget * parent, const char * name) :QDataTable( parent, name )

{. . .// signals and slots connectionsconnect( this, SIGNAL( primeInsert(QSqlRecord*) ),

this, SLOT( slotPrimeInsert(QSqlRecord*) ) );connect( this, SIGNAL( currentChanged(QSqlRecord*) ),

this, SLOT( slotCurrentChanged(QSqlRecord*) ) );connect( this, SIGNAL(beforeUpdate(QSqlRecord*) ),

this, SLOT(slotBeforeUpdate(QSqlRecord*) ) );}

filmdatatable.cpp

78

FilmDataTable: Destructor

FilmDataTable::~FilmDataTable(){

if (propMap) delete propMap;if (editorFactory) delete editorFactory;if (cursor) delete cursor; //May be it’s not necessary.

}

FilmDataTable::~FilmDataTable(){

if (propMap) delete propMap;if (editorFactory) delete editorFactory;if (cursor) delete cursor; //May be it’s not necessary.

}

filmdatatable.cpp

FilmDataTable::FilmDataTable(. . .){

cursor = new FilmSqlCursor();. . .propMap = new QSqlPropertyMap();. . .editorFactory = new FilmSqlEditorFactory();. . .

}

FilmDataTable::FilmDataTable(. . .){

cursor = new FilmSqlCursor();. . .propMap = new QSqlPropertyMap();. . .editorFactory = new FilmSqlEditorFactory();. . .

}

filmdatatable.cpp

79

FilmDataTable: slotPrimeInsert()

void FilmDataTable::slotPrimeInsert(QSqlRecord * buffer){

QSqlQuery query;query.exec("UPDATE sequence SET sequence = sequence + 1 WHERE tablename

='films';");query.exec("SELECT sequence FROM sequence WHERE tablename ='films';");if (query.next()) {buffer->setValue("film_id", query.value(0));buffer->setValue("amount",1);buffer->setValue("rented",0);buffer->setValue("available",1);buffer->setValue("type","DVD");

}

}

void FilmDataTable::slotPrimeInsert(QSqlRecord * buffer){

QSqlQuery query;query.exec("UPDATE sequence SET sequence = sequence + 1 WHERE tablename

='films';");query.exec("SELECT sequence FROM sequence WHERE tablename ='films';");if (query.next()) {buffer->setValue("film_id", query.value(0));buffer->setValue("amount",1);buffer->setValue("rented",0);buffer->setValue("available",1);buffer->setValue("type","DVD");

}

}

filmdatatable.cpp

Default values starting insertion.

Default values starting insertion.

Default calculatedvalue must be done, TOO, otherwise thisvalue remains zero.

Default calculatedvalue must be done, TOO, otherwise thisvalue remains zero.

80

FilmDataTable: slotBeforeUpdate()

void FilmDataTable::slotBeforeUpdate(QSqlRecord* buffer){

if(buffer->value("amount").toInt() < buffer->value("rented").toInt()) {buffer->setValue("amount",buffer->value("rented"));QMessageBox::information( this,

tr(QString::fromUtf8("Videoteka: Updating Table of Films")),tr(QString::fromUtf8("Amount can not be less then number of rented films.!")));

}}

void FilmDataTable::slotBeforeUpdate(QSqlRecord* buffer){

if(buffer->value("amount").toInt() < buffer->value("rented").toInt()) {buffer->setValue("amount",buffer->value("rented"));QMessageBox::information( this,

tr(QString::fromUtf8("Videoteka: Updating Table of Films")),tr(QString::fromUtf8("Amount can not be less then number of rented films.!")));

}}

filmdatatable.cpp

81

FilmDataTable: setMode()void FilmDataTable::setMode(QSqlRecord* buffer){

if (buffer == 0) return;QSqlQuery query;int count_rented=0;query.exec( "SELECT rented FROM films WHERE film_id=" +

buffer->value("film_id").toString() + ";" );if (query.next())count_rented = query.value(0).toInt();

if ( count_rented == 0)cursor->setMode( QSqlCursor::Insert | QSqlCursor::Delete | QSqlCursor::Update );

elsecursor->setMode( QSqlCursor::Insert | QSqlCursor::Update );

}

void FilmDataTable::setMode(QSqlRecord* buffer){

if (buffer == 0) return;QSqlQuery query;int count_rented=0;query.exec( "SELECT rented FROM films WHERE film_id=" +

buffer->value("film_id").toString() + ";" );if (query.next())count_rented = query.value(0).toInt();

if ( count_rented == 0)cursor->setMode( QSqlCursor::Insert | QSqlCursor::Delete | QSqlCursor::Update );

elsecursor->setMode( QSqlCursor::Insert | QSqlCursor::Update );

}

filmdatatable.cpp

82

Reimplementation of paintField()

void FilmDataTable::paintField( QPainter * p, const QSqlField* field,const QRect & cr, bool b){

if ( !field )return;

if ( field->name() == "available" ) {QString text;if(field->value().toInt() == 0)

text="* Out of stock*";elsetext = field->value().toString();p->drawText( 2,2, cr.width()-4, cr.height()-4, fieldAlignment( field ), text );

} else {QDataTable::paintField( p, field, cr, b) ;

}}

void FilmDataTable::paintField( QPainter * p, const QSqlField* field,const QRect & cr, bool b){

if ( !field )return;

if ( field->name() == "available" ) {QString text;if(field->value().toInt() == 0)

text="* Out of stock*";elsetext = field->value().toString();p->drawText( 2,2, cr.width()-4, cr.height()-4, fieldAlignment( field ), text );

} else {QDataTable::paintField( p, field, cr, b) ;

}}

filmdatatable.cpp

83

FilmSqlEditorFactory: Definition(embedded!)

class FilmSqlEditorFactory : public QSqlEditorFactory{

Q_OBJECTpublic:

QWidget *createEditor( QWidget *parent, const QSqlField *field );};

class FilmSqlEditorFactory : public QSqlEditorFactory{

Q_OBJECTpublic:

QWidget *createEditor( QWidget *parent, const QSqlField *field );};

filmdatatable.h

To create „custom” editor you haveto reimlement createEditor() function.

To create „custom” editor you haveto reimlement createEditor() function.

84

FilmSqlEditorFactory: Implementation (embedded!)

. . .QWidget *FilmSqlEditorFactory::createEditor(

QWidget *parent, const QSqlField *field ){

if ( field->name() == "rented" ) {QWidget *editor = new ReadOnlyEdit( parent );return editor;

}if ( field->name() == "type" ) {

QWidget *editor = new TypePicker( parent );return editor;

}if ( field->name() == "available" ) {

QWidget *editor = new ReadOnlyEdit( parent );return editor;

} return QSqlEditorFactory::createEditor( parent, field );

}. . .

. . .QWidget *FilmSqlEditorFactory::createEditor(

QWidget *parent, const QSqlField *field ){

if ( field->name() == "rented" ) {QWidget *editor = new ReadOnlyEdit( parent );return editor;

}if ( field->name() == "type" ) {

QWidget *editor = new TypePicker( parent );return editor;

}if ( field->name() == "available" ) {

QWidget *editor = new ReadOnlyEdit( parent );return editor;

} return QSqlEditorFactory::createEditor( parent, field );

}. . .

filmdatatable.cpp

For these three fields we wan to touse „custom” editor.(These two classes will be given later!)

For these three fields we wan to touse „custom” editor.(These two classes will be given later!)

TypePicker EditorTypePicker Editor

85

ReadOnlyEdit Class

#include <qlineedit.h>class ReadOnlyEdit : public QLineEdit {

Q_OBJECTpublic:ReadOnlyEdit( QWidget *parent=0, const char *name=0 );

};

#include <qlineedit.h>class ReadOnlyEdit : public QLineEdit {

Q_OBJECTpublic:ReadOnlyEdit( QWidget *parent=0, const char *name=0 );

};

readonlyedit.h

#include "readonlyedit.h"ReadOnlyEdit::ReadOnlyEdit( QWidget *parent, const char *name ) : QLineEdit( parent, name ){

setReadOnly(TRUE);

}

#include "readonlyedit.h"ReadOnlyEdit::ReadOnlyEdit( QWidget *parent, const char *name ) : QLineEdit( parent, name ){

setReadOnly(TRUE);

}

readonlyedit.cpp

86

TypePicker Class: Definition

#include <qcombobox.h>class TypePicker : public QComboBox{

Q_OBJECT

Q_PROPERTY( QString type READ Type WRITE setType )

public:TypePicker( QWidget *parent=0, const char *name=0 );QString Type() const;void setType( QString type );

};

#include <qcombobox.h>class TypePicker : public QComboBox{

Q_OBJECT

Q_PROPERTY( QString type READ Type WRITE setType )

public:TypePicker( QWidget *parent=0, const char *name=0 );QString Type() const;void setType( QString type );

};

typepicker.h

memberread() write()

87

#include "typepicker.h"#include <qsqlcursor.h>TypePicker::TypePicker( QWidget *parent, const char *name ) : QComboBox( parent, name ){

insertItem("DVD");insertItem("VHS");setCurrentText("DVD");

}

QString TypePicker::Type() const{

return currentText();}

void TypePicker::setType( QString type ){

setCurrentText( type );}

#include "typepicker.h"#include <qsqlcursor.h>TypePicker::TypePicker( QWidget *parent, const char *name ) : QComboBox( parent, name ){

insertItem("DVD");insertItem("VHS");setCurrentText("DVD");

}

QString TypePicker::Type() const{

return currentText();}

void TypePicker::setType( QString type ){

setCurrentText( type );}

TypePicker Class: Definition

typepicker.h

read()

write()

88

Reads and writesReadingGenerates#includesToolGenerated source fileRevision controlled source file

SummaryQt

designer

UIC

form.cppform.cppmain.cppmain.cpp

form.ui form.ui

form.hform.h

form.ui form.ui

Application specific functions can be given

in form.ui.h file.

Application specific functions can be given

in form.ui.h file.

form.ui.hform.ui.h

89

Summary: Creating Dialogs

90

Summary: Creating Main Windows

91

Summary: Database Related Application

92

top related