SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
Темы лекции: Базы данных в Qt.
Практическое задание: Базы данных в Qt.
Тренер: Игорь Шкулипа, к.т.н.
С++ Библиотеки STL и Qt. Занятие 5
http://www.slideshare.net/IgorShkulipa 2
Адаптер
Паттерн Adapter, представляет собой программную обертку над
существующими классами, преобразуя их интерфейсы к виду,
пригодному для последующего использования.
Пусть класс, интерфейс которого нужно адаптировать к нужному
виду, имеет имя Adaptee. Для решения задачи преобразования
его интерфейса паттерн Adapter вводит следующую иерархию
классов:
◦ Виртуальный базовый класс Target. Здесь объявляется
пользовательский интерфейс подходящего вида. Только этот
интерфейс доступен для пользователя.
◦ Производный класс Adapter, реализующий интерфейс Target.
В этом классе также имеется указатель или ссылка на
экземпляр Adaptee. Паттерн Adapter использует этот
указатель для перенаправления клиентских вызовов в
Adaptee. Так как интерфейсы Adaptee и Target несовместимы
между собой, то эти вызовы обычно требуют
преобразования.
http://www.slideshare.net/IgorShkulipa 3
Пример. Преобразование строки в структуру
class InputStringFullName {
protected:
string _strText;
public:
InputStringFullName() {
_strText="";
}
void Input() {
cout<<"Input Full Name (Surname Name MiddleName): ";
char* cstr=new char;
cin.getline(cstr, 9999, 'n');
_strText=string(cstr);
}
string GetText(){return _strText;}
};
http://www.slideshare.net/IgorShkulipa 4
Класс структуры
class FullName {
private:
string _strName; string _strSurname; string _strMiddle;
public:
FullName(string strSurname, string strName, string strMiddleName) {
_strName=strName; _strSurname=strSurname; _strMiddle=strMiddleName;
}
void Print() {
cout<<"Name: "<<_strName<<"n";
cout<<"Middle Name: "<<_strMiddle<<"n";
cout<<"Surname: "<<_strSurname<<"n";
}
string GetName() {return _strName;}
string GetSurname() {return _strSurname;}
string GetMiddle() {return _strMiddle;}
void SetName(string strText) {_strName=strText;}
void SetSurname(string strText) {_strSurname=strText;}
void SetMiddle(string strText) {_strMiddle=strText;}
};
http://www.slideshare.net/IgorShkulipa 5
Класс-адаптер
class FullNameAdapter: public InputStringFullName
{
public:
FullNameAdapter(InputStringFullName* stringFullName)
{
_strText=stringFullName->GetText();
}
FullName* GetFullName()
{
unsigned iFirstSpace=_strText.find_first_of(" ");
string strSurname=_strText.substr(0,iFirstSpace);
unsigned iSecondSpace=
_strText.substr(iFirstSpace+1).find_first_of(" ")+iFirstSpace+1;
string strName=_strText.substr(iFirstSpace, iSecondSpace-iFirstSpace);
string strMiddle=_strText.substr(iSecondSpace);
return new FullName(strSurname, strName, strMiddle);
}
};
http://www.slideshare.net/IgorShkulipa 6
Использование адаптера
int main()
{
InputStringFullName* isfn=new InputStringFullName();
isfn->Input();
FullNameAdapter* fna=new FullNameAdapter(isfn);
FullName* fn=fna->GetFullName();
fn->Print();
}
Результат:
Input Full Name (Surname Name MiddleName): Ivanov Petr Sidorovich
Name: Petr
Middle Name: Sidorovich
Surname: Ivanov
http://www.slideshare.net/IgorShkulipa 7
Команда
Паттерн Command преобразовывает запрос на выполнение
действия в отдельный объект-команду. Такая инкапсуляция
позволяет передавать эти действия другим функциям и
объектам в качестве параметра, приказывая им выполнить
запрошенную операцию. Команда – это объект, поэтому над
ней допустимы любые операции, что и над объектом.
Команда используется, если:
◦ Система управляется событиями. При появлении такого
события (запроса) необходимо выполнить определенную
последовательность действий.
◦ Необходимо параметризировать объекты выполняемым
действием, ставить запросы в очередь или поддерживать
операции отмены и повтора действий.
◦ Нужен объектно-ориентированный аналог функции
обратного вызова в процедурном программировании.
http://www.slideshare.net/IgorShkulipa 8
Пример. Интерфейс «Игра»
class IGame
{
public:
virtual void New()=0;
virtual void Start()=0;
virtual void Pause()=0;
virtual void Resume()=0;
virtual void Finish()=0;
virtual void Break()=0;
virtual void BreakAndFinish()=0;
virtual void BreakAndStart()=0;
};
http://www.slideshare.net/IgorShkulipa 9
Реализация интерфейса
class SomeGame: public IGame {
public:
virtual void New() {
cout<< "New Game.n“; }
virtual void Start() {
cout<< "Game Started.n“; }
virtual void Pause() {
cout<< "Game Paused.n“; }
virtual void Resume() {
cout<< "Game Resumed.n“; }
virtual void Finish() {
cout<< "Game Finished.n“; }
virtual void Break() {
cout<< "Game Breaked.n“; }
virtual void BreakAndFinish() {
this->Break(); this->Finish(); }
virtual void BreakAndStart() {
this->Break(); this->New(); this->Start(); }
};
http://www.slideshare.net/IgorShkulipa 10
Классы команд
class ICommand {
public:
ICommand(IGame* game){ _game=game; }
virtual void ExecuteCommand()=0;
virtual ~ICommand(){ delete _game;}
protected: IGame* _game;
};
class NewCommand: public ICommand {
public:
NewCommand(IGame* game):ICommand(game){}
virtual void ExecuteCommand(){
cout<<"Executing New Command...n";
_game->New();
} };
class StartCommand: public ICommand {
public:
StartCommand(IGame* game):ICommand(game){}
virtual void ExecuteCommand() {
cout<<"Executing Start Command...n";
_game->Start();
} };
http://www.slideshare.net/IgorShkulipa 11
Классы команд
class PauseCommand: public ICommand {
public:
PauseCommand(IGame* game):ICommand(game){}
virtual void ExecuteCommand() {
cout<<"Executing Pause Command...n";
_game->Pause();
} };
class ResumeCommand: public ICommand {
public:
ResumeCommand(IGame* game):ICommand(game){}
virtual void ExecuteCommand() {
cout<<"Executing Resume Command...n";
_game->Resume();
} };
class FinishCommand: public ICommand {
public:
FinishCommand(IGame* game) :ICommand(game){}
virtual void ExecuteCommand() {
cout<<"Executing Finish Command...n";
_game->Finish();
} };
http://www.slideshare.net/IgorShkulipa 12
Классы команд
class BreakCommand: public ICommand {
public:
BreakCommand(IGame* game):ICommand(game){}
virtual void ExecuteCommand() {
cout<<"Executing Break Command...n";
_game->Break();
} };
class BreakAndFinishCommand: public ICommand {
public:
BreakAndFinishCommand(IGame* game):ICommand(game){}
virtual void ExecuteCommand() {
cout<<"Executing Break And Finish Command...n";
_game->BreakAndFinish();
} };
class BreakAndStartCommand: public ICommand {
public:
BreakAndStartCommand(IGame* game) :ICommand(game){}
virtual void ExecuteCommand() {
cout<<"Executing Break And Start Command...n";
_game->BreakAndStart();
} };
http://www.slideshare.net/IgorShkulipa 13
Использование команд
int main()
{
IGame* someGame=new SomeGame();
ICommand* command[10];
command[0]=new NewCommand(someGame);
command[1]=new StartCommand(someGame);
command[2]=new BreakCommand(someGame);
command[3]=new NewCommand(someGame);
command[4]=new StartCommand(someGame);
command[5]=new BreakAndStartCommand(someGame);
command[6]=new PauseCommand(someGame);
command[7]=new ResumeCommand(someGame);
command[8]=new PauseCommand(someGame);
command[9]=new BreakAndFinishCommand(someGame);
for (int i=0;i<10;i++)
{
command[i]->ExecuteCommand();
}
}
Результат:
Executing New Command...
New Game.
Executing Start Command...
Game Started.
Executing Break Command...
Game Breaked.
Executing New Command...
New Game.
Executing Start Command...
Game Started.
Executing Break And Start Command...
Game Breaked.
New Game.
Game Started.
Executing Pause Command...
Game Paused.
Executing Resume Command...
Game Resumed.
Executing Pause Command...
Game Paused.
Executing Break And Finish Command...
Game Breaked.
Game Finished.
http://www.slideshare.net/IgorShkulipa 14
Подключение к базе
Класс QSqlDatabase предоставляет интерфейс для подключения к базе
данных через соединение. Экземпляр класса QSqlDatabase
представляет соединение. Соединение предоставляет доступ к базе
данных через один из поддерживаемых драйверов баз данных,
которые унаследованы от QSqlDriver. В качестве альтернативы,
можно создать класс-наследник от QSqlDriver для драйвера своей базы
данных.
Создать соединение можно с помощью одной из статических функций
addDatabase(), которой передается используемый драйвер или тип
драйвера и имя соединения.
Соединение известно под своим собственным именем, а не по имени базы
данных с которой оно соединяет. Можно иметь множество соединений
с одной и той же базой данных.
QSqlDatabase также поддерживает концепцию соединения по умолчанию,
которое является неименованным (unnamed) соединением. Чтобы
создать соединения по умолчанию при вызове addDatabase() не
передавайте аргумент с именем соединения.
http://www.slideshare.net/IgorShkulipa 15
Драйвера баз данных Qt
Тип драйвера Описание
QDB2 IBM DB2
QIBASE Драйвер Borland InterBase
QMYSQL Драйвер MySQL
QOCI Драйвер Oracle Call Interface
QODBC Драйвер ODBC (включая Microsoft SQL Server)
QPSQL Драйвер PostgreSQL
QSQLITE SQLite версии 3 или выше
QSQLITE2 SQLite версии 2
QTDS Драйвер Sybase Adaptive Server
http://www.slideshare.net/IgorShkulipa 16
Пример соединения
QSqlDatabase db = QSqlDatabase::addDatabase(“QMYSQL”);
db.setHostName(“somehost.com”);
db.setDatabaseName(“mydb”);
db.setUserName(“admin”);
db.setPassword(“pjgf”);
bool ok = db.open();
http://www.slideshare.net/IgorShkulipa 17
Выполнение запросов
Класс QSqlQuery предоставляет возможность выполнения любой
инструкции SQL, поддерживаемой используемой базой данных.
Перемещения по записям осуществляется следующими методами:
• next()
• previous()
• first()
• last()
• seek()
Эти функции позволяют двигаться вперед, назад или произвольно по
записям, возвращаемым запросом.
Если вам нужно двигаться только вперед по результатам, можно
использовать setForwardOnly(), что позволит сэкономить
значительный объем памяти, снизить накладные расходы и повысить
производительность на некоторых базах данных.
Если активный запрос находится на действительной записи, данные
можно получить с помощью value(). Все данные передаются из
внутреннего интерфейса SQL с использованием QVariant.
http://www.slideshare.net/IgorShkulipa 18
Пример запроса
QSqlQuery query;
query.exec("SELECT u_name FROM users");
while (query.next()) {
QString name = query.value(0).toString();
doSomething(name);
}
http://www.slideshare.net/IgorShkulipa 19
Проверка ошибок запроса
Можно проверить наличие ошибок запроса, вызвав метод IsActive()
if (!query.isActive())
{
QMessageBox *mb=new QMessageBox();
mb->setText(query.lastError().text());
mb->show();
}
http://www.slideshare.net/IgorShkulipa 20
Запрос вставки данных
Запросы INSERT, UPDATE, DELETE и DROP выполняются так же, как и
SELECT (передаются в текстовом виде).
QSqlQuery query;
query.exec(“INSERT INTO users VALUES(1, ‘User1’, ‘Password1’)”);
или
QSqlQuery query(“INSERT INTO users VALUES(1, ‘User1’, ‘Password1’)”);
После этого метод numRowsAffected() возвращает количество строк,
которые были изменены инструкцией запроса или -1 в случае ошибки.
http://www.slideshare.net/IgorShkulipa 21
Вставка по позициям
Если необходимо избежать преобразования значений в строковые
данные, то можно воспользоваться методом prepare() для создания
шаблона запроса с последующим присваиванием данных.
QSqlQuery q;
q.prepare(
"INSERT INTO users (u_id, u_name, u_password)
VALUES (?,?,?)");
q.addBindValue(1);
q.addBindValue(“User1”);
q.addBindValue(“Password1”);
q.exec();
http://www.slideshare.net/IgorShkulipa 22
Пример. См. Предыдущую презентацию.
Дополнение к проекту «MVP»:
• Добавлен сигнал к IView - virtual void onRegister()=0;
• Добавлен слот к презентеру - void Register();
• Добавлен метод в модель –
void InsertUser(QString user, QString password);
• Добавлено два приватный метода в модель –
void insertQueryTextStyle(QString user, QString password);
void insertQueryPositionStyle(QString user, QString password);
• Добавлена кнопка регистрации на основное окно.
http://www.slideshare.net/IgorShkulipa 23
Класс-одиночка «Подключение к базе»
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlDriver>
class DBConnection
{
public:
static DBConnection* GetInstance(){
if (_connection==NULL) _connection= new DBConnection();
return _connection;
}
~DBConnection();
QSqlQuery execQuery(QString queryText);
private:
DBConnection();
static DBConnection* _connection;
QSqlDatabase _database;
};
http://www.slideshare.net/IgorShkulipa 24
Реализация подключения
#include "dbconnection.h"
#include <QtDebug>
#include <QSqlError>
DBConnection* DBConnection::_connection=NULL;
DBConnection::DBConnection(){
_database=QSqlDatabase::addDatabase("QODBC3");
_database.setHostName("localhost");
_database.setDatabaseName(
"Driver={Microsoft Access Driver (*.mdb, *.accdb)};
DSN='';DBQ=D:aqtdb.accdb");
_database.setUserName("");
_database.setPassword("");
if (!_database.open())
{qDebug() << _database.lastError().text();}
}
QSqlQuery DBConnection::execQuery(QString queryText){
return QSqlQuery(queryText);
}
DBConnection::~DBConnection(){
_database.close();
}
http://www.slideshare.net/IgorShkulipa 25
Новый конструктор модели
Model::Model()
{
DBConnection* db= DBConnection::GetInstance();
QSqlQuery q= db->execQuery
("SELECT u_id, u_name, u_password FROM users;");
if (!q.isActive())
{
qDebug() << q.lastError().text());
}
if (q.isActive())
{
while(q.next())
{
QString uname=q.value(1).toString();
QString upass=q.value(2).toString();
usersAndPasswords.insert(uname, upass);
}
}
}
http://www.slideshare.net/IgorShkulipa 26
Методы вставки
void Model::insertQueryPositionStyle(QString user, QString password) {
QSqlQuery q;
q.prepare("INSERT INTO users (u_name, u_password) VALUES (?,?)");
q.addBindValue(user);
q.addBindValue(password);
q.exec();
}
void Model::insertQueryTextStyle(QString user, QString password) {
QSqlQuery q
("INSERT INTO users (u_name, u_password) VALUES
('"+user+"','"+password+"');");
if (!q.isActive())
{
qDebug() << q.lastError().text());
}
}
void Model::InsertUser(QString user, QString password) {
insertQueryPositionStyle(user, password);
}
http://www.slideshare.net/IgorShkulipa 27
Результат
http://www.slideshare.net/IgorShkulipa 28
QSqlTableModel
Кроме QSqlQuery, Qt содержит класс QSqlTableModel – это интерфейс
высокого уровня, который позволяет не использовать SQL в чистом
виде для выполнения запросов.
QSqlTableModel model;
model.setTable(“users”);
model.setFilter(“id>10”);
model.select();
Просмотр результата запроса осуществляется с помощью метода record()
и доступа к отдельным полям с помощью метода value().
Метод value() принимает в качестве аргумента либо индекс поля, либо его
имя.
QSqtring user=model.record().value(1).toString();
QSqtring password=model.record().value(“u_password”).toString();
http://www.slideshare.net/IgorShkulipa 29
Вставка данных
Для вставки данных можно воспользоваться методом insertRows() для
создания новой пустой строки в таблице, а затем использовать
setData() для установки значения каждого столбца.
QSqlTableModel model;
model.setTable(“users”);
int row=0;
model.insertRows(row, 1);
model.setData(model.index(row,0), 1);
model.setData(model.index(row,0), “User1”);
model.setData(model.index(row,0), “Password1”);
model.submitAll();
http://www.slideshare.net/IgorShkulipa 30
Шаблон интерфейса «master-detail»
Классическим примером для любого средства разработки интерфейса к
БД является отражение связи "родитель-потомок" (Mater-Detail).
http://www.slideshare.net/IgorShkulipa 31
Пример. Основное окно
http://www.slideshare.net/IgorShkulipa 32
Пример. База данных
http://www.slideshare.net/IgorShkulipa 33
Заголовок окна
#include <QMainWindow>
#include <QModelIndex>
#include <QSqlTableModel>
#include <QSqlRelationalTableModel>
#include <QSqlDatabase>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_tableView_clicked(const QModelIndex &index);
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
QSqlRelationalTableModel* masterModel;
QSqlTableModel* detailModel;
};
http://www.slideshare.net/IgorShkulipa 34
Реализация окна
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QSqlError>
#include <QSqlRecord>
#include <QAbstractItemView>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
QSqlDatabase database=QSqlDatabase::addDatabase("QODBC3");
database.setHostName("localhost");
database.setDatabaseName
("Driver={Microsoft Access Driver (*.mdb, *.accdb)};
DSN='';DBQ=D:aqtdb.accdb");
database.setUserName(""); database.setPassword("");
if (!database.open()) {qDebug() << database.lastError().text();}
masterModel=new QSqlRelationalTableModel(this, database);
detailModel=new QSqlTableModel(this, database);
}
MainWindow::~MainWindow() {
delete ui;
delete masterModel;
delete detailModel;
}
http://www.slideshare.net/IgorShkulipa 35
Реализация окна
void MainWindow::on_tableView_clicked(const QModelIndex &index) {
detailModel->setTable("people");
detailModel->setFilter(QString("p_uid=%1").arg(index.row()+1));
detailModel->select();
QString text="";
if (detailModel->rowCount()>0) {
text+=detailModel->record(0).value(0).toString()+"n";
text+=detailModel->record(0).value(1).toString()+"n";
text+=detailModel->record(0).value(2).toString()+"n";
text+=detailModel->record(0).value(3).toString()+"n";
text+=detailModel->record(0).value(4).toString();
}
ui->textEdit->setText(text);
}
void MainWindow::on_pushButton_clicked() {
masterModel->setTable("users");
masterModel->setRelation(0, QSqlRelation("people", "p_id", "p_name"));
masterModel->setHeaderData(0, Qt::Horizontal, "Name");
masterModel->setHeaderData(1, Qt::Horizontal, "User");
masterModel->setHeaderData(2, Qt::Horizontal, "Password");
masterModel->select();
ui->tableView->setModel(masterModel);
}
http://www.slideshare.net/IgorShkulipa 36
Результат
http://www.slideshare.net/IgorShkulipa 37
Лабораторная работа №5. Базы данных
Добавить к тетрису возможность регистрации пользователей и ведения
полученных очков.
Реализовать отображение пользователей, отсортированных по рейтингу,
на основном окне приложения с применением шаблона «master-detail»

Contenu connexe

Tendances

C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 06.C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 06.Igor Shkulipa
 
C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.Igor Shkulipa
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5Technopark
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3Technopark
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6Technopark
 
Ввведение в java
Ввведение в javaВвведение в java
Ввведение в javaUnguryan Vitaliy
 
Java. Многопоточность.
Java. Многопоточность.Java. Многопоточность.
Java. Многопоточность.Unguryan Vitaliy
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверPlatonov Sergey
 
Введение в язык программирования «Java»
Введение в язык программирования «Java»Введение в язык программирования «Java»
Введение в язык программирования «Java»Unguryan Vitaliy
 
Java осень 2014 занятие 8
Java осень 2014 занятие 8Java осень 2014 занятие 8
Java осень 2014 занятие 8Technopark
 
Сетевое взаимодействие
Сетевое взаимодействиеСетевое взаимодействие
Сетевое взаимодействиеUnguryan Vitaliy
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Dima Dzuba
 
Введение в сетевые технологии
Введение в сетевые технологииВведение в сетевые технологии
Введение в сетевые технологииUnguryan Vitaliy
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETDev2Dev
 
Java осень 2014 занятие 7
Java осень 2014 занятие 7Java осень 2014 занятие 7
Java осень 2014 занятие 7Technopark
 

Tendances (19)

C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 06.C++ STL & Qt. Занятие 06.
C++ STL & Qt. Занятие 06.
 
C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6
 
Ввведение в java
Ввведение в javaВвведение в java
Ввведение в java
 
Java. Многопоточность.
Java. Многопоточность.Java. Многопоточность.
Java. Многопоточность.
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 
Сервлеты
СервлетыСервлеты
Сервлеты
 
Введение в язык программирования «Java»
Введение в язык программирования «Java»Введение в язык программирования «Java»
Введение в язык программирования «Java»
 
Java осень 2014 занятие 8
Java осень 2014 занятие 8Java осень 2014 занятие 8
Java осень 2014 занятие 8
 
Bytecode
BytecodeBytecode
Bytecode
 
Сетевое взаимодействие
Сетевое взаимодействиеСетевое взаимодействие
Сетевое взаимодействие
 
Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.Архитектура. Доступноять программных систем.
Архитектура. Доступноять программных систем.
 
Введение в сетевые технологии
Введение в сетевые технологииВведение в сетевые технологии
Введение в сетевые технологии
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
java
javajava
java
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
 
Java осень 2014 занятие 7
Java осень 2014 занятие 7Java осень 2014 занятие 7
Java осень 2014 занятие 7
 

En vedette

C# Desktop. Занятие 07.
C# Desktop. Занятие 07.C# Desktop. Занятие 07.
C# Desktop. Занятие 07.Igor Shkulipa
 
C# Desktop. Занятие 15.
C# Desktop. Занятие 15.C# Desktop. Занятие 15.
C# Desktop. Занятие 15.Igor Shkulipa
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.Igor Shkulipa
 
16 FACTS ABOUT CHOCOLATE
16 FACTS ABOUT CHOCOLATE16 FACTS ABOUT CHOCOLATE
16 FACTS ABOUT CHOCOLATENisha Thinisha
 
Trabajo completo correcion
Trabajo completo correcionTrabajo completo correcion
Trabajo completo correcionIda Morán
 
Production diary 8
Production diary 8Production diary 8
Production diary 8Laila Jaleel
 
Production diary 3
Production diary 3Production diary 3
Production diary 3Laila Jaleel
 
C++ Базовый. Занятие 14.
C++ Базовый. Занятие 14.C++ Базовый. Занятие 14.
C++ Базовый. Занятие 14.Igor Shkulipa
 
Fotos de la tesis
Fotos de la tesisFotos de la tesis
Fotos de la tesisIda Morán
 
Vijay Bhosekar_ Research Article_ Frontiers in Plant Science
Vijay Bhosekar_ Research Article_ Frontiers in Plant ScienceVijay Bhosekar_ Research Article_ Frontiers in Plant Science
Vijay Bhosekar_ Research Article_ Frontiers in Plant Sciencevijay bhosekar
 
JavaScript Базовый. Занятие 05.
JavaScript Базовый. Занятие 05.JavaScript Базовый. Занятие 05.
JavaScript Базовый. Занятие 05.Igor Shkulipa
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.Igor Shkulipa
 
Production diary 19
Production diary 19Production diary 19
Production diary 19Laila Jaleel
 
Organists Review.compressed
Organists Review.compressedOrganists Review.compressed
Organists Review.compressedJamie Singleton
 
σχέδιο προσέγγισης λογοτεχνικού κειμένου
σχέδιο προσέγγισης λογοτεχνικού κειμένουσχέδιο προσέγγισης λογοτεχνικού κειμένου
σχέδιο προσέγγισης λογοτεχνικού κειμένουMANOLIS MORAITIS
 
Modern Arabian Horse mag 2012 "Destination: Tulsa"
Modern Arabian Horse mag 2012 "Destination: Tulsa"Modern Arabian Horse mag 2012 "Destination: Tulsa"
Modern Arabian Horse mag 2012 "Destination: Tulsa"Janet de Acevedo Macdonald
 
Production diary 2
Production diary 2Production diary 2
Production diary 2Laila Jaleel
 

En vedette (20)

C# Desktop. Занятие 07.
C# Desktop. Занятие 07.C# Desktop. Занятие 07.
C# Desktop. Занятие 07.
 
C# Desktop. Занятие 15.
C# Desktop. Занятие 15.C# Desktop. Занятие 15.
C# Desktop. Занятие 15.
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.
 
16 FACTS ABOUT CHOCOLATE
16 FACTS ABOUT CHOCOLATE16 FACTS ABOUT CHOCOLATE
16 FACTS ABOUT CHOCOLATE
 
Trabajo completo correcion
Trabajo completo correcionTrabajo completo correcion
Trabajo completo correcion
 
Production diary 8
Production diary 8Production diary 8
Production diary 8
 
Production diary 3
Production diary 3Production diary 3
Production diary 3
 
C++ Базовый. Занятие 14.
C++ Базовый. Занятие 14.C++ Базовый. Занятие 14.
C++ Базовый. Занятие 14.
 
Fotos de la tesis
Fotos de la tesisFotos de la tesis
Fotos de la tesis
 
Vijay Bhosekar_ Research Article_ Frontiers in Plant Science
Vijay Bhosekar_ Research Article_ Frontiers in Plant ScienceVijay Bhosekar_ Research Article_ Frontiers in Plant Science
Vijay Bhosekar_ Research Article_ Frontiers in Plant Science
 
JavaScript Базовый. Занятие 05.
JavaScript Базовый. Занятие 05.JavaScript Базовый. Занятие 05.
JavaScript Базовый. Занятие 05.
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.
 
Production diary 19
Production diary 19Production diary 19
Production diary 19
 
assignment
assignmentassignment
assignment
 
Organists Review.compressed
Organists Review.compressedOrganists Review.compressed
Organists Review.compressed
 
σχέδιο προσέγγισης λογοτεχνικού κειμένου
σχέδιο προσέγγισης λογοτεχνικού κειμένουσχέδιο προσέγγισης λογοτεχνικού κειμένου
σχέδιο προσέγγισης λογοτεχνικού κειμένου
 
Modern Arabian Horse mag 2012 "Destination: Tulsa"
Modern Arabian Horse mag 2012 "Destination: Tulsa"Modern Arabian Horse mag 2012 "Destination: Tulsa"
Modern Arabian Horse mag 2012 "Destination: Tulsa"
 
Production diary 2
Production diary 2Production diary 2
Production diary 2
 
CV
CVCV
CV
 
Nowhere But Niigata
Nowhere But NiigataNowhere But Niigata
Nowhere But Niigata
 

Similaire à C++ STL & Qt. Занятие 05.

C# Desktop. Занятие 12.
C# Desktop. Занятие 12.C# Desktop. Занятие 12.
C# Desktop. Занятие 12.Igor Shkulipa
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NETVitaly Baum
 
Шаблоны разработки ПО. Часть 3. Шаблоны GoF
Шаблоны разработки ПО. Часть 3. Шаблоны GoFШаблоны разработки ПО. Часть 3. Шаблоны GoF
Шаблоны разработки ПО. Часть 3. Шаблоны GoFSergey Nemchinsky
 
Java весна 2013 лекция 8
Java весна 2013 лекция 8Java весна 2013 лекция 8
Java весна 2013 лекция 8Technopark
 
Bloch, bodoff руководство. сервлеты
Bloch, bodoff   руководство. сервлетыBloch, bodoff   руководство. сервлеты
Bloch, bodoff руководство. сервлетыalexey1991
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Fedor Malyshkin
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программированияguestfc8ae0
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)Noveo
 
C++ Базовый. Занятие 17.
C++ Базовый. Занятие 17.C++ Базовый. Занятие 17.
C++ Базовый. Занятие 17.Igor Shkulipa
 
Baseof servletsjava intro
Baseof servletsjava introBaseof servletsjava intro
Baseof servletsjava introalexey1991
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человекаNETFest
 
C# Web. Занятие 04.
C# Web. Занятие 04.C# Web. Занятие 04.
C# Web. Занятие 04.Igor Shkulipa
 
Что нового в Visual Studio 2010 и .Net 4.0
Что нового в Visual Studio 2010 и .Net 4.0Что нового в Visual Studio 2010 и .Net 4.0
Что нового в Visual Studio 2010 и .Net 4.0akrakovetsky
 
Dependency Injection в Java на примере эволюции Spring — Guice — CDI/Weld
Dependency Injection в Java на примере эволюции Spring — Guice — CDI/WeldDependency Injection в Java на примере эволюции Spring — Guice — CDI/Weld
Dependency Injection в Java на примере эволюции Spring — Guice — CDI/WeldCUSTIS
 
ук 03.003.01 2011
ук 03.003.01 2011ук 03.003.01 2011
ук 03.003.01 2011etyumentcev
 
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Andrey Rebrov
 

Similaire à C++ STL & Qt. Занятие 05. (20)

C# Desktop. Занятие 12.
C# Desktop. Занятие 12.C# Desktop. Занятие 12.
C# Desktop. Занятие 12.
 
Jdbc in java
Jdbc in javaJdbc in java
Jdbc in java
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NET
 
Шаблоны разработки ПО. Часть 3. Шаблоны GoF
Шаблоны разработки ПО. Часть 3. Шаблоны GoFШаблоны разработки ПО. Часть 3. Шаблоны GoF
Шаблоны разработки ПО. Часть 3. Шаблоны GoF
 
Java весна 2013 лекция 8
Java весна 2013 лекция 8Java весна 2013 лекция 8
Java весна 2013 лекция 8
 
Bloch, bodoff руководство. сервлеты
Bloch, bodoff   руководство. сервлетыBloch, bodoff   руководство. сервлеты
Bloch, bodoff руководство. сервлеты
 
JDBC
JDBCJDBC
JDBC
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)
 
C++ Базовый. Занятие 17.
C++ Базовый. Занятие 17.C++ Базовый. Занятие 17.
C++ Базовый. Занятие 17.
 
Baseof servletsjava intro
Baseof servletsjava introBaseof servletsjava intro
Baseof servletsjava intro
 
RoboGuice
RoboGuiceRoboGuice
RoboGuice
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
.NET Fest 2018. Сергей Калинец. Azure веб разработка здорового человека
 
C# Web. Занятие 04.
C# Web. Занятие 04.C# Web. Занятие 04.
C# Web. Занятие 04.
 
Что нового в Visual Studio 2010 и .Net 4.0
Что нового в Visual Studio 2010 и .Net 4.0Что нового в Visual Studio 2010 и .Net 4.0
Что нового в Visual Studio 2010 и .Net 4.0
 
Dependency Injection в Java на примере эволюции Spring — Guice — CDI/Weld
Dependency Injection в Java на примере эволюции Spring — Guice — CDI/WeldDependency Injection в Java на примере эволюции Spring — Guice — CDI/Weld
Dependency Injection в Java на примере эволюции Spring — Guice — CDI/Weld
 
ук 03.003.01 2011
ук 03.003.01 2011ук 03.003.01 2011
ук 03.003.01 2011
 
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
 

Plus de Igor Shkulipa

Общие темы. Тема 03.
Общие темы. Тема 03. Общие темы. Тема 03.
Общие темы. Тема 03. Igor Shkulipa
 
Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.Igor Shkulipa
 
Общие темы. Тема 01.
Общие темы. Тема 01.Общие темы. Тема 01.
Общие темы. Тема 01.Igor Shkulipa
 
JavaScript Базовый. Занятие 06.
JavaScript Базовый. Занятие 06.JavaScript Базовый. Занятие 06.
JavaScript Базовый. Занятие 06.Igor Shkulipa
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.Igor Shkulipa
 
JavaScript Базовый. Занятие 10.
JavaScript Базовый. Занятие 10.JavaScript Базовый. Занятие 10.
JavaScript Базовый. Занятие 10.Igor Shkulipa
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.Igor Shkulipa
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.Igor Shkulipa
 
JavaScript Базовый. Занятие 01.
JavaScript Базовый. Занятие 01.JavaScript Базовый. Занятие 01.
JavaScript Базовый. Занятие 01.Igor Shkulipa
 
JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.Igor Shkulipa
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.Igor Shkulipa
 
JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.Igor Shkulipa
 
C# Web. Занятие 09.
C# Web. Занятие 09.C# Web. Занятие 09.
C# Web. Занятие 09.Igor Shkulipa
 
C# Web. Занятие 08.
C# Web. Занятие 08.C# Web. Занятие 08.
C# Web. Занятие 08.Igor Shkulipa
 
C# Web. Занятие 07.
C# Web. Занятие 07.C# Web. Занятие 07.
C# Web. Занятие 07.Igor Shkulipa
 
C# Web. Занятие 12.
C# Web. Занятие 12.C# Web. Занятие 12.
C# Web. Занятие 12.Igor Shkulipa
 
C# Web. Занятие 16.
C# Web. Занятие 16.C# Web. Занятие 16.
C# Web. Занятие 16.Igor Shkulipa
 
C# Web. Занятие 14.
C# Web. Занятие 14.C# Web. Занятие 14.
C# Web. Занятие 14.Igor Shkulipa
 
C# Web. Занятие 15.
C# Web. Занятие 15.C# Web. Занятие 15.
C# Web. Занятие 15.Igor Shkulipa
 
C# Web. Занятие 13.
C# Web. Занятие 13.C# Web. Занятие 13.
C# Web. Занятие 13.Igor Shkulipa
 

Plus de Igor Shkulipa (20)

Общие темы. Тема 03.
Общие темы. Тема 03. Общие темы. Тема 03.
Общие темы. Тема 03.
 
Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.
 
Общие темы. Тема 01.
Общие темы. Тема 01.Общие темы. Тема 01.
Общие темы. Тема 01.
 
JavaScript Базовый. Занятие 06.
JavaScript Базовый. Занятие 06.JavaScript Базовый. Занятие 06.
JavaScript Базовый. Занятие 06.
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.
 
JavaScript Базовый. Занятие 10.
JavaScript Базовый. Занятие 10.JavaScript Базовый. Занятие 10.
JavaScript Базовый. Занятие 10.
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.
 
JavaScript Базовый. Занятие 01.
JavaScript Базовый. Занятие 01.JavaScript Базовый. Занятие 01.
JavaScript Базовый. Занятие 01.
 
JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.
 
JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.
 
C# Web. Занятие 09.
C# Web. Занятие 09.C# Web. Занятие 09.
C# Web. Занятие 09.
 
C# Web. Занятие 08.
C# Web. Занятие 08.C# Web. Занятие 08.
C# Web. Занятие 08.
 
C# Web. Занятие 07.
C# Web. Занятие 07.C# Web. Занятие 07.
C# Web. Занятие 07.
 
C# Web. Занятие 12.
C# Web. Занятие 12.C# Web. Занятие 12.
C# Web. Занятие 12.
 
C# Web. Занятие 16.
C# Web. Занятие 16.C# Web. Занятие 16.
C# Web. Занятие 16.
 
C# Web. Занятие 14.
C# Web. Занятие 14.C# Web. Занятие 14.
C# Web. Занятие 14.
 
C# Web. Занятие 15.
C# Web. Занятие 15.C# Web. Занятие 15.
C# Web. Занятие 15.
 
C# Web. Занятие 13.
C# Web. Занятие 13.C# Web. Занятие 13.
C# Web. Занятие 13.
 

C++ STL & Qt. Занятие 05.

  • 1. Темы лекции: Базы данных в Qt. Практическое задание: Базы данных в Qt. Тренер: Игорь Шкулипа, к.т.н. С++ Библиотеки STL и Qt. Занятие 5
  • 2. http://www.slideshare.net/IgorShkulipa 2 Адаптер Паттерн Adapter, представляет собой программную обертку над существующими классами, преобразуя их интерфейсы к виду, пригодному для последующего использования. Пусть класс, интерфейс которого нужно адаптировать к нужному виду, имеет имя Adaptee. Для решения задачи преобразования его интерфейса паттерн Adapter вводит следующую иерархию классов: ◦ Виртуальный базовый класс Target. Здесь объявляется пользовательский интерфейс подходящего вида. Только этот интерфейс доступен для пользователя. ◦ Производный класс Adapter, реализующий интерфейс Target. В этом классе также имеется указатель или ссылка на экземпляр Adaptee. Паттерн Adapter использует этот указатель для перенаправления клиентских вызовов в Adaptee. Так как интерфейсы Adaptee и Target несовместимы между собой, то эти вызовы обычно требуют преобразования.
  • 3. http://www.slideshare.net/IgorShkulipa 3 Пример. Преобразование строки в структуру class InputStringFullName { protected: string _strText; public: InputStringFullName() { _strText=""; } void Input() { cout<<"Input Full Name (Surname Name MiddleName): "; char* cstr=new char; cin.getline(cstr, 9999, 'n'); _strText=string(cstr); } string GetText(){return _strText;} };
  • 4. http://www.slideshare.net/IgorShkulipa 4 Класс структуры class FullName { private: string _strName; string _strSurname; string _strMiddle; public: FullName(string strSurname, string strName, string strMiddleName) { _strName=strName; _strSurname=strSurname; _strMiddle=strMiddleName; } void Print() { cout<<"Name: "<<_strName<<"n"; cout<<"Middle Name: "<<_strMiddle<<"n"; cout<<"Surname: "<<_strSurname<<"n"; } string GetName() {return _strName;} string GetSurname() {return _strSurname;} string GetMiddle() {return _strMiddle;} void SetName(string strText) {_strName=strText;} void SetSurname(string strText) {_strSurname=strText;} void SetMiddle(string strText) {_strMiddle=strText;} };
  • 5. http://www.slideshare.net/IgorShkulipa 5 Класс-адаптер class FullNameAdapter: public InputStringFullName { public: FullNameAdapter(InputStringFullName* stringFullName) { _strText=stringFullName->GetText(); } FullName* GetFullName() { unsigned iFirstSpace=_strText.find_first_of(" "); string strSurname=_strText.substr(0,iFirstSpace); unsigned iSecondSpace= _strText.substr(iFirstSpace+1).find_first_of(" ")+iFirstSpace+1; string strName=_strText.substr(iFirstSpace, iSecondSpace-iFirstSpace); string strMiddle=_strText.substr(iSecondSpace); return new FullName(strSurname, strName, strMiddle); } };
  • 6. http://www.slideshare.net/IgorShkulipa 6 Использование адаптера int main() { InputStringFullName* isfn=new InputStringFullName(); isfn->Input(); FullNameAdapter* fna=new FullNameAdapter(isfn); FullName* fn=fna->GetFullName(); fn->Print(); } Результат: Input Full Name (Surname Name MiddleName): Ivanov Petr Sidorovich Name: Petr Middle Name: Sidorovich Surname: Ivanov
  • 7. http://www.slideshare.net/IgorShkulipa 7 Команда Паттерн Command преобразовывает запрос на выполнение действия в отдельный объект-команду. Такая инкапсуляция позволяет передавать эти действия другим функциям и объектам в качестве параметра, приказывая им выполнить запрошенную операцию. Команда – это объект, поэтому над ней допустимы любые операции, что и над объектом. Команда используется, если: ◦ Система управляется событиями. При появлении такого события (запроса) необходимо выполнить определенную последовательность действий. ◦ Необходимо параметризировать объекты выполняемым действием, ставить запросы в очередь или поддерживать операции отмены и повтора действий. ◦ Нужен объектно-ориентированный аналог функции обратного вызова в процедурном программировании.
  • 8. http://www.slideshare.net/IgorShkulipa 8 Пример. Интерфейс «Игра» class IGame { public: virtual void New()=0; virtual void Start()=0; virtual void Pause()=0; virtual void Resume()=0; virtual void Finish()=0; virtual void Break()=0; virtual void BreakAndFinish()=0; virtual void BreakAndStart()=0; };
  • 9. http://www.slideshare.net/IgorShkulipa 9 Реализация интерфейса class SomeGame: public IGame { public: virtual void New() { cout<< "New Game.n“; } virtual void Start() { cout<< "Game Started.n“; } virtual void Pause() { cout<< "Game Paused.n“; } virtual void Resume() { cout<< "Game Resumed.n“; } virtual void Finish() { cout<< "Game Finished.n“; } virtual void Break() { cout<< "Game Breaked.n“; } virtual void BreakAndFinish() { this->Break(); this->Finish(); } virtual void BreakAndStart() { this->Break(); this->New(); this->Start(); } };
  • 10. http://www.slideshare.net/IgorShkulipa 10 Классы команд class ICommand { public: ICommand(IGame* game){ _game=game; } virtual void ExecuteCommand()=0; virtual ~ICommand(){ delete _game;} protected: IGame* _game; }; class NewCommand: public ICommand { public: NewCommand(IGame* game):ICommand(game){} virtual void ExecuteCommand(){ cout<<"Executing New Command...n"; _game->New(); } }; class StartCommand: public ICommand { public: StartCommand(IGame* game):ICommand(game){} virtual void ExecuteCommand() { cout<<"Executing Start Command...n"; _game->Start(); } };
  • 11. http://www.slideshare.net/IgorShkulipa 11 Классы команд class PauseCommand: public ICommand { public: PauseCommand(IGame* game):ICommand(game){} virtual void ExecuteCommand() { cout<<"Executing Pause Command...n"; _game->Pause(); } }; class ResumeCommand: public ICommand { public: ResumeCommand(IGame* game):ICommand(game){} virtual void ExecuteCommand() { cout<<"Executing Resume Command...n"; _game->Resume(); } }; class FinishCommand: public ICommand { public: FinishCommand(IGame* game) :ICommand(game){} virtual void ExecuteCommand() { cout<<"Executing Finish Command...n"; _game->Finish(); } };
  • 12. http://www.slideshare.net/IgorShkulipa 12 Классы команд class BreakCommand: public ICommand { public: BreakCommand(IGame* game):ICommand(game){} virtual void ExecuteCommand() { cout<<"Executing Break Command...n"; _game->Break(); } }; class BreakAndFinishCommand: public ICommand { public: BreakAndFinishCommand(IGame* game):ICommand(game){} virtual void ExecuteCommand() { cout<<"Executing Break And Finish Command...n"; _game->BreakAndFinish(); } }; class BreakAndStartCommand: public ICommand { public: BreakAndStartCommand(IGame* game) :ICommand(game){} virtual void ExecuteCommand() { cout<<"Executing Break And Start Command...n"; _game->BreakAndStart(); } };
  • 13. http://www.slideshare.net/IgorShkulipa 13 Использование команд int main() { IGame* someGame=new SomeGame(); ICommand* command[10]; command[0]=new NewCommand(someGame); command[1]=new StartCommand(someGame); command[2]=new BreakCommand(someGame); command[3]=new NewCommand(someGame); command[4]=new StartCommand(someGame); command[5]=new BreakAndStartCommand(someGame); command[6]=new PauseCommand(someGame); command[7]=new ResumeCommand(someGame); command[8]=new PauseCommand(someGame); command[9]=new BreakAndFinishCommand(someGame); for (int i=0;i<10;i++) { command[i]->ExecuteCommand(); } } Результат: Executing New Command... New Game. Executing Start Command... Game Started. Executing Break Command... Game Breaked. Executing New Command... New Game. Executing Start Command... Game Started. Executing Break And Start Command... Game Breaked. New Game. Game Started. Executing Pause Command... Game Paused. Executing Resume Command... Game Resumed. Executing Pause Command... Game Paused. Executing Break And Finish Command... Game Breaked. Game Finished.
  • 14. http://www.slideshare.net/IgorShkulipa 14 Подключение к базе Класс QSqlDatabase предоставляет интерфейс для подключения к базе данных через соединение. Экземпляр класса QSqlDatabase представляет соединение. Соединение предоставляет доступ к базе данных через один из поддерживаемых драйверов баз данных, которые унаследованы от QSqlDriver. В качестве альтернативы, можно создать класс-наследник от QSqlDriver для драйвера своей базы данных. Создать соединение можно с помощью одной из статических функций addDatabase(), которой передается используемый драйвер или тип драйвера и имя соединения. Соединение известно под своим собственным именем, а не по имени базы данных с которой оно соединяет. Можно иметь множество соединений с одной и той же базой данных. QSqlDatabase также поддерживает концепцию соединения по умолчанию, которое является неименованным (unnamed) соединением. Чтобы создать соединения по умолчанию при вызове addDatabase() не передавайте аргумент с именем соединения.
  • 15. http://www.slideshare.net/IgorShkulipa 15 Драйвера баз данных Qt Тип драйвера Описание QDB2 IBM DB2 QIBASE Драйвер Borland InterBase QMYSQL Драйвер MySQL QOCI Драйвер Oracle Call Interface QODBC Драйвер ODBC (включая Microsoft SQL Server) QPSQL Драйвер PostgreSQL QSQLITE SQLite версии 3 или выше QSQLITE2 SQLite версии 2 QTDS Драйвер Sybase Adaptive Server
  • 16. http://www.slideshare.net/IgorShkulipa 16 Пример соединения QSqlDatabase db = QSqlDatabase::addDatabase(“QMYSQL”); db.setHostName(“somehost.com”); db.setDatabaseName(“mydb”); db.setUserName(“admin”); db.setPassword(“pjgf”); bool ok = db.open();
  • 17. http://www.slideshare.net/IgorShkulipa 17 Выполнение запросов Класс QSqlQuery предоставляет возможность выполнения любой инструкции SQL, поддерживаемой используемой базой данных. Перемещения по записям осуществляется следующими методами: • next() • previous() • first() • last() • seek() Эти функции позволяют двигаться вперед, назад или произвольно по записям, возвращаемым запросом. Если вам нужно двигаться только вперед по результатам, можно использовать setForwardOnly(), что позволит сэкономить значительный объем памяти, снизить накладные расходы и повысить производительность на некоторых базах данных. Если активный запрос находится на действительной записи, данные можно получить с помощью value(). Все данные передаются из внутреннего интерфейса SQL с использованием QVariant.
  • 18. http://www.slideshare.net/IgorShkulipa 18 Пример запроса QSqlQuery query; query.exec("SELECT u_name FROM users"); while (query.next()) { QString name = query.value(0).toString(); doSomething(name); }
  • 19. http://www.slideshare.net/IgorShkulipa 19 Проверка ошибок запроса Можно проверить наличие ошибок запроса, вызвав метод IsActive() if (!query.isActive()) { QMessageBox *mb=new QMessageBox(); mb->setText(query.lastError().text()); mb->show(); }
  • 20. http://www.slideshare.net/IgorShkulipa 20 Запрос вставки данных Запросы INSERT, UPDATE, DELETE и DROP выполняются так же, как и SELECT (передаются в текстовом виде). QSqlQuery query; query.exec(“INSERT INTO users VALUES(1, ‘User1’, ‘Password1’)”); или QSqlQuery query(“INSERT INTO users VALUES(1, ‘User1’, ‘Password1’)”); После этого метод numRowsAffected() возвращает количество строк, которые были изменены инструкцией запроса или -1 в случае ошибки.
  • 21. http://www.slideshare.net/IgorShkulipa 21 Вставка по позициям Если необходимо избежать преобразования значений в строковые данные, то можно воспользоваться методом prepare() для создания шаблона запроса с последующим присваиванием данных. QSqlQuery q; q.prepare( "INSERT INTO users (u_id, u_name, u_password) VALUES (?,?,?)"); q.addBindValue(1); q.addBindValue(“User1”); q.addBindValue(“Password1”); q.exec();
  • 22. http://www.slideshare.net/IgorShkulipa 22 Пример. См. Предыдущую презентацию. Дополнение к проекту «MVP»: • Добавлен сигнал к IView - virtual void onRegister()=0; • Добавлен слот к презентеру - void Register(); • Добавлен метод в модель – void InsertUser(QString user, QString password); • Добавлено два приватный метода в модель – void insertQueryTextStyle(QString user, QString password); void insertQueryPositionStyle(QString user, QString password); • Добавлена кнопка регистрации на основное окно.
  • 23. http://www.slideshare.net/IgorShkulipa 23 Класс-одиночка «Подключение к базе» #include <QtSql/QSqlDatabase> #include <QtSql/QSqlQuery> #include <QtSql/QSqlDriver> class DBConnection { public: static DBConnection* GetInstance(){ if (_connection==NULL) _connection= new DBConnection(); return _connection; } ~DBConnection(); QSqlQuery execQuery(QString queryText); private: DBConnection(); static DBConnection* _connection; QSqlDatabase _database; };
  • 24. http://www.slideshare.net/IgorShkulipa 24 Реализация подключения #include "dbconnection.h" #include <QtDebug> #include <QSqlError> DBConnection* DBConnection::_connection=NULL; DBConnection::DBConnection(){ _database=QSqlDatabase::addDatabase("QODBC3"); _database.setHostName("localhost"); _database.setDatabaseName( "Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DSN='';DBQ=D:aqtdb.accdb"); _database.setUserName(""); _database.setPassword(""); if (!_database.open()) {qDebug() << _database.lastError().text();} } QSqlQuery DBConnection::execQuery(QString queryText){ return QSqlQuery(queryText); } DBConnection::~DBConnection(){ _database.close(); }
  • 25. http://www.slideshare.net/IgorShkulipa 25 Новый конструктор модели Model::Model() { DBConnection* db= DBConnection::GetInstance(); QSqlQuery q= db->execQuery ("SELECT u_id, u_name, u_password FROM users;"); if (!q.isActive()) { qDebug() << q.lastError().text()); } if (q.isActive()) { while(q.next()) { QString uname=q.value(1).toString(); QString upass=q.value(2).toString(); usersAndPasswords.insert(uname, upass); } } }
  • 26. http://www.slideshare.net/IgorShkulipa 26 Методы вставки void Model::insertQueryPositionStyle(QString user, QString password) { QSqlQuery q; q.prepare("INSERT INTO users (u_name, u_password) VALUES (?,?)"); q.addBindValue(user); q.addBindValue(password); q.exec(); } void Model::insertQueryTextStyle(QString user, QString password) { QSqlQuery q ("INSERT INTO users (u_name, u_password) VALUES ('"+user+"','"+password+"');"); if (!q.isActive()) { qDebug() << q.lastError().text()); } } void Model::InsertUser(QString user, QString password) { insertQueryPositionStyle(user, password); }
  • 28. http://www.slideshare.net/IgorShkulipa 28 QSqlTableModel Кроме QSqlQuery, Qt содержит класс QSqlTableModel – это интерфейс высокого уровня, который позволяет не использовать SQL в чистом виде для выполнения запросов. QSqlTableModel model; model.setTable(“users”); model.setFilter(“id>10”); model.select(); Просмотр результата запроса осуществляется с помощью метода record() и доступа к отдельным полям с помощью метода value(). Метод value() принимает в качестве аргумента либо индекс поля, либо его имя. QSqtring user=model.record().value(1).toString(); QSqtring password=model.record().value(“u_password”).toString();
  • 29. http://www.slideshare.net/IgorShkulipa 29 Вставка данных Для вставки данных можно воспользоваться методом insertRows() для создания новой пустой строки в таблице, а затем использовать setData() для установки значения каждого столбца. QSqlTableModel model; model.setTable(“users”); int row=0; model.insertRows(row, 1); model.setData(model.index(row,0), 1); model.setData(model.index(row,0), “User1”); model.setData(model.index(row,0), “Password1”); model.submitAll();
  • 30. http://www.slideshare.net/IgorShkulipa 30 Шаблон интерфейса «master-detail» Классическим примером для любого средства разработки интерфейса к БД является отражение связи "родитель-потомок" (Mater-Detail).
  • 33. http://www.slideshare.net/IgorShkulipa 33 Заголовок окна #include <QMainWindow> #include <QModelIndex> #include <QSqlTableModel> #include <QSqlRelationalTableModel> #include <QSqlDatabase> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_tableView_clicked(const QModelIndex &index); void on_pushButton_clicked(); private: Ui::MainWindow *ui; QSqlRelationalTableModel* masterModel; QSqlTableModel* detailModel; };
  • 34. http://www.slideshare.net/IgorShkulipa 34 Реализация окна #include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #include <QSqlError> #include <QSqlRecord> #include <QAbstractItemView> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); QSqlDatabase database=QSqlDatabase::addDatabase("QODBC3"); database.setHostName("localhost"); database.setDatabaseName ("Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DSN='';DBQ=D:aqtdb.accdb"); database.setUserName(""); database.setPassword(""); if (!database.open()) {qDebug() << database.lastError().text();} masterModel=new QSqlRelationalTableModel(this, database); detailModel=new QSqlTableModel(this, database); } MainWindow::~MainWindow() { delete ui; delete masterModel; delete detailModel; }
  • 35. http://www.slideshare.net/IgorShkulipa 35 Реализация окна void MainWindow::on_tableView_clicked(const QModelIndex &index) { detailModel->setTable("people"); detailModel->setFilter(QString("p_uid=%1").arg(index.row()+1)); detailModel->select(); QString text=""; if (detailModel->rowCount()>0) { text+=detailModel->record(0).value(0).toString()+"n"; text+=detailModel->record(0).value(1).toString()+"n"; text+=detailModel->record(0).value(2).toString()+"n"; text+=detailModel->record(0).value(3).toString()+"n"; text+=detailModel->record(0).value(4).toString(); } ui->textEdit->setText(text); } void MainWindow::on_pushButton_clicked() { masterModel->setTable("users"); masterModel->setRelation(0, QSqlRelation("people", "p_id", "p_name")); masterModel->setHeaderData(0, Qt::Horizontal, "Name"); masterModel->setHeaderData(1, Qt::Horizontal, "User"); masterModel->setHeaderData(2, Qt::Horizontal, "Password"); masterModel->select(); ui->tableView->setModel(masterModel); }
  • 37. http://www.slideshare.net/IgorShkulipa 37 Лабораторная работа №5. Базы данных Добавить к тетрису возможность регистрации пользователей и ведения полученных очков. Реализовать отображение пользователей, отсортированных по рейтингу, на основном окне приложения с применением шаблона «master-detail»