Russian Qt Forum

Qt => Qt-инструментарий => Тема начата: sarbash от Февраль 25, 2010, 11:11



Название: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: sarbash от Февраль 25, 2010, 11:11
Всем привет!
В настройках параметров креатора есть выбор способа встраивания ui в дизайнере классов:

1. Агрегация через указатель.
2. Агрегация.
3. Множественное наследование.

Как я понимаю, эта настройка влияет на все последующие создаваемые классы интерфейсов.
Прошу специалистов посоветовать, какую лучше настройку и какой способ лучше использовать?
Заранее благодарю.


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: b-s-a от Февраль 25, 2010, 11:57
Ты сам отличия понимаешь?
1.
Код:
class MyWidget : public QWidget
{
   ...
private:
   Ui::MyWidget *myWidget_;
};
2.
Код:
class MyWidget : public QWidget
{
   ...
private:
   Ui::MyWidget myWidget_;
};
3.
Код:
class MyWidget : public QWidget, private Ui::MyWidget
{
   ...
};
Способы 2 и 3 подразумевают, что Ui::MyWidget будет виден всем, кто подключил этот хидер. Первый же способ позволяет использовать шаблон проектирования PIMPL (т.е. подключать UI в cpp файле), что может несколько ускорить компиляцию за счет очень малого замедления работы программы (дополнительная операция разыменования указателя).
Вот и выбирай в зависимости от потребностей. Кстати, никто не мешает тебе потом в конкретном классе менять один способ на другой.

Наиболее удобен в программирования третий вариант - не нужно писать ни myWidget_->, ни myWidget_. перед требуемым полем формы.


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: sarbash от Февраль 25, 2010, 12:19
Благодарю за ответ.
Различия понимаю.
Интересовал совет именно в плане удобства программирования.
Сам лично склонялся к множественному наследованию.
Интересовала практика применения и опыт.
В справке креатора есть один пример, в котором показывается выгода применения указателя, но меня интересовало, насколько часто в реальной практике приходилось сталкиваться с этим. Т.к. инкапсуляция - штука хорошая, но для доступа к данным виджетов требует дополнительных манипуляций. Вот и возникло сомнение - а насколько это оправдано, если можно просто третий способ использовать в большинстве случаев? Вот и обратился за советом...


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: b-s-a от Февраль 25, 2010, 13:35
Я уже написал, что выгода от использования первого способа - отсутствие необходимости подключать Ui в хидер класса. Что несколько ускорит компиляцию. Еще для библиотек это бывает полезно - вне зависимости от количества аттрибутов класса, оператор new будет всегда выделять одно и тоже количество памяти (например, если изменилась версия библиотеки, то это нужно, чтобы не пересобирать все программы).
А именно с точки зрения удобства программирования лучше третий вариант. Но вот с точки зрения структуризации он не очень - сложней искать концы.


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: voronElf от Февраль 25, 2010, 13:54
Добавлю насчет точки зрения удобства написания кода: очень мне нравится пользоваться дополнением кода (ну эта выпадашка с именами полей объекта) и тут все плюсы у 1 и 2 методов (для 3-го this писать придется  :) ). Когда контролов много на форме, замучаешься имена вспоминать, а тут все перед глазами в нужный момент ...


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: Igors от Февраль 25, 2010, 14:13
На роль "специалиста" не претендую  :)
По поводу мн. наследования: это хорошо написано в ++библии, если не путаю называется "Альтернатива: членство или наследование". Предлагается способ проверки: а может ли таких (встраиваемых) быть 2 или больше? Напр. 2 скроллбара - может, значит мн. наследование не подходит.

А если это Qt UI, то указатель - самое ходовое. Объект-член заклинит т.к. Qt parent удаляет child'ов. Мн. наследование - проблемы с "который QObject?".


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: b-s-a от Февраль 25, 2010, 15:00
Объект-член заклинит т.к. Qt parent удаляет child'ов. Мн. наследование - проблемы с "который QObject?".
1. Не заклинит, так как Ui сам ничего не удаляет. А создается все методом setupUi(this).
2. Нет проблем, так как Ui это не потомок QObject.


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: kkk777kkk от Февраль 25, 2010, 16:14
как показывает практика и как уже написали выше, удобнее всего делать так как это сделано в новосозданных проектах Ui::bdClass ui; при этом наглядно видны контролы, пробовал раз пользоваться третим вариантом, но переделал в итоге обратно на второй, ибо жудко не удобно


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: break от Февраль 25, 2010, 18:38
Много работаю с формами - пользуюсь вариантом 2 всегда

Цитировать
при этом наглядно видны контролы
что имеется ввиду - они во всех вариантах видны если я так понял

Думаю что 1-ый вариант самый грамотный (т.к. быстрее компиляция и нет ничего лишнего в хедере...), хотя у меня все пока сделано на втором.

 
Цитировать
Объект-член заклинит т.к. Qt parent удаляет child'ов.

А если он их удаляет по умному через QPointer? - не смотрел но скорее всего так и есть т.к. не клинит...

Цитировать
Мн. наследование - проблемы с "который QObject?".
Мне тоже кажется что множественное наследование не нужно в данном случае хотя класс описатель интерфейса не является наследником QObject - легко убедиться в этом заглянув в файл ui_Widget.h - это просто класс содержащий набор указателей на ообъекты формы.

