Название: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 05, 2022, 13:29 Добрый день коллеги !
Есть необходимость создания класса нового устройства рисования аналогичного QWidget, QPrinter, ... ! Цель - написание класса который позволит грузить в него svg и на выходе формировать списки примитивов QPainterPath::ElementType::... для конвертации их в g-code ! Понимаю что это взаимодействие классов QPaint + QPaintEngine + QPaintDevice ! Но вопрос именно в нюансах взаимодействия и реализации ! У кого есть опыт написания таких классов ? Нужны консультации по ходу реализации ! С уважением, Юрий. ПС - уточню - решение задачи с помощью парсинга XML я знаю - но это это "не по феншую" Qt :) ! Хотелось бы реализовать именно через внутренний функционал Qt ! Тем более что он есть ... Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 05, 2022, 15:16 ни один класс из свг модуля не подходит? https://doc.qt.io/qt-5/qtsvg-module.html QSvgRenderer например.
Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 05, 2022, 15:57 Спасибо за ответ !
Интересны любые соображения по данной теме ! На сколько я понял из описания Paint System (https://doc.qt.io/qt-6/paintsystem.html) - класс методы которого можно перегрузить и тем самым можно получить примитивы рисования QPainterPath::ElementType::... это класс QPaintEngine ! Не совсем понятно как получить аналогичный результат от класса QSvgRenderer() ? Если не сложно - поясните пожалуйста ! На данный момент мое затруднение в том что мне не понятно как "связать" классы QPaint + QPaintEngine + QPaintDevice для решения этой задачи ! Вроде читаю доки но блин не понимаю !!! :) Ни одного вменяемого примера реализации пока найти не смог ! - как наследоваться и перегрузить методы QPaintEngine - понятно ! - ... остальное в процессе :) ... С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 05, 2022, 18:41 QSvgGenerator наследуется от QPaintDevice, тут уже ничего придумывать и не надо. если я правильно понимаю, достаточно унаследоваться от QSvgGenerator и перехватывать нужные методы. Либо наследоваться от QPaintDevice и поглядеть в исходники QSvgGenerator, чтобы сделать аналогично, но для вывода в нужный формат.
Цитировать This paint device represents a Scalable Vector Graphics (SVG) drawing. Like QPrinter, it is designed as a write-only device that generates output in a specific format. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 05, 2022, 19:39 Может быть оно конечно и так ...
Но поглядев внимательно header этого класса я не совсем понимаю что именно и как можно перегрузить в этом классе для того что бы решить мою задачу ?! Сам QSvgGenerator предназначен все таки для генерации svg файлов на основании отрисованых с помощью QPainter примитивов ! А моя задача как раз обратная - получение примитивов на выходе класса ! При том что на входе есть svg файл ! С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 05, 2022, 20:02 могу лишь посоветовать открыть исходники QPainter и изучить как оттуда извлекать примитивы (если такая возможность вообще есть)
Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 06, 2022, 12:26 Добрый день !
Спасибо за ответ ! И спасибо за совет ! Тут такое дело ! Я уже потратил какое то время в попытке проанализировать троицу классов и нашел возможность перегрузки методов ! По моему мнению делаются они в классе наследнике QPaintEngine ! QPainter же это класс рисовальщик (собственно и из названия оно логично следует :) ) ! На данный час мне не понятно как описать взаимодействие классов которые обеспечивают Paint System ?! Это и является моей проблемой и соответственно моим вопросом ! :) Вроде описание вижу - https://doc.qt.io/qt-6/paintsystem.html ! :) И желание реализовать имею ! :) Но видимо experience мягко говоря не достаточен !!! :) С уважением, Юрий. ПС Буду премного благодарен за высказывание любых мнений и соображений ! Ну а если кто то имеет такой опыт и может указать "путь истинный" готов отблагодарить ! :) Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 06, 2022, 16:22 Цитировать Custom Backends Support for a new backend can be implemented by deriving from the QPaintDevice class and reimplementing the virtual QPaintDevice::paintEngine() function to tell QPainter which paint engine should be used to draw on this particular device. To actually be able to draw on the device, this paint engine must be a custom paint engine created by deriving from the QPaintEngine class. Цитировать If one wants to use QPainter to draw to a different backend, one must subclass QPaintEngine and reimplement all its virtual functions. The QPaintEngine implementation is then made available by subclassing QPaintDevice and reimplementing the virtual function QPaintDevice::paintEngine(). судя по описанию, в наследнике QPaintDevice достаточно переопределить лишь один метод, а всю нужную логику написать в наследнике QPaintEngine. Далее при создании QPainter подавать ему своего наследника QPaintDevice. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 06, 2022, 16:43 Совершенно согласен с вашей точкой зрения ! :)
Таки да ! Я тоже так считаю ! В наследнике QPaintDevice переопределяем paintEngine() и создаем обьект наследника QPaintEngine (в котором в свою очередь преопределены виртуальные методы в которых мы и перехватываем примитивы рисования) ! Но как быть дальше что то я ... :) С уважением, Юрий. ПС Могу выложить проект набросков ввиде архива ! Если оно конечно нужно ? Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 06, 2022, 17:02 Да ! Очень похоже что вы правы !
Судя по описанию класса QPicture (https://doc.qt.io/qt-5/qpicture.html) а он наследуется так же от QPaintDevice ! Класс наследника QPaintDevice скармливается QPainter ! И QPainter отрисовывает нужную svg'шку на QPaintDevice ! Осталось это разумно описать кодом ! :) Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 06, 2022, 17:04 дальше загружаем свой свг в QSvgRenderer и отрисовываем на свой QPaintDevice через https://doc.qt.io/qt-5/qsvgrenderer.html#render
Цитировать Since the rendering is performed using QPainter, SVG drawings can be rendered on any subclass of QPaintDevice. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 07, 2022, 10:05 Добрый день !
Спасибо ! В общем идея понятна ! Буду пробовать реализовать ! По дальнейшему процессу или результату обязательно отпишусь ! С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 12, 2022, 12:24 Добрый день !
После недолгого копания получился вот такой вот набросок - https://gitlab.com/z34x/codemaker.git Что то конечно получилось ! Но вопросов поубавилось не значительно :) ! И так : 1 Понимаю что наследование должно быть примерно такое. 2 Понимаю что применение объектов классов наследников QPaintDevice, QPaintEngine и QPainter должно происходить так. 3 Не понимаю как задать линейные размеры наследнику QPaintDevice ! Логично бы было что бы именно наследник QPaintDevice имел бы виртуальные методы с помощью которых меняются параметры устройства на которое происходит вывод (линейные размеры, единицы измерения ...) ! Но понимаю что моя логика тут конфликтует с действительностью. :) 4. Не понимаю что нужно делать в методах begin() и end() при наследовании например классa QPaintDevice. :) Так и хочется сказать - запишите меня на курсы по Qt :))))) ! Ну или растолкуйте невежде ... Решения подобной задачки я к сожалению в сети не нашел, а научиться писать классы устройств очень хочется ! :) Ну и как следствие - у меня получается конвертировать один из svg файлов который есть в subдиректории /in и его сконвертированный образ в /out ! Он называется Петя.svg ! Но не получается конвертировать остальные ! Причина мне понятна в остальных есть тег g< \> ! Но как решить эту проблему не понятно ! :) Короче вопросов много ... С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 12, 2022, 14:31 наследовать QSvgRenderer особого смысла нет. остальное вроде верно, но я лишь по диагонали посмотрел.
2) иначе б Петю сконвертировать не получилось :) 3) думаю, надо такие методы добавлять самому. например, у QSvgGenerator можно контролировать size и resolution. 4) можно ничего не делать, зависит от личной необходимости что там за g< \> не знаю, в спецификациях свг не разбираюсь. Для теста можно взять Qt пример, который загружает свг (ну или самому такое написать) и проверить отобразит ли он эти картинки. Также глянуть в документации какую спецификацию свг поддерживает Qt и в какой добавлен этот g< \>. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 12, 2022, 16:33 По QSvgRenderer - согласен ! Конечно ! Это обертка для себя ! :)
2) иначе б Петю ... - ну да ! Это для меня тоже понятно. Так же как и то что Qt понимает не только тег - g (тег g служит для группировки фигур по смыслу, чтобы поддерживать прозрачную структуру документа. Группа элементов может быть использована повторно.), но и все остальные нюансы современного стандарта SVG ! 3) думаю, надо такие методы добавлять самому. например, у QSvgGenerator можно контролировать size и resolution. - ну да так и есть ! Но это у QSvgGenerator ! В моем случае в QSvgRenderer можно задать размер области рендеринга setViewBox() и соотношение сторон при отрисовке setAspectRatio() что тоже отлично ! Но где сделать корректировку например единиц изменения я пока не знаю. 4) можно ничего не делать, зависит от личной необходимости - спасибо за уточнение - в этом были сомнения ! Хотя из того что нашел в доках понял примерно так же ! что там за g< \> не знаю, в спецификациях свг не разбираюсь. Для теста можно взять Qt пример, который загружает свг - да, это косвенно я конечно проверил ! Более того в проекте я использую те же самые svg'шки для отрисовки их на QToolButton() ! Поэтому практически уверен что дело не в Qt ! Причина того что у меня не получается в отсутствии моего опыта в данном вопросе ! С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 17, 2022, 12:04 Добрый день !
И так ! :) Часть моих выходных была посвящена попытке решения моей головоломки ! :) В результате : - понятно что в SVG мешает моему коду конвертировать файлы - это transform="translate(... ...)" ! Файлы где нет трансформаций как раз и были тем успехом который у меня был с самого начала ! :) Но я абсолютно уверен что это как раз из за того что я некачественно использую методы классов Qt Paint System ! Так как при работе например с QImage те же самые файлы рисуются отлично ! Я еще более убедился что нужно искать компетентной помощи у специалистов которые работают с SVG и могут проконсультировать по методам классов Qt Paint System или разбираться в исходном коде. :))) С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 24, 2022, 10:27 Добрый день !
Кто может подсказать как в Qt определить точки пересечения линий при отрисовке SVG ? Есть ли какие то стандартные методы ? С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 24, 2022, 12:10 если у линий есть координаты начала и конца (т.е. это отрезки), то можно, например, через https://doc.qt.io/qt-5/qlinef.html#intersects
Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 24, 2022, 13:42 Спасибо за ответ !
Ну с линией - таки да ! Я это видел ! И даже приходилось пользовать ... Но в моей задачке не совсем линии : QPainterPath::ElementType::MoveToElement: - с этим все понятно. QPainterPath::ElementType::LineToElement: - с этим ну в общем то тоже. QPainterPath::ElementType::CurveToElement: - с этим нет !!! QPainterPath::ElementType::CurveToDataElement: - с этим нет !!! да и сама проблемка не совсем о пересечении двух линий ! Скорее мне нужно получить точки пересечения рисуемого в данный момент элемента (QRect) с ранее отрисоваными элементами на QPaintDevice ! Как то так ! С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 24, 2022, 14:27 наверное только свою логику писать. например, хранить массив QPolygonF чтоб вычислять их пересечения.
Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 24, 2022, 19:14 Ну да ! Сегодня пришел примерно к такому же выводу !!! :)
Только думаю что нужно проверять вновь создаваемый QPainterPath на пересечение с ранее созданными QPainterPath ! С помощью ::intersect(...), ::intersected(...), ::contains(...), ... ! Тут есть над чем подумать и поэкспериментировать ! :) С уважением, Юрий. ПС по результатам отпишусь позже Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 27, 2022, 15:04 Добрый день !
По ходу разбора Qt SVG появляется все больше нюансов и вопросов ! :) 1. Правильно ли я понимаю что получение текущего цвета которым отрисовываются фигуры и примитивы в методах QPaintEngine доступно через - QPaintEngine::painter()->pen().color(); ? 2. Где и как можно получить имя текущего слоя если SVG файл многослойный ? ,,, С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: kambala от Октябрь 27, 2022, 17:23 1. звучит логично. pen — это цвет контура (линий), цвет заливки — brush
Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Октябрь 27, 2022, 19:01 Ну да ! :)
Проверил в коде ! Вроде так и есть ! Где бы блин найти приличное описание ? Вроде и хелпа много и обсуждений, но как только касаешься чего то что не на поверхности лежит прям ступор ! :) С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Ноябрь 06, 2022, 13:55 Добрый день !
Некоторое время занимался другими вопросами ! Ну и конечно параллельно по немногу этой темой ! :) Сейчас понимаю что уперся в проблему работы с размерами svg ! Мои предположения о том что масштабирование происходит путем вызова QSvgRenderer::setViewBox(...) оказались не верными ! После копания в исходниках наследников QPaintDevice (QImage, QPrinter ...) понимаю что это устроенно не так прямолинейно ! Но вот реального понимания механизма пока нет ! Если есть соображения и советы - с удовольствием прислушаюсь ! С уважением, Юрий. Название: Re: Создание нового устройства рисования ... Отправлено: Юрий-В от Ноябрь 22, 2022, 16:56 Добрый день !
Кто может помочь с пониманием работы с QPaintDevice::metric(..) ? Все что написано в документации я уже конечно прочел и попробовал ! :) - QPaintDevice::PdmWidth: - ширина в единицах хранения в svg; (на сколько я понимаю в пикселах) (берем из QSvgRenderer::defaultDevice(..)) - QPaintDevice::PdmHeight: - высота аналогично - QPaintDevice::PdmWidthMM: - ширина в мм (берем из QSvgRenderer::viewBox(..)) - QPaintDevice::PdmHeightMM: - высота аналогично - QPaintDevice::PdmNumColors: - количество цветов для создаваемого устройства (константа из требований к устройству) - пусть будет например 16 - QPaintDevice::PdmDepth: - количество битовых плоскостей (по докам) - тут не понятно - это бит на цвет или что ??? - QPaintDevice::PdmDpiX: - dpi X логическая - тут мне не понятно !!! - QPaintDevice::PdmPhysicalDpiX: - dpi X физическая - аналогично !!! - QPaintDevice::PdmDpiY: - dpi Y логическая - аналогично !!! - QPaintDevice::PdmPhysicalDpiY: - dpi Y физическая - аналогично !!! - QPaintDevice::PdmDevicePixelRatio: - соотношение чего с чем ??? - QPaintDevice::PdmDevicePixelRatioScaled: - аналогично !!! Уверен что не понимаю идею которая заложена в управлении классом ! Если у кого то есть опыт работы с этим методом и соответственно с классом - буду очень признателен за любые подсказки ! С уважением, Юрий. ПС Понятно что можно написать свои костыли к данному классу и заставить его генерировать то что нужно ! Но хотелось бы именно разобраться в той логике которую закладывали разработчики. |