Название: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 17, 2015, 14:28 Мне нужно расширить стандартные контролы Qt рядом функций. Они должны уметь перемещаться по родительскому виджету не вылезая за его границы, выдавать данные о своей геометрии, реагировать на набор общих сигналов. Все эти функции совершенно одинаковы для всех контролов, которые все являются виджетами. Но еще они должны принимать и отправлять, различные сигналы, и выполнять дополнительные функции, которые специфичны для каждого класса виджета.
Код общих методов написан и отлажен на примере одного контрола, но сейчас при создании других контролов придётся дублировать как тела методов, так и их объявления в заголовках. Тупо можно было бы и макрос написать, но шаблоны мощнее и современнее. Если бы в Qt было разрешено множественное наследование от QObject, я бы сделал всё очень просто. Но увы, так нельзя. Если бы у классов не было различий, можно было бы все контролы накрыть одним шаблоном и узбагоиться. Но из-за наличия существенных различий контролов, классы примерно на 50% одинаковые, и на 50% различаются. Похоже это надо делать на специализированных шаблонах. Я их совместно с Qt не использовал (честно говоря, вообще в реальных приложениях ни разу не использовал), поэтому вопрос - нет ли каких-либо подводных камней при использовании специализированных шаблонов в контексте GNU CC/MinGW и Qt конкретно версии 4.7? Кто-нибудь использует эту технику в реальных проектах? Вообще моя задача решаема этим способом? Название: Re: Специализированные шаблоны для контролов Qt Отправлено: m_ax от Апрель 17, 2015, 15:33 Цитировать Код общих методов написан и отлажен на примере одного контрола, но сейчас при создании других контролов придётся дублировать как тела методов, так и их объявления в заголовках. Тупо можно было бы и макрос написать, но шаблоны мощнее и современнее. А так ли здесь нужны шаблоны? Пишите свой базовый класс, в котором реализуете все общие методы, а от него уже наследуете другие контролы, в которых дописываете только специфмчные для них методы. и т.д. Или я чего-то не понял? Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 17, 2015, 15:50 А так ли здесь нужны шаблоны? А по-моему нужны (вот уж никак не ожидал себя в такой роли :)). Дело в том что базовый класс не может быть QObject, ему придется включать напр QLineEdit (или др Qt контрол) агрегатом - и это здесь очень неудобно. Напр QLineEdit получил сигнал - и что, надо передавать в базовый, а тот не QObject (и понеслась)Пишите свой базовый класс, в котором реализуете все общие методы, а от него уже наследуете другие контролы, в которых дописываете только специфмчные для них методы. и т.д. Или я чего-то не понял? Название: Re: Специализированные шаблоны для контролов Qt Отправлено: m_ax от Апрель 17, 2015, 15:57 Цитировать А по-моему нужны (вот уж никак не ожидал себя в такой роли Улыбающийся). Дело в том что базовый класс не может быть QObject Почему?Базовый класс наследуется от QWidget, т.к. Цитировать Они должны уметь перемещаться по родительскому виджету не вылезая за его границы, выдавать данные о своей геометрии, реагировать на набор общих сигналов. Все эти функции совершенно одинаковы для всех контролов, которые все являются виджетами. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 17, 2015, 16:09 Почему? Но не "одним и тем же виджетом/классом". Унаследовавшись от QWidget - уже не унаследоваться от того же QLineEditБазовый класс наследуется от QWidget, т.к. Цитировать Они должны уметь перемещаться по родительскому виджету не вылезая за его границы, выдавать данные о своей геометрии, реагировать на набор общих сигналов. Все эти функции совершенно одинаковы для всех контролов, которые все являются виджетами. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 17, 2015, 16:17 Базовый класс наследуется от QWidget, т.к. QWidget наследует от QObject. Все стандартные контролы тоже наследуют от QWidget. И там еще хуже - если установлен родитель для QWidget, то нельзя установить родителя для QObject, от которого он наследует (если бы можно было, я бы выкрутился). Просьба не продолжать вариант с множественным наследованием - в Qt это нереализуемо. Если бы было допустимо двойное наследование от QObject, я бы уже так и сделал. Единственный вариант - специализированные шаблоны. Но прежде чем начинать чеканить плохо изученный металл, я хочу пообщаться с теми, кто так делал. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Old от Апрель 17, 2015, 16:57 Можно попробовать сделать так (кстати, со множественным наследованием :) ):
Код
Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 17, 2015, 17:07 Единственный вариант - специализированные шаблоны. Но прежде чем начинать чеканить плохо изученный металл, я хочу пообщаться с теми, кто так делал. Ну если единственный, т.е. Вы уже все решили - зачем нужно еще какое-то общение? :) Конкретно для Qt контролов не делал, поэтому в первую очередь проверил бы нет ли там засады с Q_OBJECT т.е. можно ли такКод
Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 17, 2015, 17:25 Можно попробовать сделать так (кстати, со множественным наследованием :) ): Без множественного наследования от QObject. Код
Сейчас именно так и сделано для отладки кода общих методов. Но беда в том, что большинство методов, которые общие для всех расширенных контролов - сигналы или слоты. Так у меня дизайн сделан, и это нельзя изменить. Причём у всех контролов они одинаковые. Фактически в класс Common получилось вынести только обработку событий мыши. И то не роскошно - события то принимать надо в классе MyLineEdit из примера. А в режиме нормальной работы контролов необходимо вызывать методы приёмников у родительского класса. В общем, пришлось пока объявить typedef-ом общий SuperClass, который должен быть классом контрола, то есть typedef QLineEdit SuperClass, и вызывать SuperClass::mousePressEvent(event) когда надо, чтобы кнопка нажималась, или строка редактировалась. Но это всё, включая ваш пример, не отменило необходимости копировать все методы, которые являются сигналами или слотами. Поскольку Common - не QObject... Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 17, 2015, 17:27 в первую очередь проверил бы нет ли там засады с Q_OBJECT Вот я об этом и спрашиваю - работал ли кто-либо с таким вариантом. Мне это может сэкономить день (с учетом поиска вариантов обхода, которых может быть и не существует), а отвечающему - занять несколько минут. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Old от Апрель 17, 2015, 17:32 Вот я об этом и спрашиваю - работал ли кто-либо с таким вариантом. Мне это может сэкономить день (с учетом поиска вариантов обхода, которых может быть и не существует), а отвечающему - занять несколько минут. Это не работает с moc.Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Bepec от Апрель 17, 2015, 17:33 Пытались люди использовать шаблоны с QObject'ом.
Ничего кроме крови пота и боли они не получили. Но попробуйте, вдруг у вас получится :) Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Nimbus от Апрель 17, 2015, 18:21 Пытались люди использовать шаблоны с QObject'ом. Да, пропатчить moc, чтобы он находил по коду проекта все инстанцинации шаблонов таких классов и генерил для каждого соответственный метаобъектный код. ;DНичего кроме крови пота и боли они не получили. Но попробуйте, вдруг у вас получится :) Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Old от Апрель 17, 2015, 18:29 Но это всё, включая ваш пример, не отменило необходимости копировать все методы, которые являются сигналами или слотами. Тела слотов можно выносить в функции common, а в самих слотах вызывать эти функции.Кстати, в Qt5 можно не объявлять методы слотами, использовать новый вариант connect. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 17, 2015, 19:03 Но это всё, включая ваш пример, не отменило необходимости копировать все методы, которые являются сигналами или слотами. Тела слотов можно выносить в функции common, а в самих слотах вызывать эти функции.Смысла особого нет, поскольку тела слотов из 2-3 строк. Но еще можно мега-макрос написать... наверно я так и сделаю, если есть проблемы с шаблонами и Q_OBJECT. Кстати, в Qt5 можно не объявлять методы слотами, использовать новый вариант connect. На 4.7 делается. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 18, 2015, 08:56 Мне это может сэкономить день (с учетом поиска вариантов обхода, которых может быть и не существует), а отвечающему - занять несколько минут. Так ведь и другие (включая меня) думают так же: "та оно мне надо чего-то "изыскивать", экспериментировать? Вот найти пример и сделать по образцу - то да". Qt очень поощряет такой потребительский подход, ведь практически он очень эффективен. Почему-то вспоминается "Незнайка на Луне" как они там в конце все собирались строить лодку чтобы бежать с острова :)Ну ладно, не проходит так не проходит. Тогда может быть так Код Так придется написать для каждого базового контрола - ну не беда, это всего неск строк. А в MySlotSignals рисуете общие слоты-сигналы. Если надо перенаправляете их на чистые виртуалы. И тогда уже Код Но тут нет общего базового класса выше QWidget. Напр Код Можно пользоваться только методами QWidget - и все. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 19, 2015, 15:59 Грубо, безобразно, хак - но так работает. Так я вообще с первого раза сделал, еще до своего первого поста в этой ветке. Просто не стал тут грубить. Даже шаблоны не нужны - просто в инклюд улетел добрый кусок класса контрола, вместе с методами получения событий мыши. В результате, например, объявление класса кнопки стало выглядеть вот так:
Код: #ifndef WBUTTON_H PluginInterface тут, поскольку каждый контрол сидит в Qt-плагине Название: Re: Специализированные шаблоны для контролов Qt Отправлено: vregess от Апрель 19, 2015, 18:09 Почему бы вместо typedef и include не обернуть общий функционал в макрос по аналогии с макросами Qt? Будет легче понять, что происходит.
Это в принципе не особо и хак, просто workaround для MOC. Код
Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 19, 2015, 20:13 Почему бы вместо typedef и include не обернуть общий функционал в макрос по аналогии с макросами Qt? Будет легче понять, что происходит. Это в принципе не особо и хак, просто workaround для MOC. Код
Потому что такие макросы практически невозможно отлаживать. GDB и QtCreator на них колдобятся. В случае инклюда и точки останова работают, и переменные можно просматривать. И не надо каждый раз при добавлении или удалении qDebig() чего-то добавлять или удалять. И вообще править такие макросы неудобно (я в других местах использовал, наплевался уже). А функционально результат почти не отличается, даже хуже - надо в двух местах родительский класс контрола указывать, можно ошибиться. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: vregess от Апрель 19, 2015, 21:26 Потому что такие макросы практически невозможно отлаживать. GDB и QtCreator на них колдобятся. В случае инклюда и точки останова работают, и переменные можно просматривать. И не надо каждый раз при добавлении или удалении qDebig() чего-то добавлять или удалять. И вообще править такие макросы неудобно (я в других местах использовал, наплевался уже). А функционально результат почти не отличается, даже хуже - надо в двух местах родительский класс контрола указывать, можно ошибиться. С отладкой да, есть недостаток. Ну а что если вместо наследования использовать агрегирование (навроде pimpl)? Код
+ не забыть удалить commonImpl (можно обернуть в умный указатель). Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 19, 2015, 21:39 А это уже в гамаке и стоя, при том, что преимуществ не видно.
Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 20, 2015, 07:53 Ну а что если вместо наследования использовать агрегирование (навроде pimpl)? pimpl для того чтобы расписывать "для каждого", а здесь наоборот, нужно "для всех" (общая часть)Даже шаблоны не нужны... А ведь совсем недавно Вы весьма уверенно утверждали что специализация - единственный выход. Вероятно Вы хотели подтолкнуть обсуждение в нужном направлении, но все-таки обманывать нехорошо. Выходит Вам нельзя верить :)Я не вижу ничего страшного в таком инклуде, но вот если они начнут "расползаться", т.е. если их появится 2 и больше - тогда хана. Это может случиться если понадобится метод(ы) базового контрола которых нет у других, или наоборот. Напр setValue для QLineEdit. Тогда все-таки придется нырять в шаблоны. Ну а если такой проблемы нет, то и слава богу, меньше template-гадости = лучше Название: Re: Специализированные шаблоны для контролов Qt Отправлено: vregess от Апрель 20, 2015, 08:00 А это уже в гамаке и стоя, при том, что преимуществ не видно. Это смотря где ты ищешь преимущества. По мне преимущество только архитектурное: хоть какая-то инкапсуляция и возможность расширения (не факт, что ей придется воспользоваться); но писанины больше. include внутри класса - явный хак. Вообще, мне кажется, наследование здесь не лучший вариант, возможно с отдельным классом получится удачнее. Но хозяин-барин, решать все-равно тебе. pimpl для того чтобы расписывать "для каждого", а здесь наоборот, нужно "для всех" (общая часть) Поэтому и добавил "навроде". pimpl упомянут только чтобы показать направление реализации. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 20, 2015, 08:42 Вообще, мне кажется, наследование здесь не лучший вариант, возможно с отдельным классом получится удачнее. Но хозяин-барин, решать все-равно тебе. Поясню проблему как я ее понимаю (а ТС если надо поправит). Напрашивается такКод
Часто (и в этом топике) звучит, мол, "ах, вот если бы поддерживалось множественное наследование от QObject...". - тогда и проблем бы никаких не было. Не вижу что это особо меняет. Ну хорошо, допустим Common унаследован от QObject (предположим так можно). И что с того? Сигнал-то получает QLineEdit - а совсем не Common, проблемы те же Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Old от Апрель 20, 2015, 10:02 Здесь мы можем получить виджет имея Common, но "не наоборот". Не знаю о чем вы говорите, но новый виджет содержит в себе Common, а Common имеет указатель на виджет, для удобства доступа.Пример: вызван слот QLineEdit'а, как Common может на это среагировать? Никак, потому что QLineEdit "не наш". Опять же не знаю, кто там наш/не наш. Предлагалось вынести в common код общих методов и вызывать его из слотов самого виджета:Код
А эти слоты можно попробовать завернуть в макросы. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 20, 2015, 14:57 Ну а что если вместо наследования использовать агрегирование (навроде pimpl)? pimpl для того чтобы расписывать "для каждого", а здесь наоборот, нужно "для всех" (общая часть)Даже шаблоны не нужны... А ведь совсем недавно Вы весьма уверенно утверждали что специализация - единственный выход. Вероятно Вы хотели подтолкнуть обсуждение в нужном направлении, но все-таки обманывать нехорошо. Выходит Вам нельзя верить :)Не выход, а вариант. По вопросам веры надо идти в церковь. Вариант с инклюдом я не считал, и не считаю приемлемым вариантом решения, даже при том, что он фактически наиболее простой и работающий. Во-1ых, может потребоваться наличие общих слотов/сигналов для нескольких контролов, но не для всех (хотя это тоже с помощью инклюда делается...). Во-2ых, может потребоваться наследование от имеющихся контролов. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 20, 2015, 15:06 Опять же не знаю, кто там наш/не наш. Предлагалось вынести в common код общих методов и вызывать его из слотов самого виджета: Код
А эти слоты можно попробовать завернуть в макросы. Делал так. Не имеет смысла, поскольку "commonMethodText( val )" и "commonMethodReturn();" сами состоят из 1-3-х строк, а весь кусок private slots всё равно надо копировать. Или заворачивать в многострочный макрос (тоже делал) - но тогда отлаживать нормально не получается. Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 20, 2015, 15:11 Это смотря где ты ищешь преимущества. По мне преимущество только архитектурное: хоть какая-то инкапсуляция и возможность расширения (не факт, что ей придется воспользоваться); но писанины больше. include внутри класса - явный хак. Вообще, мне кажется, наследование здесь не лучший вариант, возможно с отдельным классом получится удачнее. Но хозяин-барин, решать все-равно тебе. В варианте агрегирования не удаётся избавиться от копирования одинаковых методов в реализациях. Только вместо обработки сигналов, эти методы занимаются передачей сигналов для обработки. См. выше пример от Old. В варианте инклюда общий класс у контролов вообще исчез. Преимущества, которые для меня важны - упрощение и уменьшение кода, упрощение его модификации, возможность отладки. С расширением пока не ясно... Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 20, 2015, 15:22 Во-1ых, может потребоваться наличие общих слотов/сигналов для нескольких контролов, но не для всех (хотя это тоже с помощью инклюда делается... Я в этом сильно сомневаюсьНазвание: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 20, 2015, 15:57 Во-1ых, может потребоваться наличие общих слотов/сигналов для нескольких контролов, но не для всех (хотя это тоже с помощью инклюда делается... Я в этом сильно сомневаюсьВ чем именно? Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 20, 2015, 16:15 В чем именно? В том что это решается (еще одним) инклудом. Станет их хотя бы 2 - пиши пропалоНазвание: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Апрель 20, 2015, 16:43 Код: class WButton : public SuperClass Страшного ничего при этом не наступает, хотя конечно - это тоже хак (to hack - англ. рубить). То есть, топором... Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Igors от Апрель 20, 2015, 17:25 Код: class WButton : public SuperClass Название: Re: Специализированные шаблоны для контролов Qt Отправлено: RiZ от Май 30, 2018, 20:39 Какой путь избрали?
Название: Re: Специализированные шаблоны для контролов Qt Отправлено: Гурман от Май 31, 2018, 00:34 |