Поиск:

Ответ в темуСоздание новой темы Создание опроса
> QGraphicsPathItem vs QVector<QGraphicsLineItem>, Нужен совет 
:(
    Опции темы
Glad
  Дата 23.4.2014, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 16.8.2005

Репутация: нет
Всего: нет



Доброго времени суток!
У меня задача нарисовать дорогу по модели(данные). Я нашёл(случайно) класс QGraphicsPathItem и все связанные с ним(QPainterPath, например). Но взглянув внутрь, как-то смутился.. Черепашья графика ? Зачем нужен этот класс ? И имеет ли он какие-нибудь преимущества над скажем QVector<QGraphicsLineItem> ?
Заранее благодарю.
PM MAIL   Вверх
Amp
Дата 23.4.2014, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 886
Регистрация: 17.2.2009

Репутация: 7
Всего: 17



QPainterPath позволяет создавать сложные контуры и кривые, комбинируя их из простых линий, дуг, кривых Безье, тестовых глифов и т.п. Полученный путь (path) можно сохранить и использовать (отрисовать) в будущем. Стандартная сущность для векторной графики (аналог, например, cairo_path_t в cairo). Все это конечно же можно аппроксимировать вручную линиями, сложив их в вектор, но это мартышкин труд с кучей недостатков. Например будут проблемы с заливкой, пересечениями контуров, соединениями между линиями (joins).
PM MAIL   Вверх
Glad
Дата 23.4.2014, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 16.8.2005

Репутация: нет
Всего: нет



Вы знаете меня смутило несколько вещей в этом всём деле. Вот несколько из них:
* Каждый элемент Path это не обязательно фигура.. В частности, там возвращается тип объекта moveTo, что как-то странно(хотя в терминах черепашьей графики это нормально).
* Селекшн не всегда работает правильно.. Я нарисовал тестовую ломанную с помощью этих инструментов и ломанная выделялась даже если я кликал мимо нее. Впрочем, определить алгоритм попадания я так и не смог: по началу я подумал что это просто попадание в BoundingBox ломанной, но потом потестировав и "потыкав" по экрану, понял что это не так. 
* Нет возможности выделять и редактировать  элементы ломаной. Если я захочу выделить элемент ломаной и что-то с ним сделать(например, изменить толщину дороги в этом участке или сменить тип дороги с гравейки на асфальт) то этого не сделаешь с помощью этих инструментов(а может быть я их просто не знаю?).

Вот как-то так.. Всё конечно зависит от решаемой задачи.. Если задача вывести буквы/цифры без возможности редактирования, то наверное этот инструмент подошёл как нельзя лучше. 


PM MAIL   Вверх
Amp
Дата 23.4.2014, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 886
Регистрация: 17.2.2009

Репутация: 7
Всего: 17



Цитата(Glad @  23.4.2014,  14:28 Найти цитируемый пост)
* Каждый элемент Path это не обязательно фигура.. В частности, там возвращается тип объекта moveTo, что как-то странно(хотя в терминах черепашьей графики это нормально).

Фигуры - это комбинации линий  и кривых. Например path в виде прямоугольника можно представить комбинацией одного moveTo и четырех lineTo вызовов. В итоге будет образован замкнутый контур, который мы сможем назвать фигурой. Методы addRect, addPolygon, addEllipse можно считать высокоуровневыми надстройками, которые в своей реализации все равно в итоге сводятся к последовательности из moveTo/lineTo/arcTo. Ну да, выходит, что бегает черепашка и оставляет за собой линию. В определенные моменты она может обравать линию и начинать рисовать новую (получаются sub path-ы в рамках одного path).

Цитата(Glad @  23.4.2014,  14:28 Найти цитируемый пост)
* Нет возможности выделять и редактировать  элементы ломаной. Если я захочу выделить элемент ломаной и что-то с ним сделать(например, изменить толщину дороги в этом участке или сменить тип дороги с гравейки на асфальт) то этого не сделаешь с помощью этих инструментов(а может быть я их просто не знаю?).

Это все надо писать самому. К тому же нельзя изменить цвет или толщину какого-то отдельного учатка внутри path. Для Qt это один целый элемент, к которому применяется текущие настройки кистей и цвета.


Цитата(Glad @  23.4.2014,  14:28 Найти цитируемый пост)
* Селекшн не всегда работает правильно

Не знаю в чем тут дело.
PM MAIL   Вверх
math64
Дата 24.4.2014, 07:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Это не черепашья графика. Черепашья графика - это когда изображение непросредственно выводится на монитор, что медленно и происходит мерцание экрана. В Qt обязательная двойная буферизация, как что мерцания не будет.
moveTo и lineTo - естественный способ задания кривой. В итоге это сводится к аналогичным вызовам Microsoft API.
QPainterPath задает одну область, заливаемую одной кистью (хотя возможно, градиентной или пустой) и обводимой одним пером (хотя возможно, градиентным или пустым). Если нужно что-то выделить другим цветом, нужен второй QPainterPath.
QPainterPath следует рассматривать как черный ящик. Хотя можно получить точки moveTo и lineTo, лучше их хранить где-то в своём классе.

Выделение действительно, иногда ведёт себя не так, как хочется. В этом случае нужно писать своё выделение.
PM   Вверх
Glad
Дата 24.4.2014, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 16.8.2005

Репутация: нет
Всего: нет



Цитата(Amp @  23.4.2014,  15:13 Найти цитируемый пост)
Это все надо писать самому. К тому же нельзя изменить цвет или толщину какого-то отдельного учатка внутри path. Для Qt это один целый элемент, к которому применяется текущие настройки кистей и цвета.

А как это сделать ? Я просто не очень понимаю алгоритм действий. Т.е. как задать свой собственный алгоритм определения попадает ли точка в фигуру ? Я переопределил метод contains но при клике он даже не был вызван.. Странно
PM MAIL   Вверх
math64
Дата 24.4.2014, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Обычно в своем GraphicsItem нужно переопредить одновременно следующие методы:
Код

    QRectF boundingRect() const;
    QPainterPath shape() const;
    bool contains(const QPointF &point) const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);

