Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Вопрос про организацию кода


Автор: azesmcar 4.8.2009, 09:00
Доброе утро,

Я начал изучение Qt (и не только Qt, весь GUI в целом smile ). В общем-то я GUI писал когда еще маленький был и опыта практически нету. Сейчас написал кое-что на Qt, смотрю - самому противно. Хотелось бы расспросить как у вас обстоит с этим делом. Приступим...

1. Насколько правильно использовать ui файлы? Он после обработки UI файла выделяет всю инициализацию в отдельный класс (файл) и вроде бы все чистенько, аккуратненько, но...
Но сгенерированный файл менять нельзя, иногда Designer генерирует там фигню какую-то, которую из designer-а никак изменить нельзя. Например при использовании класса QTreeWidget, он генерирует названия для колонок (1, 2, 3, 4...), разумеется приходится менять у себя в файле. Получается что инициализация не вся в одном месте, еще и два раза выполняется одно действие.  smile 
Да и кстати я смотрю на примеры в Qt, ни один из них не использовал ui файлы.

2. Создал окошко, все прекрасно, теперь начинаем добавлять кнопочки и форточки. Добавил одну кнопку, другую, третью...через некоторое время код становится похожим на кучу какашек. Все обработчики в одном файле, не класс а недоразумение какое-то. Возникает желание выделить логику программы куда нибудь. Сейчас сделал так
mainwindow.h - заголовочный файл
mainwindow.cpp - реализация логики программы
mainwindow_i.cpp - инициализация кнопочек, установка событий (настройки интерфейса короче)
mainwindow_e.cpp - реализация slot -ов.

Почему-то мне это нормальным не кажется. Как вы организовываете код? Все эти функции, события...ничего общего с ООП этот класс уже не имеет. И монолитный какой-то. Потому всегда не любил GUI, надеюсь все это можно привести в порядок, чтобы я по прежнему мог без рвотного рефлекса смотреть на собственный код. smile 

Спасибо.

Автор: SABROG 4.8.2009, 09:22
Цитата(azesmcar @  4.8.2009,  09:00 Найти цитируемый пост)
Например при использовании класса QTreeWidget, он генерирует названия для колонок (1, 2, 3, 4...), разумеется приходится менять у себя в файле.

Имена колонок можно из дизайнера изменить.

Цитата(azesmcar @  4.8.2009,  09:00 Найти цитируемый пост)
Да и кстати я смотрю на примеры в Qt, ни один из них не использовал ui файлы.

.ui скорее для статики. Если приходится часто наследоваться, динамически создавать/уничтожать виджеты. В общем не программа, а дискотека, тогда придется всё вручную вбивать. К тому же примеры остаются примерами, их должно быть удобно читать, серьезными приложениями их не назвать. Но примеры такие все-таки есть:

Код

$(QTDIR)/examples/activeqt/webbrowser
$(QTDIR)/examples/dbus/dbus-chat
$(QTDIR)/examples/dbus/remotecontrolledcar
$(QTDIR)/examples/designer/calculatorbuilder
$(QTDIR)/examples/designer/calculatorform
$(QTDIR)/examples/designer/worldtimeclockbuilder
$(QTDIR)/examples/graphicsview/padnavigator
$(QTDIR)/examples/help/contextsensitivehelp
$(QTDIR)/examples/help/remotecontrol
$(QTDIR)/examples/ipc/sharedmemory
$(QTDIR)/examples/itemviews/editabletreemodel
$(QTDIR)/examples/network/http
$(QTDIR)/examples/network/network-chat
$(QTDIR)/examples/network/securesocketclient
$(QTDIR)/examples/network/torrent
$(QTDIR)/examples/painting/fontsampler
$(QTDIR)/examples/painting/svggenerator
$(QTDIR)/examples/qmake/precompile
$(QTDIR)/examples/script/calculator
$(QTDIR)/examples/script/qstetrix
$(QTDIR)/examples/uitools/multipleinheritance
$(QTDIR)/examples/uitools/textfinder
$(QTDIR)/examples/webkit/formextractor
$(QTDIR)/examples/webkit/googlechat
$(QTDIR)/examples/webkit/previewer
$(QTDIR)/examples/widgets/stylesheet
$(QTDIR)/examples/widgets/validators
$(QTDIR)/examples/xmlpatterns/filetree
$(QTDIR)/examples/xmlpatterns/qobjectxmlmodel
$(QTDIR)/examples/xmlpatterns/recipes
$(QTDIR)/examples/xmlpatterns/trafficinfo


Цитата

Все обработчики в одном файле


Можно написать всего один слот для всех кнопок на форму на базе QAbstractButton, если так будет удобней.