Цитировать
очень мне нравится пользоваться дополнением кода (ну эта выпадашка с именами полей объекта) и тут все плюсы у 1 и 2 методов (для 3-го this писать придется   )
достаточно объекты размещенные на форме называть с префикса - например QLabel-ы lbXXXX, QPushButton-ы btnXXXX и т.д. и тогда и this не нужен - и вообще это во всех случаях удобнее!


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: sarbash от Февраль 25, 2010, 19:41
Непонятны мне комментарии по поводу видимости контролов, я склонялся к множественному наследованию как раз по причине более простой инициализации начальных значений виджетов и впоследствии доступа к изменённым значениям оных без дополнительного огорода в виде сигналов/слотов и прочих манипуляций... Разве в плане прямого доступа к значениям input-виджетов преимущественнее приватный мембер-указатель в сабклассе? И как я доберусь из него вне класса?
Для ясности вот пример:
Создается диалоговое окно. Его виждетам надо назначить значения, которые до создания диалога не были известны. Без множественного наследования я смогу добраться до виджетов диалога чтобы назначить им значения, а потом получить новые? Ведь мне показалось, что я не смогу напрямую добраться до виджетов, так как они доступны только через приватный указатель и для этого придётся задействовать другие механизмы?


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: lit-uriy от Февраль 25, 2010, 20:21
как-то подобное на форуме упоминалось.
В пользу первого варианта:
когда проект жирный и рассматриваемый класс используется многими другими файлами, то полная пересборка проекта занимает слишком много времени.


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: break от Февраль 25, 2010, 21:18
Цитировать
Без множественного наследования я смогу добраться до виджетов диалога чтобы назначить им значения, а потом получить новые? Ведь мне показалось, что я не смогу напрямую добраться до виджетов, так как они доступны только через приватный указатель и для этого придётся задействовать другие механизмы?
Для таких вещей делаются инлайн методы для доступа к соответствующим подобъектам или свойствам диалога - причем желательно делать константный и неконстантный вариант. Получать доступ к членам класса без функций оберток неправильно. Есть еще куча способов - например сделать мтруктуру с данными для обмена между диалоговым окном и вызывающим кодом а в окне соответствующую ф-ии

Код
C++ (Qt)
setData( CDataForDialog& data );
getData( CDataForDialog& data );
 


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: sarbash от Февраль 25, 2010, 22:59
Благодарю всех, кто принимал участие в обсуждении.
Получился очень продуктивный диалог.
Беру таймаут на обдумывание. :)

P.S. Читаю и перечитываю Using a Designer UI File in Your Application (http://qt.nokia.com/doc/4.6/designer-using-a-ui-file.html) до полного просветления...


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: SABROG от Февраль 26, 2010, 03:35
По сути первый способ это та же техника, которая используется внутри Qt.
Объект представлен двумя классами:
- класс интерфейс, весь такой чистенький, красивенький, мусора нет, низкая зависимость от приватной реализации, внешняя статичность.
- приватный класс реализации. Машинный цех, тут члены добавляются, удаляются, их типы и названия постоянно меняются, исправляются баги. Интерфейс такого класса потенциально изменчив точно также как размер самого класса.

оба класса зафрендили друг друга, чтобы получать доступ к приватным членам. Интерфейс получает доступ к приватному классу и его членам через указатель, который возвращается макросом Q_D, а приватный класс использует макрос Q_Q, чтобы получить обратный доступ к интерфейсу. То есть они оба содержат в себе по указателю на друг друга. Если взять в пример QLineEdit, то тут вообще сказка получается:

QLineEdit - интерфейс
QLineEditPrivate - приватная реализация

И наследование:

QLineEdit <- QWidget <- QObject
QLineEditPrivate <- QWidgetPrivate <- QObjectData

указатель d_ptr возвращаемый макросом Q_D одновременно указывает сразу на 3 приватных класса
указатель q_ptr возвращаемый макросом Q_Q также одновременно указывает на 3 интерфейса


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: kkk777kkk от Февраль 26, 2010, 11:13
Цитировать
что имеется ввиду - они во всех вариантах видны если я так понял

имел ввиду, что c префиксом "ui" мне удобнее потом разбирать код


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: SABROG от Февраль 26, 2010, 15:13
Указатель ui при этом играет ту же роль, что и q_ptr.


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: b-s-a от Февраль 26, 2010, 17:00
По сути первый способ это та же техника, которая используется внутри Qt.
... она называется PIMPL (Pointer to IMPLementation)


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: sarbash от Февраль 27, 2010, 00:08
После неторопливого размышления и взвешивания всех за и против выбор пал в пользу агрегации через указатель.


Название: Re: Qt Creator - вопрос по выбору способа встраивания ui
Отправлено: SABROG от Февраль 27, 2010, 01:16
По сути первый способ это та же техника, которая используется внутри Qt.
... она называется PIMPL (Pointer to IMPLementation)

Похоже, но тут структура сложнее. Если брать конкретно QWidget, то у него есть QWidgetPrivate класс. При этом в файлах реализации: qwidget_win.cpp, qwidget_x11.cpp переопределение идет методов как QWidget, так и QWidgetPrivate.
То есть тут двойной pimpl, при этом и файл QWidget и QWidgetPrivate не являются абстрактными интерфейсами, в них тоже до кучи своих методов, которые уже не зависят от нативных реализаций. А так они бы могли QWidgetPrivate вообще убрать за ненадобностью и в файле qwidget_win.cpp просто сделать реализацию методов QWidget класса. Ну или все методы которые они переопределили для QWidget переместить в QWidgetPrivate, который полностью перенести в тот же qwidget_win.cpp. Только в этом случае им бы пришлось делать кучу лишней работы, так внутреннюю реализацию пришлось бы исправлять для всех ОС одновременно. В общем приват классы что-то типа машинного цеха с общим двигателем для любой платформы. Если основная цель pimpl предоставить одинаковую работу под разными платформами или условиями, то приватные классы такой цели себе не ставят, разве что на уровне отдельно взятых методов, а не всего класса целиком.