Общая структура показана ниже.
Наименование проекта я подправил. Но в заголовках статей и метках я всё равно оставлю «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 из книги Шлее. Принципиальное отличие - где коннект ставить. :)) Разве что на это упор сделать. Но я могу этот пример кинуть с поправкой на то, откуда оригинал взят.
Конечно )) На самом деле не все читали Шлее... я например не читал ))