Цитата(azesmcar @  4.8.2009,  09:00 Найти цитируемый пост)
Как вы организовываете код?

На каждую новую форму - новую пару классов newform.h, newform.cpp. А так, чтобы выносить слоты и инициализацию в отдельные файлы, я этим не занимаюсь. Меня в принципе это устраивает.

Автор: azesmcar 4.8.2009, 09:32
Цитата(SABROG @  4.8.2009,  09:22 Найти цитируемый пост)
Имена колонок можно из дизайнера изменить.

Скорее всего не нашел. Поищу еще.

Цитата(SABROG @  4.8.2009,  09:22 Найти цитируемый пост)

.ui скорее для статики. Если приходится часто наследоваться, динамически создавать/уничтожать виджеты. В общем не программа, а дискотека, тогда придется всё вручную вбивать. К тому же примеры остаются примерами, их должно быть удобно читать, серьезными приложениями их не назвать. Но примеры такие все-таки есть:

Это все ясно, просто интересно как вообще принято.

Цитата(SABROG @  4.8.2009,  09:22 Найти цитируемый пост)

Можно написать всего один слот для всех кнопок на форму на базе QAbstractButton, если так будет удобней.

Ну речь шла не только о кнопках, я для примера написал кнопка. Не все можно в одну функцию направлять..и даже если можно, это не всегда удачная идея, так как логически эти кнопки могут выполнять совершенно разные функции, нарушается принцип "одна функция - одна задача".

Цитата(SABROG @  4.8.2009,  09:22 Найти цитируемый пост)

На каждую новую форму - новую пару классов newform.h, newform.cpp. А так, чтобы выносить слоты и инициализацию в отдельные файлы, я этим не занимаюсь. Меня в принципе это устраивает.

А логику где пишешь? В том же классе?

Автор: VC15 4.8.2009, 10:30
Я обычно делаю так. Один элемент GUI - это один .h, один .cpp и один .ui. Каша, которая творится в сгенерированном исходнике, меня не смущает - главное, чтобы работало правильно.
В дизайнере я стараюсь делать максимум настроек, чтобы как можно меньше писать самому. Ну а дополнительную инициализацию осуществляю в конструкторе. Получается, что реализация GUI-класса содержит две части - дополнительную инициализацию элементов управления и собственно логику работы. Конечно, и то, и другое может иметь невероятно большой объём, но в этом случае нужно либо перепроектировать свой класс, разбив его на несколько, либо смириться с этим и использовать IDE, обеспечивающую удобную навигацию по коду (например Eclipse), что избавляет тебя от постоянного пролистывания огромных кусков инициализирующего кода.

Автор: azesmcar 4.8.2009, 10:36
Цитата(VC15 @  4.8.2009,  10:30 Найти цитируемый пост)
Я обычно делаю так. Один элемент GUI - это один .h, один .cpp и один .ui. Каша, которая творится в сгенерированном исходнике, меня не смущает - главное, чтобы работало правильно.
В дизайнере я стараюсь делать максимум настроек, чтобы как можно меньше писать самому. Ну а дополнительную инициализацию осуществляю в конструкторе. Получается, что реализация GUI-класса содержит две части - дополнительную инициализацию элементов управления и собственно логику работы. Конечно, и то, и другое может иметь невероятно большой объём, но в этом случае нужно либо перепроектировать свой класс, разбив его на несколько, либо смириться с этим и использовать IDE, обеспечивающую удобную навигацию по коду (например Eclipse), что избавляет тебя от постоянного пролистывания огромных кусков инициализирующего кода. 

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

Цитата(VC15 @  4.8.2009,  10:30 Найти цитируемый пост)
Каша, которая творится в сгенерированном исходнике, меня не смущает

QSystemTrayIcon как я понал в дизайнере нельзя установить и настроить, т.е. писать его (и не только его) придется в самом коде (поскольку в кашу ручками нельзя лезть). Получается что половина инициализаций в одном файле, половина в другом. Уже безобразие. Но это еще не все. Теперь о событиях...
Некоторые события имеют отношение к логике программы а не которые нет (например мне нужно перехватить onMouseOver на какой нибудь кнопочке и как-то очень красиво ее покрасить в гламурно зеленый smile), тут уже совсем путаница. Отделить логику от интерфейса никак не получается, хотя и это событие и нажатие на ту же кнопку, по которому мне нужно будет загрузить файл из интернета тоже.
 smile 

Автор: pan2004 4.8.2009, 12:44
Цитата(azesmcar @  4.8.2009,  10:36 Найти цитируемый пост)
Некоторые события имеют отношение к логике программы а не которые нет (например мне нужно перехватить onMouseOver на какой нибудь кнопочке и как-то очень красиво ее покрасить в гламурно зеленый ), тут уже совсем путаница. Отделить логику от интерфейса никак не получается, хотя и это событие и нажатие на ту же кнопку, по которому мне нужно будет загрузить файл из интернета тоже.

