Russian Qt Forum
Ноябрь 25, 2024, 10:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Разделение логики и GUI  (Прочитано 20524 раз)
Lagovas
Гость
« : Август 03, 2011, 19:25 »

Только начал осваивать Qt и тому подобное. Сразу хочется учится программировать правильно, ведь учиться легче чем переучиваться. Сейчас не работаю и не пишу продакшн проекты, а для себя. И мне кажется что в реальных приложениях намного лучше изначально отделять логику и отображение. Так вот, подскажите что почитать, что попробовать, в каком направлении двигаться. И возможно ли с Qt так делать. Насколько я пока понимаю как это делается, пишется в куте форма, с сигналами и методами которыми можно с ней взаимодействовать. А "логика" должна взаимодействовать с формой. Так вот, если так делать, то все классы логики должны наследоваться от QObject? Ведь вроде без него нельзя работать с сигналами, а если так, то вся фишка гуи в куте теряется. Скорее всего я чего то недопонимаю, и прошу раздуплить. Заранее благодарен.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #1 : Август 04, 2011, 02:24 »

Так вот, если так делать, то все классы логики должны наследоваться от QObject? Ведь вроде без него нельзя работать с сигналами, а если так, то вся фишка гуи в куте теряется.
Не понял. Какая фишка?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Август 04, 2011, 06:02 »

Классическая проверка на вшивость: есть некоторое приложение с GUI, теперь требуется консольная версия (без GUI). И вот тут выясняется что "ой" Улыбающийся По существу Вы спрашиваете: а как сделать чтобы мои приложения имели хорошую, гибкую архитектуру? Ответ на этот вопрос мне неизвестен. Я стараюсь решать это на уровне файлов и классов. Т.е. есть cpp файлы "с UI и без". Это примитивное разделение но работает неплохо.  Расчетные" классы не знают о существовании UI и обычно подаются в UI как указатели/ссылки. Часто приходится делать небольшие адаптеры для развязки. Слот/сигнал цветет пышным цветом именно в UI, в расчетной части его применение гораздо скромнее, а часто можно спокойно обойтись и без него. 

Тему Вы затронули интересную, но Ваш вопрос слишком общий. Возможно с конкретным примером обсуждение было бы более интересным/продуктивным.     
Записан
SeverusSnape
Гость
« Ответ #3 : Август 04, 2011, 09:51 »

В качестве конкретного примера можно посмотреть на великолепную читалку FBReader - которая реализована по такому принципу
Записан
Lagovas
Гость
« Ответ #4 : Август 07, 2011, 01:22 »

Просто есть ведь разные паттерны проектирования и тому подобное, много книг по архитектуре, думал уже есть какие то отлаженные механизмы разделения. Плюс хотел узнать возможно ли так и как вы это сами делаете.
Записан
asvil
Гость
« Ответ #5 : Август 07, 2011, 09:59 »

Хм, web же. Там гуи на языке html + интерактивность с помощью javascript, для логики используется серверный язык (php, python, java ....). Вот вам шаблон проектирования: сервер логики и гуи клиент.
Распространенный шаблон номер два: фронт-енд к базе данных. ГУИ представляет из себя формочки для ввода данных, с некоторой интерактивностью, а тажке отчетики длы вывода данных. Сами же данные храняться в СУБД и агрегируются с помощью процедур в триггерах.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Август 07, 2011, 11:43 »

Ну когда оно сделано и работает - то конечно все ясно Улыбающийся. А вот простейший пример: при выполнении какой-то ф-ии или метода произошла ошибка. Нужно показать  пользователю модальный диалог и вернуть false

Код
C++ (Qt)
if (!... ) {           // нашли ошибку
sprintf(buf, "Error reading file %s, line %d, unexpected token (%c) ", fName, lineNo, token);  // сообщение
QMessageBox(QMessageBox::Warning, "Error", buf).exec();  // показали модальный диалог
return false;  //  вышли
}
 
Как мы видим UI проникло/просочилось в cpp файл который занят разбором текста (т.е. никакого отношения к UI иметь не должен). Как этого избежать?
Записан
Lagovas
Гость
« Ответ #7 : Август 07, 2011, 11:47 »

Я хоть с потоками мало работал, но мне кажется можно ошибки писать в std::err или чет такое, а там где гуи, читать этот поток и выводить. На крайняк в файл, и с файла читать.
Записан
asvil
Гость
« Ответ #8 : Август 07, 2011, 11:59 »

Lagovas прав.
QMessageBox в алгоритмах зло, ибо потенциально может являться спамом.
Любой алгоритм должен журналироваться, а журнал перенаправлятся в виджет. Вот и вся логика.
Если есть такое требование в ТЗ, то ТЗ нужно редактировать.
Записан
Lagovas
Гость
« Ответ #9 : Август 07, 2011, 12:06 »

А какой метод лучше, сделать отдельный метод в гуи классе, который принимает параметром ошибки для вывода и использовать его в логике, все же писать в поток и емитить сигнал, о том что надо показать еррор либо же что бы метод гуя был в отдельном потоке и по таймеру проверял еррор лог?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Август 07, 2011, 12:14 »

QMessageBox в алгоритмах зло, ибо потенциально может являться спамом.
Все согласны что зло  Улыбающийся
Любой алгоритм должен журналироваться, а журнал перенаправлятся в виджет. Вот и вся логика.
Прошу показать "UI - независимую" версию фрагмента приведенного в посте #6
Записан
asvil
Гость
« Ответ #11 : Август 07, 2011, 12:14 »

Я реализовывал через log4qt с помощью сигнал-слотового соединения. Соединение потокобезопасное, поэтому как алгоритм будет реализован не важно.
Записан
asvil
Гость
« Ответ #12 : Август 07, 2011, 12:22 »

Код:
StaticLogAppender appender
{
   slot:
       addMessage(string) {emit message(string);}
   signals:
       message(string);
};

handler (string){
     appender.addMessage(string)
}

main
{
   installQtDebugHandlers(handler);

   QWidget logwindow;
   connect(appender, SIGNAL(message), logwindow, SLOT(addMessage), Qt::QueuedConnection);
}

algorythm()
{
   qDebug() << error;
}
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #13 : Август 07, 2011, 12:31 »

Прошу показать "UI - независимую" версию фрагмента приведенного в посте #6
например в Objective-C часто используется передача в функцию последним параметром указатель на NSError *, который в случае неудачи выполнения функции становится != nil и содержит информацию об ошибке, а в случае успеха - == nil.

другой вариант - возвращать из функции QString, а не bool (в случае успеха - QString(), неудачи - сообщение с ошибкой), но тогда не получится красивого
Код
C++ (Qt)
if (myfunction())
{
   ...
}
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Lagovas
Гость
« Ответ #14 : Август 07, 2011, 12:36 »

разве не получится? Разве пустая строка не будет считаться false?
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.083 секунд. Запросов: 23.