c++ gui programming with qt 3 · creating the „videoteka” project file/new 20 creating the main...

16
1 1 C++ GUI Programming with Qt 3 Rozália Szabó Nacsa Eötvös Loránd University, Budapest Faculty of Informatics [email protected] 2 The Task 3 The „Tricks” ComboBox Modification with controls Calculated field Calculated field with „info” Read Only 4 The Tables 5 Database Managament using API calls Database 1 Application API 1 calls API 1 Database 2 Alkalmazás API 2 calls API 2 Database specific function calls. 6 Database Management using SQL commands Database 1 API 1 Database 2 Application SQL commands API 2 SQL SQL Database specific function calls Standard Query Language

Upload: others

Post on 14-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

1

1

C++ GUI Programming with Qt 3

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

Faculty of [email protected]

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

Database1

Application

API1calls

API1

Database2

Alkalmazás

API2calls

API2

Database specificfunction calls. 6

Database Management using SQL commands

Database1API1

Database2

Application

SQLcommands

API2

SQL

SQL

Database specificfunction calls Standard Query

Language

Page 2: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

2

7

Database Management using ODBC

Database1API1 Application

SQLcommands

ODBCfunction calls

SQL

ODBCfunctions

Database2API1

SQL

ODBCfunctions

ODBCdriver1

ODBCdriver1

ODBCdriver2

Database specificfunction calls

Standard QueryLanguage

Standard functions

8

Database Management using ODBC

Database1API1 Application

SQLcommands

ODBCfunction calls

SQL

ODBCfunctions

Database2API1

SQL

ODBCfunctions

ODBCdriver2

ODBCdriver1

ODBCdriver2

9

videoteka

Registration

Videoteka„MySQL” driver

DSN (Data Source Name)Driver

10

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

Registration

11

ODBC datasource

12

Page 3: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

3

13

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

16

Qt / SQL module

DBMS classes canbe found in SQL

Module .

17

Database Related Classes

QSqlQuery QSqlCursor

QDataTableQTable

„Represent” data

„Display” data18

Page 4: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

4

19

Creating the „Videoteka” project

File/New

20

Creating the Main Window

File/New

21

Wizard: Choose menus and toolbars

We don’t needthese „services”.

22

Wizard: Setup Toolbar

23

Wizard: Finish

24

Previewing the Project

Ctrl+T

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

OR: Build

Page 5: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

5

25

The Starting Project

26

Adding main program to the project

File/New

27

The generated main program

28

Compile & Run

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

29

Connecting to the Database

connection.cpp

connection.h

main.cpp

30

Adding Source File to the Project

File/New

File/Save as …

Page 6: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

6

31

Adding Header File to the Project

File/New

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();

#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

connection.h

connection.cpp

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;}

main.cpp

34

35

Creating New Action – Tables/Customers

36

tableCustomersAction: Properties

Page 7: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

7

37

tableFilmsAction: Properties

38

tableRentsAction: Properties

39

Adding Actions to the Menu

Drag & Drop

40

Creating CustomersForm

File/New

41

Drag & Drop & . . .

42

Data Table Wizard: Choose Database & Table

1

23

Page 8: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

8

43

Data Table Wizard: Choose Database & Table

customersfilmsrentssequence

44

Data Table Wizard: Displayed Fields

nameaddresscode

45

Data Table Wizard: Table Properties

46

Data Table Wizard: SQL

You can add a valid WHERE clause here.

47 48

Double Click ontable to edit it.

Page 9: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

9

49

Bringing up the CustomersForm

CustomersForm

50

Creating a New Slot

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

51

Connections

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

52

Further Slots

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

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

53

Further Connections

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

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")));

}

mainform.ui.h

Page 10: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

10

55

Implementation: slotTableFilms()

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." );

}

mainform.ui.h

56

DataTable: Signals

57

New Slot: slotPrimeInsert()

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

Edit/Slots …

58

Connection

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));}

}

customerform.ui.h

60

Controlling Data Entry

Page 11: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

11

61

Slot: slotCurrentChanged()

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

62

Function: setMode()

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 );

}

customerform.ui.h

64

Compile & Run

65

Compile & Run

66

Page 12: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

12

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.cpp70

FilmSqlCursor - Definition

#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.

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);

}

filmsqlcursor.cpp

The field „available” is a calculated field.

72

Classes

QSqlCursor

FilmSqlCursorQDataTable

FilmDataTable

QMainWindow

Videoteka

main.cpp

Page 13: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

13

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;

};

filmdatatable.h

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

75

FilmDataTable: Constructor /BasicsFilmDataTable::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"

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.cpp

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

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

77

FilmDataTable: Constructor / ConnectionsFilmDataTable::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.cpp

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

}

filmdatatable.cpp

Page 14: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

14

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");

}

}

filmdatatable.cpp

Default values starting insertion.

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.!")));

}}

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 );else

cursor->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) ;

}}

filmdatatable.cpp

83

FilmSqlEditorFactory: Definition(embedded!)

class FilmSqlEditorFactory : public QSqlEditorFactory{

Q_OBJECTpublic:

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

filmdatatable.h

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 );

}. . .

filmdatatable.cpp

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

TypePicker Editor

Page 15: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

15

85

ReadOnlyEdit Class

#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);

}

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 );

};

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 );}

TypePicker Class: Definition

typepicker.h

read()

write()

88

Reads and writesReadingGenerates#includesToolGenerated source fileRevision controlled source file

SummaryQt

designer

UIC

form.cpp main.cpp

form.ui

form.h

form.ui

Application specific functions can be given

in form.ui.h file.

form.ui.h

89

Summary: Creating Dialogs

90

Summary: Creating Main Windows

Page 16: C++ GUI Programming with Qt 3 · Creating the „Videoteka” project File/New 20 Creating the Main Window File/New 21 Wizard: Choose menus and toolbars We don’t need these „services”

16

91

Summary: Database Related Application

92