- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
QT 4: программирование GUI на С++ - Жасмин Бланшет
Шрифт:
Интервал:
Закладка:
Ниже приводится пример использования QSqlTableModel для выполнения команды SELECT:
QSqlTableModel model;
model.setTable("cd");
model.setFilter("year >= 1998");
model.select();
Это эквивалентно запросу
SELECT * FROM cd WHERE year >= 1998
Просмотр результирующего набора выполняется путем получения заданной записи функцией QSqlTableModel::record() и доступа к отдельным полям с помощью функции value():
for (int i = 0; i < model.rowCount(); ++i) {
QSqlRecord record = model.record(i);
QString title = record.value("title").toString();
int year = record.value("year").toInt();
cerr << qPrintable(title) << ": " << year << endl;
}
Функция QSqlRecord::value() принимает либо имя поля, либо индекс поля. При работе с большими наборами данных рекомендуется задавать поля с помощью их индексов. Например:
int titleIndex = model.record().indexOf("title");
int yearIndex = model.record().indexOf("year");
for (int i = 0; i < model.rowCount(); ++i) {
QSqlRecord record = model.record(i);
QString title = record.value(titleIndex).toString();
int year = record.value(yearIndex).toInt();
cerr << qPrintable(title) << ": " << year << endl;
}
Для вставки записи в таблицу базы данных мы действуем так же, как если бы делали вставку в двумерную модель: сначала вызываем функцию insertRow() для создания новой пустой строки (записи) и затем используем setData() для установки значения каждого столбца (поля записи).
QSqlTableModel model;
model.setTable("cd");
int row = 0;
model.insertRows(row, 1);
model.setData(model.index(row, 0), 113);
model.setData(model.index(row, 1), "Shanghai My Heart");
model.setData(model.index(row, 2), 224);
model.setData(model.index(row, 3), 2003);
model.submitAll();
После вызова submitAll() запись может быть перемещена в другую позицию, зависящую от упорядоченности таблицы. Вызов submitAll() возвратит false, если вставка окажется неудачной.
Важным отличием модели SQL от стандартной модели является необходимость вызова в модели SQL функции submitAll() для записи всех изменений в базу данных
Для обновления записи мы должны сначала установить QSqlTableModel на запись, которую мы хотим модифицировать (например, используя функции select()). Затем мы извлекаем запись, обновляем соответствующие поля и записываем наши изменения обратно в базу данных:
QSqlTableModel model;
model.setTable("cd");
model.setFilter("id = 125");
model.select();
if (model.rowCount() == 1) {
QSqlRecord record = model.record(0);
record.setValue("title", "Melody A.M.");
record.setValue("year", record.value("year").toInt() + 1);
model.setRecord(0, record);
model.submitAll();
}
Если имеется запись, удовлетворяющая заданному фильтру, доступ к ней мы получаем при помощи функции QSqlTableModel::record(). Мы осуществляем наши изменения и вновь записываем в базу данных запись с новыми значениями полей.
Кроме того, обновление можно выполнить при помощи функции setData(), как это делается для модели, отличной от SQL—модели. Для получения доступа к полям записи используются индексы модели с указанием номера строки (записи) и столбца (поля):
model.select();
if (model.rowCount() == 1) {
model.setData(model.index(0, 1), "Melody A.M.");
model.setData(model.index(0, 3),
model.data(model.index(0, 3)).toInt() + 1);
model.submitAll();
}
Удаление записи напоминает ее обновление:
model.setTable("cd");
model.setFilter("id = 125");
model.select();
if (model.rowCount() == 1) {
model.removeRows(0, 1);
model.submitAll();
}
В вызове removeRows() указываются номер строки первой удаляемой записи и количество удаляемых записей. В следующем примере удаляются все записи, удовлетворяющие фильтру:
model.setTable("cd");
model.setFilter("year < 1990");
model.select();
if (model.rowCount() > 0) {
model.removeRows(0, model.rowCount());
model.submitAll();
}
Классы QSqlQuery и QSqlTableModel обеспечивают интерфейс между Qt и базой данных SQL. Используя эти классы, можно создавать формы, представляющие данные пользователям и позволяющие им вставлять, обновлять и удалять записи.
Представление данных в табличной форме
Во многих случаях табличное представление является самым простым представлением набора данных для пользователей. В этом и последующих разделах мы рассмотрим простое приложение CD Collection (Коллекция компакт-дисков), в котором модель QSqlTableModel и ее подкласс QSqlRelationalTableModel используются для просмотра и взаимодействия пользователей с данными, хранимыми в базе данных.
Главная форма показывает представление «master—detail» для компакт-дисков и дорожек текущего компакт-диска (рис. 13.1).
Рис. 13.1. Приложение CD Collection.
В приложении используются три таблицы, определенные следующим образом:
CREATE TABLE artist (
id INTEGER PRIMARY KEY,
name VARCHAR(40) NOT NULL,
country VARCHAR(40));
CREATE TABLE cd (
id INTEGER PRIMARY KEY,
title VARCHAR(40) NOT NULL,
artistid INTEGER NOT NULL,
year INTEGER N0T NULL,
FOREIGN KEY (artistid) REFERENCES artist);
CREATE TABLE track (
id INTEGER PRIMARY KEY,
title VARCHAR(40) NOT NULL,
duration INTEGER NOT NULL,
cdid INTEGER NOT NULL,
FOREIGN KEY (cdid) REFERENCES cd);
Некоторые базы данных не поддерживают внешние ключи. В этом случае мы должны убрать фразы FOREIGN KEY. Пример будет все-таки работать, но база данных не будет поддерживать целостность на уровне ссылок.
Рис. 13.2. Таблицы приложения CD Collection.
В этом разделе мы создадим диалоговое окно, позволяющее пользователю редактировать список артистов, используя простую форму с таблицей. Пользователь может вставлять, обновлять или удалять артистов при помощи кнопок формы. Обновления можно делать напрямую, просто редактируя текст ячеек. Изменения вносятся в базу данных при нажатии пользователем кнопки Enter или при переходе на другую запись.
Рис. 13.3. Диалоговое окно ArtistForm.
Ниже приводится определение класса для диалогового окна ArtistForm:
01 class ArtistForm : public QDialog
02 {
03 Q_OBJECT
04 public:
05 ArtistForm(const QString &name, QWidget *parent = 0);
06 private slots:
07 void addArtist();
08 void deleteArtist();
09 void beforeInsertArtist(QSqlRecord &record);
10 private:
11 enum {
12 Artist_Id = 0,
13 Artist_Name = 1,
14 Artist_Country = 2
15 };
16 QSqlTableModel *model;
17 QTableView *tableView;
18 QPushButton *addButton;
19 QPushButton *deleteButton;
20 QPushButton *closeButton;
21 };
Конструктор этого класса очень похож на конструктор, который использовался бы для создания формы, построенной для модели, отличной от SQL—модели:
01 ArtistForm::ArtistForm(const QString &name, QWidget *parent)
02 : QDialog(parent)
03 {
04 model = new QSqlTableModel(this);
05 model->setTable("artist");
06 model->setSort(Artist_Name, Qt::AscendingOrder);
07 model->setHeaderData(Artist_Name, Qt::Horizontal, tr("Name"));
08 model->setHeaderData(Artist_Country, Qt::Horizontal, tr("Country"));
09 model->select();
10 connect(model, SIGNAL(beforeInsert(QSqlRecord &)),
11 this, SLOT(beforeInsertArtist(QSqlRecord &)));
12 tableView = new QTableView;
13 tableView->setModel(model);
14 tableView->setColumnHidden(Artist_Id, true);
15 tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
16 tableView->resizeColumnsToContents();
17 for (int row = 0; row < model->rowCount(); ++row) {
18 QSqlRecord record = model->record(row);
19 if (record.value(Artist_Name).toString() == name) {
20 tableView->selectRow(row);
21 break;
22 }
23 }
24 …
25 }
Конструктор начинается с создания объекта QSqlTableModel. Мы передаем this в качестве родителя, чтобы владельцем модели стала форма. Нами выбрана сортировка по столбцу 1 (задается константой Artist_Name), который соответствует полю имени. Если бы мы не задали заголовки столбцов, то использовались бы имена полей. Мы предпочитаем их указать, чтобы обеспечить правильный регистр и локализацию.
Затем создается QTableView для визуального отображения модели. Мы не показываем поле id и устанавливаем такую ширину столбцов, которая будет достаточна для размещения в них текста без необходимости вывода многоточия.
Конструктор ArtistForm принимает имя артиста, который будет выбран при выводе на экран диалогового окна. Мы проходим по записям таблицы artist и выбираем этого артиста. Остальная часть программного кода конструктора используется для создания кнопок и подключения к ним слотов, а также для компоновки дочерних виджетов в диалоговом окне.

