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

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

Страниц: [1] 2 3 ... 5   Вниз
  Печать  
Автор Тема: "Закрытость" Qt  (Прочитано 35988 раз)
AzazelloAV
Гость
« : Март 14, 2015, 15:46 »

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

О чём я? О  функции (в cpp):
    NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in qgraphicsitem.cpp!

    NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in
          qgraphicssvgitem.cpp!

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

« Последнее редактирование: Март 14, 2015, 16:05 от AzazelloAV » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Март 15, 2015, 10:56 »

Многие функции, с которыми я сталкивался (как по мне) должны были быть виртуальными, аль нет.
Да, такое впечатление есть, но мне кажется оно проходит с опытом. Qt явно стремится к минимуму виртуалов, и в этом есть смысл. Виртуал практически вынуждает наследование которое часто может оказаться неудачным (то самое "не плодите сущностей"). Приведите примеры чтобы говорить более конкретно.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #2 : Март 15, 2015, 11:11 »

Qt явно стремится к минимуму виртуалов, и в этом есть смысл.
Qt не стремится к "минимуму виртуалов", разработчики стремятся правильно проектировать классы, и не делать виртуальными методы те, которым это не нужно.

Виртуал практически вынуждает наследование которое часто может оказаться неудачным (то самое "не плодите сущностей").
Ну это у вас наследование часто оказывается неудачным. Улыбающийся
Все остальные спокойно пользуются этим основополагающим свойством языка. Его именно для наследования и придумали.
Записан
AzazelloAV
Гость
« Ответ #3 : Март 15, 2015, 13:24 »

Многие функции, с которыми я сталкивался (как по мне) должны были быть виртуальными, аль нет.
Да, такое впечатление есть, но мне кажется оно проходит с опытом. Qt явно стремится к минимуму виртуалов, и в этом есть смысл. Виртуал практически вынуждает наследование которое часто может оказаться неудачным (то самое "не плодите сущностей"). Приведите примеры чтобы говорить более конкретно.

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

Ну а насчет примера, где не помешали бы виртуальные методы:
Их настолько много, что пример не приходит в голову, не хочу сейчас придумывать ситуацию, встречу, сразу отпишусь, это не так много времени. Ну ладно, из придуманого QGraphicsItem::setVisible. Почему за меня решили, что дополнительных действий в данной операции быть не может (QGraphicsItem - базовый класс для использования в коллекции QGraphiscScene). По сути, чтобы реализовываться свои QGraphicsItem мне приходится создавать свой класс и пользоваться множесвенным наследованием. От блин, неудачный пример, там события на него вроде есть. Встречу реальный, отпишусь.

Ура, ура. Нашёл. В моем реальном проекте
QGraphicsItemGroup *   QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> & items)

Метод возвращает конктетный класс (объект класса), мне же нужен мой. Он может возращать данный тип, в коллекции по другому не получится, но вот внутри мне нужно new МойГроупКласс. Я не спорю, данный метод не обязательно должен быть виртуальным, но вот вызывать протекстед виртуальный createItemGroup не помешало бы.

« Последнее редактирование: Март 15, 2015, 13:46 от AzazelloAV » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Март 15, 2015, 13:49 »

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

Встречу реальный, отпишусь.
Ну хорошо, посмотрим  Улыбающийся
Записан
AzazelloAV
Гость
« Ответ #5 : Март 15, 2015, 14:01 »

ф-ции - пока, потом может они станут разными. Не вижу чем вызвано негодование Улыбающийся И причем тут (якобы) недостающие виртуалы?

Ну, эта функция рисует рамку. Вы кляцнули на что-то, и рамка появилась (элемент выделен). Эту рамку нельзя заменить на свою, что уже плохо. Негодования нету, уже привык давно. Но а теперь, я создаю свой элемент коллекции. И что же мне делать, точно также копировать этот код и писАть  - скопировать с Qt. Мало того, не существует возможности заменить рамку на свою, приходится так извращаться, что ужас. И эта не та "рамка", которую не стоит изменять, дабы не сбить пользователя с толку.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Март 15, 2015, 14:37 »

Мало того, не существует возможности заменить рамку на свою, приходится так извращаться, что ужас. И эта не та "рамка", которую не стоит изменять, дабы не сбить пользователя с толку.
Чего ж не существует? Смотрим исходник
Код
C++ (Qt)
void QGraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
   Q_D(QGraphicsPolygonItem);
   Q_UNUSED(widget);
   painter->setPen(d->pen);
   painter->setBrush(d->brush);
   painter->drawPolygon(d->polygon, d->fillRule);
 
   if (option->state & QStyle::State_Selected)
       qt_graphicsItem_highlightSelected(this, painter, option);
}
 
Ну, стало быть, наш paint
Код
C++ (Qt)
void MyPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
   bool selected = (option->state & QStyle::State_Selected) != 0;
   option->state &= ~QStyle::State_Selected;
 
   QGraphicsPolygonItem::paint(painter, option, widget);
 
   if (selected) {
     option->state |= QStyle::State_Selected;
     MyDrawSelect(painter, option, widget);
   }
}
 