Пока придется мириться с таким "смешением", или ждать прихода Qt Kinetic

Автор: azesmcar 4.8.2009, 12:49
Цитата(pan2004 @  4.8.2009,  12:44 Найти цитируемый пост)
Пока придется мириться с таким "смешением", или ждать прихода Qt Kinetic 

Что, совсем никак что ли? Плохо что тут нужна и обратная связь, получается либо все бросать в кучу, либо связь типа - все знают обо всех. 
Ладно, это еще ничего, я вот не могу понять что делать с первым вопросом.

Цитата(azesmcar @  4.8.2009,  10:36 Найти цитируемый пост)
QSystemTrayIcon как я понал в дизайнере нельзя установить и настроить, т.е. писать его (и не только его) придется в самом коде (поскольку в кашу ручками нельзя лезть). Получается что половина инициализаций в одном файле, половина в другом. Уже безобразие. 

Если я буду использовать ui файл, как я потом создам tray icon? В дизайнере его я не нашел как поставить, в самом коде это писать что ли?

Автор: pan2004 4.8.2009, 13:20
Цитата(azesmcar @  4.8.2009,  12:49 Найти цитируемый пост)
Получается что половина инициализаций в одном файле, половина в другом. Уже безобразие. 

В данном примере - а чем плохо? Очевидно, что QSystemTrayIcon не имеет никакого отношения к форме(не говоря о том, что рисуется в системе совсем в другом месте), и инициализироваться должен отдельно.

Автор: azesmcar 4.8.2009, 13:22
Цитата(pan2004 @  4.8.2009,  13:20 Найти цитируемый пост)

В данном примере - а чем плохо? Очевидно, что QSystemTrayIcon не имеет никакого отношения к форме(не говоря о том, что рисуется в системе совсем в другом месте), и инициализироваться должен отдельно. 

К форме - да, но он имеет отношение к пользовательскому интерфейсу. Так куда же его можно засунуть? В принципе он и к логике программы никакого отношения не имеет. smile 

Да еще и это не только Tray icon а идущий за ним QMenu и целый вагон QAction -ов. smile 
Код становиться похожим на свалку.

Автор: VC15 4.8.2009, 13:52
Знаешь, по-моему ты слишком сильно заморачиваешься. Получается, что классификация кода и размещение его по отдельным файлам - это самоцель. На мой взгляд, гораздо важнее грамотно спроектировать классы с точки зрения их функциональности, а где и как находится код - это второй вопрос. Повторюсь, что использование хорошей IDE решает проблему навигации по коду.

Автор: pan2004 4.8.2009, 13:54
Цитата(azesmcar @  4.8.2009,  13:22 Найти цитируемый пост)
Да еще и это не только Tray icon а идущий за ним QMenu и целый вагон QAction -ов.

Оба вполне спокойно добавляются и редактируются через дизайнер

Автор: azesmcar 4.8.2009, 14:00
Цитата(VC15 @  4.8.2009,  13:52 Найти цитируемый пост)
Знаешь, по-моему ты слишком сильно заморачиваешься. Получается, что классификация кода и размещение его по отдельным файлам - это самоцель. На мой взгляд, гораздо важнее грамотно спроектировать классы с точки зрения их функциональности, а где и как находится код - это второй вопрос. Повторюсь, что использование хорошей IDE решает проблему навигации по коду. 

Возможно, я идеалист...
Нет, в принципе сама цель на данный момент изучение, так что мне особо не важно сколько времени уйдет на написание программы, но хотелось бы научится делать правильно, нет у меня опыта в разработке GUI, может это и нормально, но только я не видел кода грамотно написанного на Qt и не знаю с чем сравнивать. Я сравниваю со своими кодами, с кодами написанными в компаниях в которых я работал (речь идет о не GUI программах) и этот код явно проигрывает в читабельности и вообще в красоте, во всех понятиях этого слова.
Применить MVC? Для каждой формы наследовать три класса...тоже не дело. Речь не о размещении файлов, а о разделении интерфейса и логики. Покажите мне грамотный во всех понятиях GUI код написанный на Qt и я успокоюсь если там будет свалено все в кучу smile 
Если нет - научусь как надо.

Action и Menu - да, TrayIcon - нет, я не пойму куда его внедрить, в какой модуль программы.

Цитата(VC15 @  4.8.2009,  13:52 Найти цитируемый пост)
На мой взгляд, гораздо важнее грамотно спроектировать классы с точки зрения их функциональности, а где и как находится код - это второй вопрос

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

