Понятие и основные вопросы о разделении логики (C ++) и GUI (Qt)

Я закончил проект в C++, Это консольное приложение, созданное с помощью CodeBlocks. Хотя я считаю, что это не так важно в рамках этого вопроса: приложение управляет данными о счетах и ​​клиентах небольшой компании. Программа завершена и может быть очень легко расширена с помощью пользовательского интерфейса консоли (сейчас я запускаю ее как программист).

Теперь я решил изучить программирование с использованием графического интерфейса Qt и QtCreator с его QtDesigner!

Не только потому, что при создании приложения с графическим интерфейсом принято отделять логику от GUI, я хочу реализовать свой проект на двух больших частях, а именно: логика а также графический интерфейс пользователя.
Вы уже знаете, что логическая часть завершена; что у меня есть папка проекта называется project содержащий другую папку (проект CodeBlocks) project_logic который снова содержит несколько классов, таким образом, заголовочные файлы и файлы реализации (и основной, который, конечно, в конечном итоге устареет). Он также содержит файлы из / в которые программа читает / пишет. Это написано в «чистом» C++ и использует никто средств, предоставленных Qt и это важно для меня, что это остается таким!

Теперь я добавил Qt проект project_gui в project-папка и начала создавать графический интерфейс, реализуя только самые основные функции, такие как переключение между диалогами, закрытие приложения и т. д. ничего такого о своем будущем бэк-энде (project_logic).

В качестве третьего компонента мне нужен какой-то управление которая связывает логику приложения с его графическим интерфейсом. Вот мой концептуальный вопрос: Как лучше всего объединить их в одном приложении?

Предложения

  1. поскольку project_logic может работать в одиночку как консольное приложение, оно уже обеспечивает наиболее важные управляющие компоненты и функции. Так будет и дальше, потому что я хочу сохранить его автономную функциональность. Тем более, что я совершенно новичок в программировании GUI и / или через две недели я мог бы создать еще один GUI для той же логики. В результате классы логической части включаются в исходный код GUI, как и любой другой заголовок, и используются для создания программы с полной функциональностью. Проверка пользовательского ввода будет опираться на часть GUI. Логика программы в любом случае останется обновляемой.

  2. Сделать графический интерфейс максимально пригодным для повторного использования; я должен реализовать третий компонент а ля project_controlling что обеспечивает взаимодействие между графическим интерфейсом и логикой (проверка пользовательского ввода осуществляется путем контроля) в том, что каждый из этих двух остается максимально независимым? GUI, не считая, так сказать, заголовков логики, но включая управляющие заголовки?


Второй момент может показаться немного странным, я признаю; Короче говоря, мои цели:

  • Держать project_logic стандарт C++ а также независимый (с точки зрения исправления, добавления функциональности и т. д.) и
  • с помощью Qt для GUI при максимальном (в то же время разумном) разделении GUI и логики.

Поезда мыслей

  1. Должен ли я включить project_logic Заголовки через #include "../project_logic/header1.h" так далее? (Может быть проблема с использованием классов, которые я опубликую в отдельном вопросе.)

  2. Должен ли я включить их в качестве подпроекта?

  3. Как бы я соединить части «в коде»?

  4. Логические функции все еще находят файлы, которые я упоминал ранее (чтение / запись)?


Пожалуйста, имейте в виду следующее: Я новичок в программировании GUI! И я приложил все усилия, чтобы объяснить мои мысли / проблемы … Однако я знаю C и C ++ и пишу консольные приложения, которые я использую, например, для. Я считаю, что симуляции в университете и могут справиться со стандартными вещами довольно хорошо. Даже если потенциальный ответчик захочет предложить совсем другой подход, я был бы признателен за «решение» предложенной мной концепции. Причину этого я объяснил во введении. Нет необходимости упоминать, что мне, конечно, интересно услышать разные предложения.

Я решил опубликовать вопрос после того, как я провел небольшое исследование и постарался изо всех сил & error «fashion before. Существует много информации на эту тему на StackOverflow и других форумах, поэтому я хотел представить свою идею и собрать критику и комментарии, а не добавлять другое» как? «к мешанине вопросов.

Поскольку этот вопрос относится к общему подходу, я, возможно, (вполне уверен …) задам больше технических вопросов позже, которые я хотел бы отредактировать в этом вопросе (гиперссылки), как только они возникнут.
Тем не менее, основные рецепты в этом вопросе, если таковые имеются, приветствуются, конечно.


После некоторых комментариев и ответов я чувствую, что хочу опубликовать немного РЕДАКТИРОВАТЬ, чтобы прояснить ситуацию:

Текущее состояние логики

  • project_logic более или менее закончен и закодирован в CodeBlocks как проект CodeBlocks.
  • Это мог работать как консольное приложение с «пользовательским интерфейсом консоли». (Оно имеет main.cpp который теперь используется только для отладки.)
  • Его компоненты делятся на классы (заголовки и файлы реализации cpp), насколько это возможно.

