Загальну структуру показано нижче.
Назва проекту я підправив. Але в заголовках статей та мітках я все одно залишу «Simple tracker», щоб не було плутанини.
Проект складається з підпроектів клієнтської та серверної частини та підпроекту тестування. Головний файл проекту має такий вигляд.
TEMPLATE = subdirs CONFIG += ordered SUBDIRS += ICTrackerServer ICTrackerClient tests
Варто звернути увагу на файл common.pri, який видно підпроектами клієнта та сервера (а також підключатиметься до тестів у міру необхідності). Туди я вписав додаткові директиви, які були підглянуті в інших проектах.
# Переменная PWD разворачивается в путь к файлу *.pro/*.pri, в котором используется BUILD_DIR = $${PWD}/build # В зависимости от типа билда, debug или release, устанавливаем соответствующее # значение переменной BUILD_TYPE CONFIG(release, debug|release){ message(Release) BUILD_TYPE = release }else{ message(Debug) BUILD_TYPE = debug } DEST_BINS = $${BUILD_DIR}/$${BUILD_TYPE} # В зависимости от платформы, на которой собираем проект, устанавливаем # расположение исполняемых файлов. # Регулярное выражение "s,/,\\,g" в SOME_VAR ~= s,/,\\,g означает # "заменить в переменной SOME_VAR прямой слэш ("/") на обратный слэш ("\")". win32 { DEST_BINS ~= s,/,\\,g DESTDIR = $${DEST_BINS} } linux { DESTDIR = $${DEST_BINS} } # Остальные файлы, которые генерируются по ходу сборки, выносим за пределы репозитория. # Переменная OUT_PWD разворачивается в путь построения билда, # заданный в Qt Creator в настройках проекта. MOC_DIR = $${OUT_PWD}/$${BUILD_TYPE}/moc UI_DIR = $${OUT_PWD}/$${BUILD_TYPE}/ui UI_HEADERS_DIR = $${OUT_PWD}/$${BUILD_TYPE}/ui UI_SOURCES_DIR = $${OUT_PWD}/$${BUILD_TYPE}/ui OBJECTS_DIR = $${OUT_PWD}/$${BUILD_TYPE}/obj RCC_DIR = $${OUT_PWD}/$${BUILD_TYPE}/rcc
Таким чином, при компіляції проекту в debug-режимі структура папок може мати приблизно такий вигляд.
Поряд з папками вихідних формується папка build з двома підпапками debug і release, куди записуються тільки файли, що виконуються.
Інші файли виносяться за межі дерева проекту.
Я розмістив файл common.pri в корені проекту і підключив до pro-файлів підпроектів за допомогою директиви include.
include(../common.pri)
Тепер розглянемо підпроекти.
У клієнта, крім файлів pro та pri є тільки main.cpp. Оскільки клієнт передбачається консольним, швидше за все, крім допоміжних функцій, більше нічого не знадобиться.
Залишається лише дописати у pro-файл підтримку мережі.
QT += network
У сервера завдань більше, і тому структура його складніша. Тут є клас TrackerServer, який відповідає за формування GUI трекера та роботу сервера. На зображенні показаний і клас DataBase, який відповідає за роботу з базою даних. Також під час розробки будуть додані класи для реалізації діалогових вікон.
Тут у pro-файл, крім підтримки мережі, потрібно додати підтримку SQL.
QT += sql network
Підпроект tests сам складатиметься з підпроектів, тому в pro-файлі записано таке:
TEMPLATE = subdirs CONFIG += ordered SUBDIRS +=
Зі структурою проекту в першому наближенні закінчено. У наступній частині я опишу базу даних та її тестування.
Я правильно понимаю, что сервер будет формироавть API для доступа клиентов, а клиенты не будут иметь прямого доступа к базе данных?
Вы используете JSON для формирования сообщений между сервером и клиентами?
Да, прямой доступ не предполагается. Впрочем, можно, конечно, и напрямую. Всё равно всё локально происходит. Проблема в том, как донести сведения об изменениях в базе, которые вносит клиент, до модели QSqlTableModel, которая в сервере? Если как-то можно, то тогда надобность в QLocalServer и QLocalSocket, конечно, отпадает.
Нет, JSON не использую. Просто QByteArray и QDataStream. От клиента серверу передётся всего три параметра: наименование проекта, номер закрываемой задачи и номер ревизии, закрывающей задачу.
Лучше API )))
Кстати, по использованию QLocalServer и QLocalSocket на сайте нет статей, было бы очень полезно и хорошо пошло бы в раздел Qt.
Так пример с QLocalServer и QLocalSocket я целиком переписал с QTcpSocket и QTcpServer из книги Шлее. Принципиальное отличие - где коннект ставить. :)) Разве что на это упор сделать. Но я могу этот пример кинуть с поправкой на то, откуда оригинал взят.
Конечно )) На самом деле не все читали Шлее... я например не читал ))