Давайте рассмотрим пример, так будет понятнее.

Допустим
Нужно написать калькулятор
нам нужно ОДНО окно и множество кнопочек на нем.
как вы организуете класс окна, где поместите логику программы (функции подсчетов и так далее).

У меня нет пока мышления GUI разработчика, хотелось бы чтобы появилось.

Автор: andrew_121 4.8.2009, 14:17
azesmcar, Объясни, какие файлы у тебя генеряться при создании одного .ui файла.

Автор: azesmcar 4.8.2009, 14:20
Цитата(andrew_121 @  4.8.2009,  14:17 Найти цитируемый пост)
azesmcar, Объясни, какие файлы у тебя генеряться при создании одного .ui файла. 

А что, они отличаются от тех, что генерируются у других?
Один заголовочный файл, там создание всех визуальных элементов и установка из значений в функции setupUi и основной файл использующий первый.

Автор: andrew_121 4.8.2009, 14:26
Т.е.
Допустим форма зовется MainForm, файл mainform.uiuic сгенерит из него .h файл. В конце которого будет:
Код

namespace Ui {
    class MainForm: public Ui_MainForm {};
} // namespace Ui

Значит все ГУИ объекты в пространстве имен Ui. Унаследуйся, добавь свои методы. Инициализацию для каждого пиши в .cpp файле.

Автор: azesmcar 4.8.2009, 14:31
Цитата(andrew_121 @  4.8.2009,  14:26 Найти цитируемый пост)
Значит все ГУИ объекты в пространстве имен Ui. Унаследуйся, добавь свои методы. Инициализацию для каждого пиши в .cpp файле. 

Это считается хорошим стилем? Почему Qt генерирует код с композицией этого класса а не наследованием?

Автор: SABROG 4.8.2009, 14:32
Цитата(azesmcar @  4.8.2009,  14:00 Найти цитируемый пост)
Допустим
Нужно написать калькулятор
нам нужно ОДНО окно и множество кнопочек на нем.
как вы организуете класс окна, где поместите логику программы (функции подсчетов и так далее).

У меня нет пока мышления GUI разработчика, хотелось бы чтобы появилось.


На самом деле не правильно выбирать простые примеры. Они никогда не решают реальных задач. 

Для калькулятора достаточно одного main.cpp файла в который запихать всё целиком. Тут даже .ui файл не нужен. Где слоты, там и логика.
Я бы даже не стал писать отдельный класс для логических операций. Это скорее усложнит читабельность, чем реально поможет.

Все-таки для меня бизнес логика это не вообще любой маломальский код, который приходится писать в слотах, а реализация модульных вещей: парсеры xml, работа с БД, делегаты, унаследованные виджеты, работа с сетью и т.п.

Цитата(azesmcar @  4.8.2009,  14:31 Найти цитируемый пост)
Это считается хорошим стилем? Почему Qt генерирует код с композицией этого класса а не наследованием?

На самом деле я видел 3 варианты использование класса сгенеренного от .ui файла:
- полное наследование, при котором область видимости UI пропадает
- аггрегация UI класса
- использование указателя на UI

Где-то даже тема была о выборе одного из этих методов. Были и плюсы и минусы подходов. Но как я не пытался найти объяснение троллей, так и не нашел.

Автор: azesmcar 4.8.2009, 14:37
Цитата(SABROG @  4.8.2009,  14:32 Найти цитируемый пост)
Для калькулятора достаточно одного main.cpp файла в который запихать всё целиком. Тут даже .ui файл не нужен. Где слоты, там и логика.
Я бы даже не стал писать отдельный класс для логических операций. Это скорее усложнит читабельность, чем реально поможет.

Все-таки для меня бизнес логика это не вообще любой маломальский код, который приходится писать в слотах, а реализация модульных вещей: парсеры xml, работа с БД, делегаты, унаследованные виджеты, работа с сетью и т.п. 

Ну хотелось бы чтобы вы не делали скидку на простоту примера smile 
Даже самый простой пример можно написать правильно, так чтобы в будущем его было проще расширить, добавить функциональность не потеряв красоты кода. Над учесть что в большинстве GUI приложений будет работа с БД (тут все усложняется). Просто хотелось бы увидеть сложный дизайн на простом примере, если это нереально - покажите сложный пример. smile 
А калькулятор - вполне реальная задача. Вон, микрософт его столько лет расширить не могла, сейчас совсем переписали smile наверное проблемы архитектуры smile 

Автор: andrew_121 4.8.2009, 14:42
Цитата(azesmcar @  4.8.2009,  14:31 Найти цитируемый пост)
Почему Qt генерирует код с композицией этого класса а не наследованием?