Текущий статус GUI

  • project_gui настраивается как проект Qt-Widget-Application (используя QtCreator / Designer).
  • Пока что только GUI больше ничего (нет связи с project_logic в любом случае).

Цели и …

рабочий процесс, Я хочу следовать, так как это мой первый большой проект:

  • project_logic а также project_gui не будет покидать свои соответствующие каталоги; они оба находятся в каталоге под названием project, (Исключение: логика будет экспортирована как dll (или что-то подобное) если необходимо, который затем предоставляется в GUI.)
  • Если бы было что-то изменить в project_logic Я хочу сделать это в CodeBlocks (и повторить возможный экспорт, как описано выше).
  • project_logic (или любой третий слой, например, project_controlling) должны быть сделаны одноразовыми для project_gui самым простым способом, который только можно вообразить … (см. «Поезд мыслей № 1») 😛

15

Решение

  • Если у вас есть отдельные проекты :

когда вы разрабатывали разные части своего приложения в разных проектах, самый простой способ — просто связать ваш основной проект с библиотеками и использовать их. Так что в вашем случае вы должны предоставить dll для логики проекта, которая разработана и скомпилирована в CodeBlocks для вашего проекта Qt, сделать ссылку на нее и использовать классы.

Например, вы можете поместить файлы заголовков вашей библиотеки в папку с именем Logic и отладочные и выпускные версии .lib файлы в соответствующих папках и ссылку на приложение:

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/Logic/release/ -lLogic
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/Logic/debug/ -lLogic

INCLUDEPATH += $$PWD/Logic
DEPENDPATH += $$PWD/Logic
  • Если у вас есть все в одном проекте Qt:

В этом случае с помощью Subdirs Хорошая идея отделить модули кода друг от друга. Таким образом, вы можете иметь независимые программные модули, которые можно использовать многократно и которые можно легко заменить. Это также делает проект намного чище и легче для чтения.

При таком подходе модули могут взаимодействовать друг с другом через сигналы и слоты, что делает различные компоненты полностью независимыми, и замена одного модуля не требует замены других частей.

Qt Creator обеспечивает хорошую автоматизацию в сопоставлении деталей друг с другом. Вы можете создать проект Subdirs и добавить свои подпроекты в его файл .pro:

TEMPLATE = subdirs

CONFIG += ordered

SUBDIRS += \
Component1 \
Component2 \
Component3 \
MainApp \

Вы должны перечислить подпроекты, от которых зависят другие, сначала в списке. Также обратите внимание, что имя .pro файла подпроекта должно совпадать с именем его папки. Таким образом, подпроекты обнаруживаются и отображаются на панели «Проекты».

Подпроекты Component1, Component2 а также Component3 могут быть библиотеки. Часть файла .pro для Component1:

TARGET = Component1
TEMPLATE = lib

DEFINES += COMPONENT1_LIBRARY

SOURCES += ...
HEADERS += ...

Подпроект MainApp может быть приложение. Часть файла .pro для MainApp :

TARGET = MainApp
TEMPLATE = app

Вы можете использовать библиотеки в каждом подпроекте, связав его с подпроектом. Это можно сделать, щелкнув правой кнопкой мыши по подпроекту и выбрав «Добавить библиотеку», а затем «Внутренняя библиотека». Когда вы выбираете одну библиотеку из списка подпроектов, конфигурации ссылок добавляются в .pro автоматически. Это будет похоже на:

win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../Component1/release/ -lComponent1
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../Component1/debug/ -lComponent1
else:unix: LIBS += -L$$OUT_PWD/../Component1/ -lComponent1

INCLUDEPATH += $$PWD/../Component1
DEPENDPATH += $$PWD/../Component1
3

Другие решения

Добро пожаловать в ТАК.

Вы действительно соединили два или три вопроса здесь, но давайте попробуем:

В качестве третьего компонента мне нужен какой-то контроль, который связывает
логика приложения с его графическим интерфейсом.

Поскольку вы используете Qt, у вас есть встроенный ответ на этот вопрос:

Qt Project-Model / Просмотр программирования. Для начала:

Модель / вид архитектуры

Model-View-Controller (MVC) — это шаблон проектирования, происходящий из
Smalltalk, который часто используется при создании пользовательских интерфейсов. В дизайне
Patterns, Gamma et al. записывать:

MVC состоит из трех видов объектов. Модель это приложение
объект, представление его экранного представления, а контроллер
определяет, как пользовательский интерфейс реагирует на ввод пользователя. До MVC,
проекты пользовательского интерфейса имели тенденцию смешивать эти объекты вместе. MVC
разъединяет их для повышения гибкости и повторного использования.

Если представление и объекты контроллера объединены, результатом является
модель / вид архитектуры. Это по-прежнему отделяет способ, которым данные
хранится в том виде, в котором он представлен пользователю, но обеспечивает
более простая структура, основанная на тех же принципах. Это разделение делает
можно отображать одни и те же данные в нескольких разных видах и
реализовать новые типы представлений, не изменяя базовые данные
структур. Чтобы обеспечить гибкую обработку пользовательского ввода, мы вводим
Концепция делегата. Преимущество наличия делегата в этом
Основой является то, что она позволяет отображать элементы данных и
отредактировано, чтобы быть настроенным.

