c++ gui programming with qt 3 · 1. qmake –o makefile videoteka.pro 2. nmake 3. quit or: buildor:...
TRANSCRIPT
1
C++ GUI Programming with Qt 3
Rozália Szabó NacsaEötvös Loránd University, Budapest
Faculty of Informatics
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