Хороши вопрос. Многими был задан ранее.

Серьезный проект на Qt - http://www.qutecom.org/

Автор: azesmcar 4.8.2009, 14:45
Да, вариант с наследованием мне тоже определенно нравится больше, но в таком случае хотелось бы заставить Qt генерировать объекты в хотя бы в protected секции (я уже не говорю про функции доступа) smile 

Автор: SABROG 4.8.2009, 14:47
А чем QtCreator не серьезный проект? Исходники есть. Еще можно посмотреть в сторону QDevelop и qutim. В принципе сами утилиты Qt: Designer и Assistant достаточно серьезны. Можно конечно еще серьезней - KDE.

Автор: andrew_121 4.8.2009, 14:49
azesmcar, Нет у uic-а такой опции.
Делай по другому.
Подключай генерированные хидеры, но не используй объект из namespace::Ui, наследуйся от объекта Ui_[имя формы]. Оно же тебе известно.

Автор: azesmcar 4.8.2009, 14:50
Цитата(andrew_121 @  4.8.2009,  14:49 Найти цитируемый пост)
Подключай генерированные хидеры, но не используй объект из namespace::Ui, наследуйся от объекта Ui_[имя формы]

а что это изменит?

Автор: andrew_121 4.8.2009, 14:53
Цитата(azesmcar @  4.8.2009,  14:50 Найти цитируемый пост)
а что это изменит? 

Пихай предков в протектед.

Автор: azesmcar 4.8.2009, 14:56
Цитата(andrew_121 @  4.8.2009,  14:53 Найти цитируемый пост)
Пихай предков в протектед. 

зачем в protected, сразу в private. Это ясно, я имел ввиду в самом классе забить все в protected. Ладно, нельзя так нельзя.

Автор: andrew_121 4.8.2009, 14:57
Я привык формы создавать дизайнером. Но все остальное ручками пишу. Может средства разработки как-то иначе этот процесс выполняют...

Добавлено @ 14:58
Цитата(azesmcar @  4.8.2009,  14:56 Найти цитируемый пост)
я имел ввиду в самом классе забить все в protected. Ладно, нельзя так нельзя. 

Ну если уж невмоготу, измени uic, его коды прилагаются smile 

Автор: SABROG 4.8.2009, 14:59
Цитата(azesmcar @  4.8.2009,  14:50 Найти цитируемый пост)
а что это изменит? 


Я думаю ничего, точно также как и эта тема. Если хочется побороться за "правое" дело с троллями, то мы будем только рады почитать переписку и услышать их аргументы.

Может быть тебе будет интересна http://qt.gitorious.org/qt/pages/CodingConventions ссылка.

Автор: azesmcar 4.8.2009, 15:00
Такой вопрос.

Есть ли гарантия, что Qt завтра не станет генерировать класс Ui_mainwindowClass наследником QObject? В этом случае появится проблема.
Код

class mainwindow : public QMainWindow, private Ui::mainwindowClass //тут проблема

наследование от двух классов, наследников от QObject - не разрешено.
Может потому в генерированном исходнике используется вариант с агрегацией?

Автор: andrew_121 4.8.2009, 15:03
Цитата(azesmcar @  4.8.2009,  15:00 Найти цитируемый пост)
Есть ли гарантия, что Qt завтра не станет генерировать класс Ui_mainwindowClass наследником QObject?

Нет.
С версии 4.6 многое измениться. Точнее SABROG знает. Потом, еще что-то радикально могут изменить.

Автор: VC15 4.8.2009, 16:10
Цитата
Да, вариант с наследованием мне тоже определенно нравится больше, но в таком случае хотелось бы заставить Qt генерировать объекты в хотя бы в protected секции (я уже не говорю про функции доступа)


Я думаю, uic специально генерит всё в public, чтобы ты сам потом решал, как это использовать. Если хочешь все члены спрятать (а так обычно и надо делать), используй private-наследование.

P.S. На мой взгляд, тема себя исчерпала. Преимущества средств разработки заключаются в тех возможностях, которые они дают, а не в том, как с их помощью можно организовать свой код. Хотя, конечно, организация и читабельность кода - это очень важные его свойства.

Автор: azesmcar 4.8.2009, 16:19
Цитата(VC15 @  4.8.2009,  16:10 Найти цитируемый пост)

P.S. На мой взгляд, тема себя исчерпала. Преимущества средств разработки заключаются в тех возможностях, которые они дают, а не в том, как с их помощью можно организовать свой код. Хотя, конечно, организация и читабельность кода - это очень важные его свойства. 

Да, но вообще-то тема была не об этом. smile 

