Разделение логики и пользовательского интерфейса - PullRequest
11 голосов
/ 13 августа 2011

Я разрабатываю приложение с графическим интерфейсом на Qt.

Это мое первое приложение с графическим интерфейсом, и я не очень опытен, и мне все еще приходится сталкиваться с некоторыми более продвинутыми аспектами C ++ и Qt Framework.

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

Теперь у меня проблема. Я помещаю все свои расчетные данные (статические и загруженные из ресурсов) и логику в отдельный класс. Я создаю экземпляр этого класса и классов пользовательского интерфейса. Теперь проблема в том, как получить доступ к членам класса данных / логики из класса пользовательского интерфейса? Скажем, в классе Logic есть QStringList, и я хочу, чтобы определенное диалоговое окно получило доступ к этому списку и представило его пользователю, не копируя его в памяти?

Я понимаю, что это, вероятно, очень простой вопрос C ++ (Qt даже не актуален), но не каждый - мастер программирования. Спасибо за любую подсказку или помощь!

Ответы [ 3 ]

16 голосов
/ 13 августа 2011

Есть несколько способов сделать это, поэтому ваш вопрос верен.

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

  2. Ваш класс GUI может содержать указатель на ваш класс логики и / или наоборот. Это также может быть ссылка для удобства, если ваш класс логики существует до класса GUI и выживает. Затем вы можете передать ссылку на конструктор класса GUI и вам никогда не придется проверять, является ли указатель действительным.

  3. Ваш класс GUI может получить доступ к членам данных через методы получения / установки или напрямую, если вы хотите сделать их общедоступными или просто определить свой класс GUI как класс friend для класса Logic. Даже если вы используете геттеры, они могут возвращать константные ссылки, поэтому копирование не требуется. Классы Qt, такие как QStringList, также имеют свой собственный механизм подсчета ссылок, механизм копирования при записи, который избегает копий.

  4. Ваш класс графического интерфейса может излучать сигналы, а класс логики может принимать их. Смотрите механизм Qt сигнал / слот. Это очень удобно для таких событий, как кнопка «Начать вычисление». Сигналы имеют два преимущества: (а) они могут проходить через потоки, однако, если получатель не является основным циклом, он становится немного сложнее; (б) объекты не должны видеть друг друга (указатель не передается), вы можете подключить сигналы к слотам в любом месте вашей программы, где вы видите оба объекта одновременно.

Как правило, вы будете использовать смесь из 2 и 3: используйте геттеры для чтения данных из класса логики, который представлен пользователю. Используйте сигналы, чтобы вызвать действие или манипулировать данными (пользователь делает выбор, класс логики должен реагировать).

5 голосов
/ 13 августа 2011

Существует модель программирования под названием MVC (Модель - Вид - Управление)

Для простых случаев достаточно просто Model - View. Модель представляет данные, а View представляет пользовательский интерфейс.

Класс модели предоставляет некоторые интерфейсы для установки / получения данных. Класс модели обычно не знает о классе View, но обычно может уведомлять класс View об изменении данных (это можно сделать с помощью сигнала / слота в Qt).

Класс View содержит указатель на класс Model и использует интерфейсы, предоставляемые классом Model, для манипулирования данными.

1 голос
/ 13 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...