Название: Как рисовать не в paintEvent? Отправлено: marty от Июль 15, 2009, 17:14 Здравствуйте!
Собственно сабж, и возможнро ли это? Хочу рисовать (дорисовывать) изображение/его части, реагируя на действия пользователя - мышь, клавиатура, при этом не хотелось бы самому заводить QPixmap, в который будет производится отрисовка, и который будет копироваться в widget по paintEvent'у. Хочу так: 1) Создаем Qpixmap размером с виджет. 2) копируем в него изображение виджета (или только его части), планируется использовать hint о том, какая область будет обновляться 3) Рисуем на QPixmap'е 4) Копируем QPixmap или его часть на виджет. Не пойму, как реализовать пп 2, 4? Нашел вроде метод grabWidget, но как я понял, он вызывает событие paintEvent для виджета, чего как раз хочется избежать. Название: Re: Как рисовать не в paintEvent? Отправлено: f-r-o-s-t от Июль 15, 2009, 17:31 Мало понятно чего ты хочешь, подробней можно зачем оно тебе
как рисовать первое что нашел в Assistent это Plug & Paint Example Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 15, 2009, 18:01 Я хочу модифицировать изображение на виджете по различным событиям - так, пример, на котором я пытаюсь добиться нужного мне поведения, по движению мышки печатает в углу ее координаты.
Что я не хочу - не хочу заводить pixmap, на котором все будет рисоваться, для последующей переброски на экран по paintEvent (так сделано в Plug & Paint); не хочу запоминать данные и потом учитывать при перерисовке по paintEvent. Backbuffer pixmap я не хочу заводить - тогда для каждого класса виджета, который хочет рисовать не только по paintEvent, я должен наследоваться не от QWidget, а от моего класса, в котором этот бэкбуфер реализован. Запоминать данные и потом делать update - перерисовка виджетов может быть длительной, и поэтому не хочется все перерисовывать. В принципе, если ничего другого не остается, то наверно так и сделаю. Тогда вопрос возникает, по каким событиям следует изменять размеры беэкбуфера? И второй возникающий вопрос - QPainter (или QWidget) вроде реализует двойную буфферизацию, если я сам буду буфер использовать, как отключить стандартную? Название: Re: Как рисовать не в paintEvent? Отправлено: f-r-o-s-t от Июль 15, 2009, 18:15 А какой нибудь пример кроме мышки, подробнее что должно быть в конце.
отключить буферезацию QWidget::setAttribute(Qt::WA_PaintOnScreen). Название: Re: Как рисовать не в paintEvent? Отправлено: lit-uriy от Июль 15, 2009, 18:44 marty может проще рисовать повех виджета, как здесь (http://www.crossplatform.ru/node/887), задачка изначальная была другая, но на основе неё можно сделать.
Название: Re: Как рисовать не в paintEvent? Отправлено: lit-uriy от Июль 15, 2009, 18:53 Вот ещё: Рисование_поверх_дочерних_виджетов (http://wiki.crossplatform.ru/index.php/Рисование поверх дочерних виджетов)
Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 15, 2009, 20:31 А какой нибудь пример кроме мышки, подробнее что должно быть в конце. отключить буферезацию QWidget::setAttribute(Qt::WA_PaintOnScreen). Ну с мышкой это тривиальный пример, а так - у меня приходят данные, скажем, по таймеру, по их приходу надо подправить картинку, не перерисовывая целиком, потому что больно долго будет. Также данные куда-то складываются, и когда надо все перерисовать, то они тоже используются. Написал такой класс: Код: template <typename T> Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 15, 2009, 20:38 Что-то редактор сообщений стало колбасить, не смог дописать
Код: // испорльзовать так Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 15, 2009, 20:43 А вообще, что-то Qt не такая уж хорошая, раз для такого простого действия надо так извращаться.
Название: Re: Как рисовать не в paintEvent? Отправлено: Rcus от Июль 15, 2009, 21:14 Точно, не бери Qt, жизнь себе поломаешь! ©
Такие заявления мне кажутся забавными, особенно на фоне серьезных обсуждений багов и недостатков архитектуры Qt :) Название: Re: Как рисовать не в paintEvent? Отправлено: lit-uriy от Июль 15, 2009, 21:27 >>Точно, не бери Qt, жизнь себе поломаешь! ©
Плюс милиён, говно этот Qt, надо на Визуал Басике, тем более, что там уже всё за тебя сделано. Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 16, 2009, 01:32 Точно, не бери Qt, жизнь себе поломаешь! © Что в этом заявлении кажется вам забавным? По-моему, данное ограничение по рисованию только во время paintEvent довольно большой недостаток, которого нет у WinAPI (и его оберток) и у wxWidgets.Такие заявления мне кажутся забавными, особенно на фоне серьезных обсуждений багов и недостатков архитектуры Qt :) Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 16, 2009, 01:35 >>Точно, не бери Qt, жизнь себе поломаешь! © Я бы с удовольствием, но надо на плюсах, да так, чтоб работало с WTL, wxWidgets да с Qt. С последним постоянно какой-то гемморой возникает, в отличии от первых двух библиотек.Плюс милиён, говно этот Qt, надо на Визуал Басике, тем более, что там уже всё за тебя сделано. Вы бы лучше приведенный код попинали, вместо ёрничания. Название: Re: Как рисовать не в paintEvent? Отправлено: lit-uriy от Июль 16, 2009, 01:42 Продолжать сравнение Qt лучше здесь (http://www.prog.org.ru/index.php?topic=9980)
Название: Re: Как рисовать не в paintEvent? Отправлено: lit-uriy от Июль 16, 2009, 01:44 >>Вы бы лучше приведенный код попинали, вместо ёрничания.
ну я тебе ссылки давал, во втрой ссылке как раз расматривается вопрос рисования не в paintEvent Название: Re: Как рисовать не в paintEvent? Отправлено: lit-uriy от Июль 16, 2009, 01:48 Цитировать по их приходу надо подправить картинку, не перерисовывая целиком, потому что больно долго будет. Также данные куда-то складываются, и когда надо все перерисовать, то они тоже используются. подобная ситуация возникает например при построении графика. Есть такая библиотека Qwt, можно наверняка глянуть её исходники.Я не замечал существенных тормозов на динамически обновляемых графиках в их примерах. Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 16, 2009, 01:55 >>Вы бы лучше приведенный код попинали, вместо ёрничания. За ссылки спасибо, правда это не совсем то, что нужно. То, что нужно, пришлось самому написать ;)ну я тебе ссылки давал, во втрой ссылке как раз расматривается вопрос рисования не в paintEvent Название: Re: Как рисовать не в paintEvent? Отправлено: BRE от Июль 16, 2009, 07:28 По-моему, данное ограничение по рисованию только во время paintEvent довольно большой недостаток, которого нет у WinAPI (и его оберток) и у wxWidgets. Рисовать на большинстве PaintDevice можно в любой момент, а вот рисовать на виджете можно только в paintEvent. Кстати как и в WinAPI и у wxWidgets (если мне память не изменяет). :)Я бы с удовольствием, но надо на плюсах, да так, чтоб работало с WTL, wxWidgets да с Qt. С последним постоянно какой-то гемморой возникает, в отличии от первых двух библиотек. В свете последних обсуждений, вырисовывается закон:Чем меньше человек знаком с Qt, тем больше он находит в ней несуществующих проблем. ;) Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 16, 2009, 10:45 По-моему, данное ограничение по рисованию только во время paintEvent довольно большой недостаток, которого нет у WinAPI (и его оберток) и у wxWidgets. Рисовать на большинстве PaintDevice можно в любой момент, а вот рисовать на виджете можно только в paintEvent. Кстати как и в WinAPI и у wxWidgets (если мне память не изменяет). :)С wxWidget по этому вопросу еще не разбирался, а в винде можно рисовать в любой момент. Есть только небольшое отличие - контекс HDC надо получать через BeginPaint (в обработчике WM_PAINT) или GetDC в остальных случаях. Название: Re: Как рисовать не в paintEvent? Отправлено: Авварон от Июль 16, 2009, 10:54 контекст устройства это вообще ппц... перегрузка пейнт эвента гораздо проще и адекватнее выглядит
Название: Re: Как рисовать не в paintEvent? Отправлено: marty от Июль 16, 2009, 13:14 контекст устройства это вообще ппц... перегрузка пейнт эвента гораздо проще и адекватнее выглядит А чего тут ппц? В paintEvent'е все равно используется контекст рисования, а как он называется, HDC, wxDC или QPainter, это по-моему не принципиально.Название: Re: Как рисовать не в paintEvent? Отправлено: Авварон от Июль 16, 2009, 13:28 эти классы имеют _разный_ смысл. контекст устройства - непонятная примочка, нафиг откуда мне взявшаяся. qpainter - класс-рисовальщик. А всякие bitblt это вообще вынос мозга...
Название: Re: Как рисовать не в paintEvent? Отправлено: break от Июль 16, 2009, 22:27 Прочитал тему с самого начала!
Не пойму одного почему автор не хочет рисовать в PaintEvent - даже если предположить что в Qt с этим проблемы - зачем не использовать то подо что в Qt все рисования и затачивались. Кроме того контекст QPainter - сильно от личается от других контекстов- он имеет кучу доп. возможностей - например трансформации(scale, rotate и др.). Название: Re: Как рисовать не в paintEvent? Отправлено: fuCtor от Июль 18, 2009, 21:24 Заходя на форум хотел создать почти такой же топик.
Автора топика очень даже понимаю. самого интересует вопрос как бы ускорить вывод порядка тысячи полигонов с переключением стилей и тд. По замерам на отрисовку окна 1024 на 768 на котором помещалось порядка пары тысяч полигонов уходило порядка секунды. Отрисовку выполнял в буфер а только потом вывод буфера на бэкграунд GraphicsView. Скорость явна маленькая и неприемлимая. При том что под WinAPI удалось точно такой же код разогнать до 300мс. Вознивает вопрос. Что не так делаю и куда копать чтоб ускорить отрисовку. Буфер используется для частичной перерисовки при смещении., путем дорисовки необходимого. Название: Re: Как рисовать не в paintEvent? Отправлено: ufna от Июль 18, 2009, 21:28 вопрос - а стили и т.п., да и сами полигоны на поле у тебя динамичные или статичные?
Название: Re: Как рисовать не в paintEvent? Отправлено: fuCtor от Июль 18, 2009, 21:37 статичны и хранятся в дереве (полигоны). Стили тоже статичны. Если загрузить ВСЕ полигоны в виде GraphicsItem то это cъедает не мало памяти. Если фрагментами, то нарушается порядок следования (z-order). Судя по профайлеру то 80% времени съедает вывод именно полигонов, а не смена стиля рисования.
Название: Re: Как рисовать не в paintEvent? Отправлено: ufna от Июль 18, 2009, 21:48 а можно сам код отрисовки глянуть?
Название: Re: Как рисовать не в paintEvent? Отправлено: fuCtor от Июль 18, 2009, 21:56 Сейчас нет под рукой кода. Там просто хитрая система накручина с различными абстракциями и тд ). Собственно сами данные это картография.
а сама отрисовки сводится к: - вывод обычных полигонов + плюс накопление для отложенного вывода при определенных условиях - обработка списка отложенных полигонов - вывод их Название: Re: Как рисовать не в paintEvent? Отправлено: ufna от Июль 19, 2009, 08:57 Просто любой рендеринг - это оптимизация. В данном случае я бы вообще выводил не на GVC (по-моему излишне, если все и так в буфер только пишется). И тут нужно смотреть флаги с которыми ты рисуешь картинку, как ее рисуешь, что еще важнее, потому как оптимизация вывода - штука, на которой все игрушки работают черт знает сколько лет уже :)
если картография, то наверняка у тебя нет каждый раз изменения стилей, вывод - пока не сменили стиль, перерисовывать не нужно. Можно разбить на куски, которые только будем перерисовывать, если возможно. Порядок z-следования - нужно считать отдельно заранее (раз он должен сохраниться). И т.д., и т.п. Потому и хочу посмотреть, т.к. код сказал бы куда большее :) Название: Re: Как рисовать не в paintEvent? Отправлено: fuCtor от Июль 19, 2009, 12:36 Полученный буфер потом выводится на QGV и поверх него еще элементы интерфейса рисуются (QGI).
Оптимизировал алгоритм, стало все очень даже прилично ) Осталось с надписями разобраться, раза в 3 4 просаживают. Для дополнительной оптимизации вобще думаю переписать paintEvent у QGV (взять его родной и убрать оттуда буфер фона, заменив его на свой). А код в итоге не разрешили показывать :( мол коммерческая тайна... Название: Re: Как рисовать не в paintEvent? Отправлено: ufna от Июль 19, 2009, 15:14 вот видишь :)
с текстом можно буферизировать, т.е. если текст изменился - перерисовывать, а статичный текст рендерить в пиксмап и рисовать при перерисовке именно его. И т.д., и т.п. |