Автор: andrew_121 4.8.2009, 17:24
azesmcar, А если серьезно, то и вправду можно изменить uic. Посмотрел, кода не много. Можно его генератор заточить как хочется, и будет он тебе генерить то, что хочешь.

Лежит в $(QTDIR)/src/tools/uic

Автор: Любитель 5.8.2009, 00:56
Цитата(azesmcar @  4.8.2009,  09:00 Найти цитируемый пост)
Да и кстати я смотрю на примеры в Qt, ни один из них не использовал ui файлы.

Посмотри код асистента, дизайнера.. Простые, но вполне реальные примеры.

Цитата(azesmcar @  4.8.2009,  09:00 Найти цитируемый пост)
mainwindow.h - заголовочный файл
mainwindow.cpp - реализация логики программы
mainwindow_i.cpp - инициализация кнопочек, установка событий (настройки интерфейса короче)
mainwindow_e.cpp - реализация slot -ов.

Так не стоит. Я считаю, что делить класс на файлы - это зло.

Цитата(azesmcar @  4.8.2009,  14:00 Найти цитируемый пост)
Применить MVC? Для каждой формы наследовать три класса...тоже не дело. Речь не о размещении файлов, а о разделении интерфейса и логики. Покажите мне грамотный во всех понятиях GUI код написанный на Qt и я успокоюсь если там будет свалено все в кучу

В мире Qt (да ладно, что уж самих себя обманывать - вообще в мире десктоп-гуя) MVC подход в нормальном виде не принят (Model View Framework в Qt - это не MVC).

Цитата(azesmcar @  4.8.2009,  14:00 Найти цитируемый пост)
Допустим
Нужно написать калькулятор
нам нужно ОДНО окно и множество кнопочек на нем.
как вы организуете класс окна, где поместите логику программы (функции подсчетов и так далее).

Функции подсчётов - очевидно, отдельные классы (или просто функции даже). Это ж domain layer (busyness layer).
Отдельный виджет основного поля калькулятора (умеющего отображать состояния ошибки, переключать отображение числа с разной точностью и т. д.).
Отдельный виджет поля кнопок. Опционально - виджеты групп (блок цифр, блок таких-то операций, блок таких-то операций).
Возможно - подгрузка функций через плагины и соответственно абстракция для задания лейаута (в самописном xml-е проще всего) smile
Отдельный класс для основного окошка.
И т. д. Это ж только пример smile 

Цитата(azesmcar @  4.8.2009,  14:31 Найти цитируемый пост)
Почему Qt генерирует код с композицией этого класса а не наследованием?

Потому что композиция лучше, чем наследование. Читаем любую книгу по ОО-дизайну.

Цитата(SABROG @  4.8.2009,  14:47 Найти цитируемый пост)
Еще можно посмотреть в сторону QDevelop и qutim

Насчёт криэйтора вообщем согласен, но всё-таки preffered way это ассистент с дизайнером (они проще гораздо). А вот последние два - не рекомендую. При том, что там есть хорошие идеи, как идеальный пример - точно не пойдут. Уж извините, но они остаются "оупенсорсными поделками" (проекты сами плохими из-за этого не становятся, я их уважая и пр. - поймите меня правильно).

Цитата(andrew_121 @  4.8.2009,  14:57 Найти цитируемый пост)
Ну если уж невмоготу, измени uic, его коды прилагаются smile 

На qtapps.org когда-то натыкался на "правильную" реализацию генерилки для ui-файлов (когда после переноса одного лейбла не надо рекомпилить всё).  Не тестил smile

Автор: andrew_121 5.8.2009, 01:21
Цитата(Любитель @  5.8.2009,  00:56 Найти цитируемый пост)
На qtapps.org когда-то натыкался на "правильную" реализацию генерилки для ui-файлов (когда после переноса одного лейбла не надо рекомпилить всё).  Не тестил smile 

Где "оно" ?

Автор: Любитель 5.8.2009, 07:15
http://www.qt-apps.org/content/show.php/SplitUI?content=61344

Оказывается, работает как обёртка над uic-ом. Что, впрочем не есть плохо.

Автор: azesmcar 5.8.2009, 08:30
Цитата(Любитель @  5.8.2009,  00:56 Найти цитируемый пост)
Посмотри код асистента, дизайнера.. Простые, но вполне реальные примеры.

Сейчас гляну.

Цитата(Любитель @  5.8.2009,  00:56 Найти цитируемый пост)
Так не стоит. Я считаю, что делить класс на файлы - это зло.

Я тоже не люблю делить, но просочилась идея от partial class -а в C#, студия генерирует функцию инициализации компонентов в отдельном от самого кода файле, думалось реализовать что-то наподобие этого, но...как я сказал мне и самому не нравится.

