В этой статье мы напишем простую программу с использованием библиотеки SQLite. Программа создаст базу данных, запишет туда информацию, а потом выведет эту информацию на экран.
1. Создание нового проекта
Для работы с таблицей мы будем виджеты GTK+, поэтому запустите CodeBlocks и выполните «Файл — Создать — Проект — GTK+ project». Готовый проект вы можете скачать в конце этой статьи.
Установите параметры проекта. Меню «Проект — Свойства — Цели сборки». Поставьте выделенные параметры.
Запустите приложение для проверки.
Библиотека GTK+ работает. Теперь убедитесь, что библиотека SQLite подключена к CodeBlocks.
2. Подключение GtkListStore для вывода таблицы
В GTK+ для работы со сложными данными используется GtkTreeModel — набор функций для хранения и отображения данных.
Существует две модели хранения GtkListStore и GtkTreeStore и один виджет отображения GtkTreeView, который поддерживает обе модели хранения.
Для работы с таблицами нужно сделать запрос к БД и поместить результат в структуру GtkListStore. Виджет GtkTreeView отобразит данные в виде таблицы.
Для работы с таблицей в GTK+ нужно:
- Создать буфер GtkListStore.
- Добавить строки в буфер.
- Создать таблицу GtkTreeView.
- Добавить столбцы в таблицу.
Для обращения к таблице используется:
- Итератор GtkTreeIter — текущая строка.
- Колонка GtkTreeViewColumn — текущий столбец.
- Рендер GtkCellRenderer — текущая ячейка.
Запускаем Glade и готовим виджет, для этого.
- Создаем буфер liststore1 для модели таблицы,
- Создаем виджет дерева treeview1.
- Указываем для этого виджета буфер liststore1.
Сохраняем интерфейс в файл main.glade. Виджет готов, теперь его надо настроить: указать столбцы и формат ячеек.
3. Настройка виджета GtkTreeView в Glade
У нас сейчас пустое окно, в котором есть дерево treeview1 и буфер liststore1. Нажимаем на иконку Edit.
В редакторе виджета «Дерево» столбцы настраиваются на вкладке “Основные”, а ячейки — на вкладке “Иерархия”. Сначала добавим три столбца:
- guint1
- gcharray1
- guin2
Теперь настроим ячейки:
- Номер
- Фамилия
- Оклад
Всё, интерфейс готов. Теперь можно писать обращение к базе данных.
4. Создание базы данных SQLite
Для подключения к БД SQLite используется команда sqlite3_open(«b1.db», &db). В этой строчке открывается база данных b1.db, если ее нет, то она создается.
В качестве примера возьмем таблицу «Сотрудники», в которой зададим поля:
- N
- Фамилия
- Оклад
Теперь составляем SQL-запрос, в котором создаем таблицу «Сотрудники» и задаем значения полей. Начинается запрос с удаления таблицы «Сотрудники», если она есть. Это для того, чтобы мы могли запускать программу несколько раз.
В этой статье мы напишем простую программу с использованием библиотеки SQLite. Программа создаст базу данных, запишет туда информацию, а потом выведет эту информацию на экран.
Содержание
1. Создание нового проекта
Для работы с таблицей мы будем виджеты GTK+, поэтому запустите CodeBlocks и выполните «Файл — Создать — Проект — GTK+ project». Готовый проект вы можете скачать в конце этой статьи.
Установите параметры проекта. Меню «Проект — Свойства — Цели сборки». Поставьте выделенные параметры.
Запустите приложение для проверки.
Библиотека GTK+ работает. Теперь убедитесь, что библиотека SQLite подключена к CodeBlocks. Об этом подробно написано здесь.
2. Подключение GtkListStore для вывода таблицы
В GTK+ для работы со сложными данными используется GtkTreeModel — набор функций для хранения и отображения данных.
Существует две модели хранения GtkListStore и GtkTreeStore и один виджет отображения GtkTreeView, который поддерживает обе модели хранения.
Для работы с таблицами нужно сделать запрос к БД и поместить результат в структуру GtkListStore. Виджет GtkTreeView отобразит данные в виде таблицы.
Для работы с таблицей в GTK+ нужно:
- Создать буфер GtkListStore.
- Добавить строки в буфер.
- Создать таблицу GtkTreeView.
- Добавить столбцы в таблицу.
Для обращения к таблице используется:
- Итератор GtkTreeIter — текущая строка.
- Колонка GtkTreeViewColumn — текущий столбец.
- Рендер GtkCellRenderer — текущая ячейка.
Запускаем Glade и готовим виджет, для этого.
- Создаем буфер liststore1 для модели таблицы,
- Создаем виджет дерева treeview1.
- Указываем для этого виджета буфер liststore1.
Сохраняем интерфейс в файл main.glade. Виджет готов, теперь его надо настроить: указать столбцы и формат ячеек.
3. Настройка виджета GtkTreeView в Glade
У нас сейчас пустое окно, в котором есть дерево treeview1 и буфер liststore1. Нажимаем на иконку Edit.
В редакторе виджета «Дерево» столбцы настраиваются на вкладке “Основные”, а ячейки — на вкладке “Иерархия”. Сначала добавим три столбца:
- guint1
- gcharray1
- guin2
Теперь настроим ячейки:
- Номер
- Фамилия
- Оклад
Всё, интерфейс готов. Теперь можно писать обращение к базе данных.
4. Создание базы данных SQLite
Для подключения к БД SQLite используется команда sqlite3_open(«b1.db», &db). В этой строчке открывается база данных b1.db, если ее нет, то она создается.
В качестве примера возьмем таблицу «Сотрудники», в которой зададим поля:
- N
- Фамилия
- Оклад
Теперь составляем SQL-запрос, в котором создаем таблицу «Сотрудники» и задаем значения полей. Начинается запрос с удаления таблицы «Сотрудники», если она есть. Это для того, чтобы мы могли запускать программу несколько раз.
// Запись в БД
int SaveDB()
{
char* SQL1 = "DROP TABLE IF EXISTS Сотрудники; \
CREATE TABLE Сотрудники(N,Фамилия,Оклад); \
INSERT INTO Сотрудники VALUES(1,'Иванов',20000); \
INSERT INTO Сотрудники VALUES(2,'Петров',25000); \
INSERT INTO Сотрудники VALUES(3,'Сидоров',30000); \
";
if (sqlite3_exec(db, SQL1, 0, 0, &err))
{
sprintf(str, "Ошибка выполнения SQL-запроса: %sn", err);
sqlite3_free(err);
return 2;
}
return 0;
}
5. Загрузка данных в буфер виджета GtkTreeView
Когда мы подключились к баз данных, мы можем загрузить строки БД в буфер виджета GtkTreeView. Сам буфер мы задаем строчкой:
GtkListStore *buffer; // Буфер таблицы
Загрузку данных выполняет следующий код:
// Цикл по SQL-запросу и запись в буфер таблицы
while((rc = sqlite3_step(stmt)) == SQLITE_ROW)
{
gtk_list_store_append (buffer, &iter);
gtk_list_store_set (buffer, &iter,
C_NUM, sqlite3_column_int(stmt, C_NUM),
C_NAME, sqlite3_column_text(stmt, C_NAME),
C_OKLAD, (guint) sqlite3_column_int(stmt, C_OKLAD),
-1);
}
Здесь мы в цикле перебираем строки запроса и заполняем ячейки таблицы значениями полей из базы данных.
6. Итоговая программа
Остальные шаги по выводу таблицы на экран достаточно стандартны. Подключаем интерфейс main.glade и выводим на экран основное окно. Вот код целиком.
В результате мы получаем вывод таблицы из базы данных на экран.
С помощью SQLite Studio можно подключиться к этой БД и увидеть, что все данные отражаются правильно.
Полностью проект можно скачать здесь
5. Загрузка данных в буфер виджета GtkTreeView
Когда мы подключились к баз данных, мы можем загрузить строки БД в буфер виджета GtkTreeView. Сам буфер мы задаем строчкой:
1GtkListStore *buffer; // Буфер таблицы
Загрузку данных выполняет следующий код:
12345678910 // Цикл по SQL-запросу и запись в буфер таблицы while((rc = sqlite3_step(stmt)) == SQLITE_ROW) { gtk_list_store_append (buffer, &iter); gtk_list_store_set (buffer, &iter, C_NUM, sqlite3_column_int(stmt, C_NUM), C_NAME, sqlite3_column_text(stmt, C_NAME), C_OKLAD, (guint) sqlite3_column_int(stmt, C_OKLAD), -1); }
Здесь мы в цикле перебираем строки запроса и заполняем ячейки таблицы значениями полей из базы данных.
6. Итоговая программа
Остальные шаги по выводу таблицы на экран достаточно стандартны. Подключаем интерфейс main.glade и выводим на экран основное окно. Вот код целиком.
/****************************************
Пример использования SQLite и GtkTreeView
*****************************************/
# include <stdlib.h>
# include <gtk/gtk.h>
# include <sqlite3.h>
GtkWidget *window1;
GtkBuilder *builder1;
sqlite3 *db; // хэндл БД
// Структуры данных для виджета
GtkListStore *buffer; // Буфер таблицы
GtkTreeView *table; // Таблица
GtkTreeViewColumn *column; // Отображаемая колонка
GtkTreeIter iter; // Итератор таблицы (текущая строка)
GtkCellRenderer *renderer; // Рендер таблицы (текущая ячейка)
// Обозначения полей
enum
{
C_NUM, C_NAME, C_OKLAD
};
// Структуры данных для базы данных
sqlite3_stmt* stmt; // строка запроса к БД
char *err = 0;
int rc = 0;
int ShowGladeError()
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
"Не найден файл\n main.glade");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
return 0;
}
char str[1000];
int lenstr=0;
// Открываем БД
void StartDB()
{
if( sqlite3_open("b1.db", &db))
{
sprintf(str, "Ошибка открытия БД: %s\n", sqlite3_errmsg(db));
}
}
void EndDB()
{
sqlite3_close(db);
}
// Запись в БД
int SaveDB()
{
char* SQL1 = "DROP TABLE IF EXISTS Сотрудники; \
CREATE TABLE Сотрудники(N,Фамилия,Оклад); \
INSERT INTO Сотрудники VALUES(1,'Иванов',20000); \
INSERT INTO Сотрудники VALUES(2,'Петров',25000); \
INSERT INTO Сотрудники VALUES(3,'Сидоров',30000); \
";
if (sqlite3_exec(db, SQL1, 0, 0, &err))
{
sprintf(str, "Ошибка выполнения SQL-запроса: %sn", err);
sqlite3_free(err);
return 2;
}
return 0;
}
// Загрузка таблицы из БД в буфер виджета
int LoadDB()
{
char* SQL2 = "SELECT N, Фамилия, Оклад FROM Сотрудники;";
// Готовим SQL-запрос к БД
if(sqlite3_prepare_v2(db, SQL2, -1, &stmt, NULL) != SQLITE_OK)
{
sprintf(str, "Ошибка подготовки SQL-запроса: %s\n", sqlite3_errmsg(db));
sqlite3_finalize(stmt);
return 3;
}
// Цикл по SQL-запросу и запись в буфер таблицы
while((rc = sqlite3_step(stmt)) == SQLITE_ROW)
{
gtk_list_store_append (buffer, &iter);
gtk_list_store_set (buffer, &iter,
C_NUM, sqlite3_column_int(stmt, C_NUM),
C_NAME, sqlite3_column_text(stmt, C_NAME),
C_OKLAD, (guint) sqlite3_column_int(stmt, C_OKLAD),
-1);
}
if(rc != SQLITE_DONE)
{
sprintf(str, "Ошибка выполнения SQL-запроса: %s\n", sqlite3_errmsg(db));
sqlite3_finalize(stmt);
return 4;
}
// 5. Освобождаем строку запроса
sqlite3_finalize(stmt);
return 0;
}
void ShowError ()
{
GtkWidget *dialog = NULL;
dialog = gtk_message_dialog_new (GTK_WINDOW (window1), GTK_DIALOG_MODAL,
GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, str);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
int ShowMainWindow()
{
builder1 = gtk_builder_new ();
if (gtk_builder_add_from_file (builder1, "main.glade", NULL))
{
window1 = GTK_WIDGET(gtk_builder_get_object(builder1, "window1"));
buffer = GTK_LIST_STORE(gtk_builder_get_object(builder1, "liststore1"));
table = GTK_TREE_VIEW(gtk_builder_get_object(builder1, "treeview1"));
gtk_window_set_default_size (GTK_WINDOW (window1), 500, 300);
gtk_window_set_position(GTK_WINDOW(window1), GTK_WIN_POS_CENTER);
gtk_builder_connect_signals (builder1, NULL);
g_signal_connect(G_OBJECT(window1), "destroy", G_CALLBACK(gtk_main_quit), NULL);
SaveDB();
if(LoadDB())
{
ShowError();
}
gtk_widget_show (window1);
return TRUE;
}
else
{
return FALSE;
}
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
StartDB();
if (ShowMainWindow ())
{
gtk_main ();
EndDB();
return 0;
}
else
{
ShowGladeError();
EndDB();
return 1;
}
}
В результате мы получаем вывод таблицы из базы данных на экран.
С помощью SQLite Studio можно подключиться к этой БД и увидеть, что все данные отражаются правильно.
Полностью проект можно скачать здесь
Можно ли стать программистом за год с нуля?
Читайте в моей бесплатной мини-книге «Путь в программисты». Скачать её можно здесь.