Модель MVC, явно поддерживаемая платформой QT (и возможная для реализации с другими структурами GUI, хотя и с большим количеством работы), широко принята как надежная, гибкая группа шаблонов проектирования, которая обеспечивает управление и разделение различных прикладных уровней так, как вы думаете — значит, вы на правильном пути.

Второй момент может показаться немного странным, я признаю; поставить это
Короче говоря, мои цели …

Вопрос о том, как настроить проекты с исходным кодом, на самом деле не имеет ничего общего с архитектурой вашего приложения, хотя эти области обычно пересекаются так, что хорошая организация проекта облегчает реализацию вашей архитектуры, и наоборот. То, как вы организуете свой проект и его различные библиотеки и классы, может зависеть не только от проекта, над которым вы сейчас работаете, но и от планов будущих проектов. Например, как вы упомянули, вы можете разработать определенные компоненты графического интерфейса, которые вы можете использовать для нескольких различных приложений. Если это так, вы можете поместить свои модули GUI в отдельную универсальную библиотеку многократного использования, которая может использоваться многими приложениями.

Некоторые правила, однако, применимы по всем направлениям и соблюдаются большинством опытных разработчиков — вот несколько важных, есть еще много:

  • Один основной класс и его дочерние классы на единицу (файл hpp / cpp).

  • Будьте очень осторожны с тем, что вы включаете в заголовочные файлы и что вы оставляете в ваших файлах CPP. Ты найдешь
    руководящие принципы здесь на SO и в любой хорошей книге C ++ на эту тему, которая
    довольно важно, особенно в сложных проектах. (От звука
    это — например ваши вопросы о том, как использовать #include и «соединить части
    «в коде — вам нужно лучше понять некоторые основы
    программирования на C ++. Там есть несколько отличных книг — вы можете найти
    списки здесь. C ++ Primer (5-й
    Издание)

    это одно из лучших мест для начала.)

  • Разбейте свои классы и библиотеки с точки зрения их
    функциональность. Большинство IDES поддерживают виртуальные подпапки в вашем проекте
    (не уверен насчет Code :: Blocks), чтобы помочь организовать вещи такими
    манера. Это на самом деле входит в фундаментальные вопросы дизайна, а не
    просто как выложить код в вашем проекте.

  • избежать тесная связь!

    В разработке программного обеспечения связь или зависимость — это степень, в которой
    каждый программный модуль опирается на каждый из других модулей.

    Сцепление обычно противопоставляется сплоченности. Низкая связь часто
    коррелирует с высокой сплоченностью и наоборот. Низкая связь часто
    признак хорошо структурированной компьютерной системы и хорошего дизайна, и когда
    в сочетании с высокой сплоченностью, поддерживает общие цели высокого
    удобочитаемость и ремонтопригодность.

  • Хорошо использовать Пространства имен, еще одна замечательная языковая функция, которая помогает поддерживать модульность и организованность.

В вашем случае кажется, что вы можете захотеть сделать, это упаковать свою «логику приложения» в одну библиотеку, свои универсальные модули GUI в секунду, а затем третий, тонкий исполняемый файл — возможно, просто содержащий main() и несколько строк, чтобы начать работу и завершить работу, когда это будет сделано — это запускает приложение Qt и инициализирует классы в ваших библиотеках, которые взаимодействуют с использованием модели MVC и выполняют фактическую работу приложения. Три отдельных модуля не нужны, хотя они будут более «универсальными» и многократно используемыми, и таким образом их будет проще организовать.

Вы действительно затронули этот вопрос по широкому кругу вопросов, и опять же, некоторые из них относятся к основам программирования на C ++, а не просто к «отделению логики приложения от GUI». Надеюсь, этот ответ поможет вам двигаться в правильном направлении.

Важное примечание: Программирование с помощью графического интерфейса — это полная и не особо легкая ветвь программирования. Есть специалисты по GUI и есть программисты, которые работают с GUI только минимально. (Я одна из последней группы). Есть сайт SE под названием Пользовательский опыт который, хотя он не имеет дело с GUI программирование По сути, речь идет о том, как пользователи взаимодействуют с системами, что напрямую связано с методами программирования GUI. Итак, когда вы говорите: «Теперь я решил изучать программирование в GUI», знайте, что вы берете на себя большую работу. Если вы на самом деле не заинтересованы в том, чтобы программирование с использованием графического интерфейса стало вашей специальностью, вы можете рассмотреть возможность использования мастеров и готовых решений с графическим интерфейсом вместо того, чтобы делать все вручную. QtCreator действительно предоставляет такую ​​поддержку, как Code :: Blocks. Если вы намереваетесь заняться этим серьезным бизнесом, есть и коммерческие структуры. Если вы не делаете это просто ради обучения, повторное изобретение колеса не рекомендуется для серьезной коммерческой работы по программированию.

3

По вопросам рекламы [email protected]