Цитата(Любитель @  5.8.2009,  00:56 Найти цитируемый пост)
В мире Qt (да ладно, что уж самих себя обманывать - вообще в мире десктоп-гуя) MVC подход в нормальном виде не принят (Model View Framework в Qt - это не MVC).

smile Я его применение удачно только для Web -а видел.

Цитата(Любитель @  5.8.2009,  00:56 Найти цитируемый пост)
Функции подсчётов - очевидно, отдельные классы (или просто функции даже). Это ж domain layer (busyness layer).
Отдельный виджет основного поля калькулятора (умеющего отображать состояния ошибки, переключать отображение числа с разной точностью и т. д.).
Отдельный виджет поля кнопок. Опционально - виджеты групп (блок цифр, блок таких-то операций, блок таких-то операций).
Возможно - подгрузка функций через плагины и соответственно абстракция для задания лейаута (в самописном xml-е проще всего) smile
Отдельный класс для основного окошка.
И т. д. Это ж только пример smile 

В общем-то все также, но сам интерфейс разделен на несколько групп. Ясно. Спасибо.

Цитата(Любитель @  5.8.2009,  00:56 Найти цитируемый пост)
Потому что композиция лучше, чем наследование. Читаем любую книгу по ОО-дизайну.

Потому я и спросил
Цитата(azesmcar @  4.8.2009,  14:31 Найти цитируемый пост)
Это считается хорошим стилем? 

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

Любитель большое спасибо за содержательный пост.

Автор: Kipter 14.8.2009, 11:14
azesmcar
оО где где а вот в QT помоему не должно быть проблем с оформлением и размещением кода =)

если проект больше чем калькулятор или "блокнот" то лично я делаю:

1) Если интерфейс простой (1 окно, небольшое количество виджетов), большая чатсь программы - логика.
а. То весь интерфейс описываю в своем классе (KipMainWindow, унаследованный от QMainWindow или QDialog);
   в конструкторе класса описываеться интерфйес этого окна (создаються виджеты/лейоуты и т д)
  также этот класс наделяю функциями котоыре онтосяться только к интерфейсу! Никаких функций обрабатывающих логику (т.е назначение этой программы)
 и создаю слоты для влияния на интерфейс из классов логики.

б. Всю логику (Классы/функции назначения программы) заношу в другой класс/классы Наследуемые от QObject. Определяю слоты для сигналов от интерфейса и сигналы для влияния на интерфейс.

в. Связываю слоты и сигналы Обьекта интерфейса с Обьектами Логики =)

2) Если интерфейс большой и накручен множеством элементов управления, то разбиваю его на сегменты (Фреймы, меню, диалоги,) и распределяю их по нескольким классам. Которые позже создаю в том же KipMainWindow ну и дальше как в пункте 1

Добавлено через 5 минут и 45 секунд
В моем идеалистическом взгляде... необходимо отделять интерфейс и логику решающую конкретную задачу.

Автор: andrew_121 14.8.2009, 12:59
Цитата(Kipter @  14.8.2009,  11:14 Найти цитируемый пост)
б. Всю логику (Классы/функции назначения программы) заношу в другой класс/классы Наследуемые от QObject. Определяю слоты для сигналов от интерфейса и сигналы для влияния на интерфейс.

Любопытно. Как такое возможно без наследования от QObject ? smile 

Автор: Kipter 15.8.2009, 00:41
Цитата

Любопытно. Как такое возможно без наследования от QObject ?  


Я же сказал, все классы в приложении имеют наследование от QObject. Но темнеменее логика находиться отдельно от интерфейса (в разных классах)

Вообщем кому как удобно, можно хоть всю программу в 1 единственный класс запихнуть при желании =)))

Автор: korbian 17.8.2009, 08:00
Цитата(andrew_121 @  14.8.2009,  13:59 Найти цитируемый пост)
Любопытно. Как такое возможно без наследования от QObject ?

Любопытно, а почему так важен вопрос наследования от QObject? какие еще плюсы дает такой вариант, кроме общей для проекта модели взаимодействия сигнал\слот? 

имхо, при таком подходе логика становится зависимой от конечного user interface и непереносимой.

Автор: andrew_121 17.8.2009, 08:32
Цитата(korbian @  17.8.2009,  08:00 Найти цитируемый пост)
Любопытно, а почему так важен вопрос наследования от QObject?

Без этого сигналы/слоты и много другое не будет работать.

Автор: korbian 17.8.2009, 08:34
andrew_121, это как раз и понятно. smile