и они должны работать согласованно
paint() рисует внутри shape(),
и соблюдаются соотнношения:
boundingRect() = shape().boundingRect()
contains() =  shape().contains()

т.о. для определения принадлежности точки может быть вызвано не contains(), а shape().contains()


PM   Вверх
Glad
  Дата 24.4.2014, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 16.8.2005

Репутация: нет
Всего: нет



Цитата(math64 @  24.4.2014,  15:01 Найти цитируемый пост)
Обычно в своем GraphicsItem нужно переопредить одновременно следующие методы:
Выделить всёкод C++
1:
2:
3:
4:
    
    QRectF boundingRect() const;
    QPainterPath shape() const;
    bool contains(const QPointF &point) const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);

и они должны работать согласованно
paint() рисует внутри shape(),
и соблюдаются соотнношения:
boundingRect() = shape().boundingRect()
contains() =  shape().contains()

т.о. для определения принадлежности точки может быть вызвано не contains(), а shape().contains()


Спасибо! Ясно примерно. Хотя я так посмотрел.. У QGraphicsItem есть метод shape. Получается что так или иначе возращается QPainterPath(кстати по значению, что тоже смутило учитывая частоту вызова данной функции). Т.е. с помощью shape() мы можем построить свой контур и Qt сожет определить попали ли мы в этот контур автоматически, я правильно понимаю ? 
Пока конечно не вдаюсь в детали, но с первого взгляда это кажется сложным.. Не проще было бы дать юзеру определять с помощью того же метода contains содержится ли точка в фигуре или нет ? smile 
PM MAIL   Вверх
math64
Дата 25.4.2014, 07:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



contains() для точки частная задача. по умочанию она вызывает shape().contains()
Если можно выполнить contains() быстрее, можно предложить другую реализацию.
shape() нужен для других задач, например фигуры выделение контуром, которое с помощью contains() не сделаешь.
shape() возвращает QPainterPath по значению, а не по ссылке, т.к. путь нельзя модиффицировать (если он хранится постоянно), или он может создаваться каждый раз при вызове, чтобы не тратить много памяти на его хранение.
Как бы то ни было, конструктор копирования выполняется быстро, т.к. данные хранятся в QPainterPathPrivate, а копия использует те же данные, что и оригинал (в QPainterPathPrivate есть счетчик использования) - так устроены многие классы Qt.
PM   Вверх
Glad
Дата 25.4.2014, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 16.8.2005

Репутация: нет
Всего: нет



А прикол хотите ? smile Я определил shape для своей дороги.. И вроде выделяется всё правильно.. Но.. Если из переопределенного мной  метода paint убрать рисование базовым методом QGraphicsPathItem::paint объект перестанет выделяться.. Хотя у меня подозрение, что он всё-таки выделяется, просто не рисует выделение.
PM MAIL   Вверх
math64
Дата 25.4.2014, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Цитата(Glad @  25.4.2014,  18:53 Найти цитируемый пост)
Хотя у меня подозрение, что он всё-таки выделяется, просто не рисует выделение

Именно так. при прорисовке нужно смотреть на параметр option
PM   Вверх
Glad
Дата 26.4.2014, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 16.8.2005

Репутация: нет
Всего: нет



math64, 
Спасибо за ответы!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0485 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.