Ну или фильтрок навесить, тогда можно и не наследоваться, и рисовать выбор для всех айтемов. Это что, титанические усилия?  Улыбающийся Конечно было бы еще лучше иметь это в стиле (как для виджетов). Но это никак не виртуал.

Ура, ура. Нашёл. В моем реальном проекте
QGraphicsItemGroup *   QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> & items)

Метод возвращает конктетный класс (объект класса), мне же нужен мой. Он может возращать данный тип, в коллекции по другому не получится, но вот внутри мне нужно new МойГроупКласс. Я не спорю, данный метод не обязательно должен быть виртуальным, но вот вызывать протекстед виртуальный createItemGroup не помешало бы.
Да, если нужно МойГроупКласс (вместо QGraphicsItemGroup) - придется самому, скопировать из исходников и заменить new. Ну или сразу template. Но объявление этого метода виртуалои все равно не помогло бы.
Записан
AzazelloAV
Гость
« Ответ #7 : Март 15, 2015, 17:17 »

Код:
[quote author=Igors link=topic=28597.msg209285#msg209285 date=1426419474]
[quote author=AzazelloAV link=topic=28597.msg209281#msg209281 date=1426417265]
Мало того, не существует возможности заменить рамку на свою, приходится так извращаться, что ужас. И эта не та "рамка", которую не стоит изменять, дабы не сбить пользователя с толку.
[/quote]

Ну, стало быть, наш paint
Код
C++ (Qt)
void MyPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
   bool selected = (option->state & QStyle::State_Selected) != 0;
   option->state &= ~QStyle::State_Selected;
 
   QGraphicsPolygonItem::paint(painter, option, widget);
 
   if (selected) {
     option->state |= QStyle::State_Selected;
     MyDrawSelect(painter, option, widget);
   }
}
 
Ну или фильтрок навесить, тогда можно и не наследоваться, и рисовать выбор для всех айтемов. Это что, титанические усилия?  Улыбающийся Конечно было бы еще лучше иметь это в стиле (как для виджетов). Но это никак не виртуал.

Давайте так, чтобы это не превратилось в воду, как сказали в  прошлой теме.
Здесь же вопрос стоит не "как", а "почему".
Понятно, убираем флаг (чтобы сдуру базовый класс не перерисовал), рисуем свой, восстанавливаем флаг (кстати, из коробки работать не будет, там ещё есть завязки) . Вот про эти извращения я и говорил. Если Вы считаете это нормальным, тогда чтож, данный топик не имеет смысла.

Так и работаем, не жалуемся. Но это, скажем так, курилка, и мысли вслух просто.
Так вот, вопрос -  зачем мы должны так извращаться. Какие накладные расходы несёт данный метод, если бы его сделать протектед виртуал? При чем здесь разные части библиотеки? Если это сделано так, я точно уверен, что из за политики Qt, а не целесообразности программирования.
Это все риторические вопросы.
Я ничего не добиваюсь, но эта интересная особенность вовсе не особенность, а целенеправленная фигня.

И стили здесь не причем. Стили - это стили, а мне нужно изменить поведение рамки в зависимости от моих условий. К примеру - рисовать розочки по внутренним углам.

P.S. Кстати, что такое фильтрок
« Последнее редактирование: Март 15, 2015, 17:33 от AzazelloAV » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Март 15, 2015, 18:12 »

Понятно, убираем флаг (чтобы сдуру базовый класс не перерисовал), рисуем свой, восстанавливаем флаг (кстати, из коробки работать не будет, там ещё есть завязки) . Вот про эти извращения я и говорил. Если Вы считаете это нормальным, тогда чтож, данный топик не имеет смысла.
Я считаю это абсолютно нормальным использованием наследования.

Какие накладные расходы несёт данный метод, если бы его сделать протектед виртуал?
Какой "данный метод"? QGraphicsItem::paint и так виртуал, а если разговор о QGraphicsScene::createItemGroup, то уже говорилось - там хоть виртуал, хоть нет, не поможет.

Так что на данный момент не видно в чем же "закрытость" Qt. Ни одного реального примера "плохо-расширяемости" Вы так и не привели. Выглядит как типичная мечта люмпена "как бы ни хрена не делать и зарплату получать"  Улыбающийся
Записан
AzazelloAV
Гость
« Ответ #9 : Март 15, 2015, 18:25 »


Так что на данный момент не видно в чем же "закрытость" Qt. Ни одного реального примера "плохо-расширяемости" Вы так и не привели. Выглядит как типичная мечта люмпена "как бы ни хрена не делать и зарплату получать"  Улыбающийся

В какую то другую сторотону всех понесло. Люмпена какого-то привели. Если Вы считаете, что копирование полностью функции это "хорошая" расширяемость.... Ну чтож, тогда нужно и QObject туда копировать. Если это не кричащий пример плохой расширяемости, то я пас. Чего Вы защищаетесь, никто ни на Qt, ни на Вас не нападал. Едрить его налево.....
Цитировать
Какой "данный метод"? QGraphicsItem::paint и так виртуал, а если разговор о QGraphicsScene::createItemGroup, то уже говорилось - там хоть виртуал, хоть нет, не поможет.
Не знаю, кем говорилось. Но поможет, очень даже.

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

P.S. И таки да, Ваш код скопировал, сразу штука баксов капнула.
« Последнее редактирование: Март 15, 2015, 18:39 от AzazelloAV » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #10 : Март 15, 2015, 23:58 »

Qt самая лучшая библиотека (фреймворк), лучше ничего нету, а кто ей не умеет пользоваться, у того руки кривые.

Тащемта, так и есть.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Март 16, 2015, 09:00 »

Чего Вы защищаетесь, никто ни на Qt, ни на Вас не нападал.
Ну к числу защитников Qt я никогда не принадлежал, что может подтвердить хотя бы автор предыдущего поста.  

Если Вы считаете, что копирование полностью функции это "хорошая" расширяемость.... Ну чтож, тогда нужно и QObject туда копировать. Если это не кричащий пример плохой расширяемости, то я пас.
О какой ф-ции Вы говорите? qt_graphicsItem_highlightSelected с которой начали тему? Или о QGraphicsScene::createItemGroup? И на то и на другое я ответил. Если Вы не поняли - или поняли. но не согласны - пожалуйста, высказывайтесь, и я попробую ответить. Но не надо "ходить кругами" повторяя одно и то же  
« Последнее редактирование: Март 16, 2015, 12:34 от Igors » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #12 : Март 16, 2015, 13:51 »

   NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in qgraphicsitem.cpp!

Вообще-то, такие комментарии они пишут для того, чтобы в будущем избавиться от копипасты (и не копировать 3й раз, а заюзать одну из двух). Почему это не сделано сейчас - вопрос. Скорее всего, эти ф-ии всё-таки чем-то отличаются и надо сделать ненулевую работу, чтобы копипасту убрать.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Март 16, 2015, 15:56 »

Вообще-то, такие комментарии они пишут для того, чтобы в будущем избавиться от копипасты (и не копировать 3й раз, а заюзать одну из двух). Почему это не сделано сейчас - вопрос. Скорее всего, эти ф-ии всё-таки чем-то отличаются и надо сделать ненулевую работу, чтобы копипасту убрать.
Если убрать эту ф-цию напр из qgraphicssvgitem.cpp, то где она должна быть? Для нее просто не находится подходящего места (во всяком случае пока), поэтому проще дублировать. Заметим что ф-ция наглухо закрыта, пользователю ее не обещали.
Записан
AzazelloAV
Гость
« Ответ #14 : Март 16, 2015, 19:35 »

Вообще-то, такие комментарии они пишут для того, чтобы в будущем избавиться от копипасты (и не копировать 3й раз, а заюзать одну из двух). Почему это не сделано сейчас - вопрос. Скорее всего, эти ф-ии всё-таки чем-то отличаются и надо сделать ненулевую работу, чтобы копипасту убрать.
Если убрать эту ф-цию напр из qgraphicssvgitem.cpp, то где она должна быть? Для нее просто не находится подходящего места (во всяком случае пока), поэтому проще дублировать. Заметим что ф-ция наглухо закрыта, пользователю ее не обещали.

Ну, её можно было бы засунуть в static protected метод класса QGraphicsItem, тем более что она не использует данные класса, пользователь данной функции ничего бы поломать не смог.
Если рассмотреть подсистему QGraphicsView (по названию каталога исходников), то там практически она вся закрыта. Добавлять новый функционал очень сложно и при том она ещё и глючит кое-где. Я, если честно, не понял вашего решения с groupClass (придется самому, скопировать из исходников и заменить new). Да, это понятно, но извените, топик как раз и называется - закрытость Qt, это ли не показатель закрытости? Тем более, вы долны понимать, что это решение (теоретически) может нехило выстрелить при изменении версии Qt. Также не понятен вопрос лицензионности - имеем ли мы право такой копипастой заниматься (May keep Qt modifications private, хотя это вторично). Да и это частичное решение, ведь QGraphicsScene гуляет в виде класса везде, и нам прийдётся делать приведения типа, чтобы вызвать свою функцию, что не такой мелкий геморой, если размазать по всему проекту с десятками таких "если".

Цитата: Авварон
Вообще-то, такие комментарии они пишут для того, чтобы в будущем избавиться от копипасты (и не копировать 3й раз, а заюзать одну из двух). Почему это не сделано сейчас - вопрос. Скорее всего, эти ф-ии всё-таки чем-то отличаются и надо сделать ненулевую работу, чтобы копипасту убрать.

Функция байт в байт. Никакой работы делать не нужно, если написание пару буков есть работа. Ведь смотрите как получилось у них. Была работа со сценой, и тут бах, в отдельном модуле нужно реализовать такой же функционал. Ведь мы понимаем, что модуль - это административное понятие (в данном случае). Что делать? Та просто что недоступно, скопируем.

И ваша (или  моя)  реализация функционала нового (такой же модуль в отношении Qt), тоже требует тупого копирования.
« Последнее редактирование: Март 16, 2015, 23:02 от AzazelloAV » Записан
Страниц: [1] 2 3 ... 5   Вверх
  Печать  
 
Перейти в:  


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