Автор: Любитель 17.8.2009, 09:56
korbian, Даёт возможность пользоваться автоматическим разрушением чайлд-объектов (если понятие иерархии применимо к ним), поиском чайлдов, загрузкой объектов из плагинов, пользоваться qobject_cast, etc. Хватит? smile 

Автор: korbian 17.8.2009, 10:20
Любитель, хватит. smile только мне кажется сомнительным награждать конечный интерфейс бизнес логики такими "ништяками", теряя переносимость. я бы делал еще один промежуточный слой для взаимодействия в концепции модели end-point user interface.

p.s. хотя qt давно уже не фреймворк для ГУИ, а гораздо больше и зависимость от нее может быть требованием проекта.

Автор: Любитель 17.8.2009, 11:02
Цитата(korbian @  17.8.2009,  10:20 Найти цитируемый пост)
хотя qt давно уже не фреймворк для ГУИ

Во-во.

Вы часто делали десять ГУИ-фронтендов к одной программе (да, бывает - но это исключение, а не правило)?

Автор: korbian 17.8.2009, 13:21
Цитата(Любитель @  17.8.2009,  12:02 Найти цитируемый пост)
Вы часто делали десять ГУИ-фронтендов к одной программе (да, бывает - но это исключение, а не правило)?

никогда не приходилось, но мозг упорно сопротивляется зависимости от ГУИ-фреймворка(исторически) на уровне бизнес логики. smile

Автор: Любитель 17.8.2009, 13:59
QtCore никакого отношения к ГУИ не имеет.

Автор: korbian 17.8.2009, 14:13
Цитата(Любитель @  17.8.2009,  14:59 Найти цитируемый пост)
QtCore никакого отношения к ГУИ не имеет.

так то оно так. но как оценивать продукт, у которого бизнес логика зависит от qtCore, а gui-фронтенд, к примеру, от wxWidgets? то есть, понятно, что конфликта не будет, но сам проект будет восприниматься нелепо, на мой взгляд. это всего лишь мое имхо, но раз уж засветил "ништяки" (привязалось слово) из какого-либо большого фреймворка аля QT или wxWidgets, то будь добр и на gui-фронтенд от него же "разориться".

Добавлено через 1 минуту и 20 секунд
теряется переносимость бизнес-логики, вот к чему я веду.

Автор: Любитель 17.8.2009, 14:29
Так. Ладно - тогда скажем по-другому.

Во-первых, есть два типа разделения BL и GUI: клиент-серверная архитектура или просто отдельная библиотека. Про первый надеюсь вообще вопросов нет? Если мне хочется использовать QtCore, QtXml, QtSql, etc. - я имею полное право их использовать.

Далее. Когда реально имеет смысл думать о поддержке нескольких ГУИ-фронтэндов - при написании небольшой утилиты (куча линуксовых утилит иллюстрируют эту мысль). Да - тогда пожалуйста. Другой вариант - при написании огромного проекта с собственным abstraction layer-ом для ГУИ. Тот же ОО или опера - в качестве экзамплов.

Иными словами - вариантов два. Либо убогий ГУИ, либо собственный ГУИ фреймворк (враппер над другими ГУИ-либами). Иначе разговор о различных фронтэндах теряет смысл.

Автор: korbian 17.8.2009, 14:55
Любитель, сложно не согласиться. smile
в данный момент работую над проектом, в котором часть BL может "прошиваться" в достаточно примитивную "железку"(микроконтроллер), а часть функционировать на PC. у модуля, функционирующего на PC gui-фронтенд QT. BL хочется реализовать общим для обоих вариантов кодом. естественно ни о каком QT или прочее на уровне BL речи не идет. 

Хочу подчеркнуть, что ситуаций когда зависимость от большого фреймворка на уровне бизнес-логики чревата последствиями мало, но они есть и надо об этом помнить! 



Автор: Kipter 21.8.2009, 17:12
Вы очень сильно отошли от темы =)
Разделение так называемой Бизнес Логики и Гуи от QT тут не затрагивался =)

Тут речь немного о другом разделении, для так сказать эстетического восприятия в программе =)
Я не говорил что я отделяю механику (или как еще бизнес логику) приложения от библиотеки QT.

Я отделяю механику от классов GUI, и считаю это правильным. Если ваша программа конвертирует изображения....
логично будет засунуть механику в какой нибудь класс CImgConverter допустим. И слать ему сигналы от CMainWindow.

Однако некоторые разработчики реализуют непосредственную задачу прямо в классе интерфейса. 
Что затрудняет потом поиск нужного кода... и восприятия программы в целом.

Да и идеология ООП в целом нарушается!
Если обьяснять на тех же кошечках  smile 

то реализовывать задачи программы в классах GUI элементов это все равно что Кошке прикреплять миску к челюсти, намертво =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)