Russian Qt Forum

Qt => Общие вопросы => Тема начата: ecspertiza от Март 30, 2012, 08:38



Название: QPainter отмена(Ctrl + Z)
Отправлено: ecspertiza от Март 30, 2012, 08:38
Всем, доброе утро. Есть софтина, местами похожая на Paint, ну то есть предоставляет пользователю возможность рисования. Что бы не возникало проблем с потоками и рисовать можно было бы не только в paintEvent в качестве поверхности для рисования используется QImage.

Код:
QImage img;
QPainter p(&img);

Возникла необходимость дать пользователю возможность отменять действия по нажатию Ctrl + Z, самое банальное что я придумал, это перед началом нового рисования, записывать текущий QImage в QList ,а при отмене перерисовывать последний QImage. Это работает, и  работает достаточно неплохо. Есть одно но, слишком много отъедает оперативной памяти. Ну например кликах при 200, запросто может съесть 700метров. Возникает вопрос, а как можно еще реализовать данный механизм или можно записывать что то другое, что по размеру меньше чем QImage?


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: Bepec от Март 30, 2012, 08:46
Сохранять последние 30 действий?
Сохранять Image в файлы?


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: ecspertiza от Март 30, 2012, 08:59
про 30ть действий думал уже, был запасным вариантом ))) С файлами наверное долго будет работать.


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: Bepec от Март 30, 2012, 09:11
Есть конечно извращенский вариант...

Сделать сериализацию действий пользователя в виде вектора действий. И соответственно необходимо написать десериализатор.


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: BRE от Март 30, 2012, 09:11
А ты картинки сжимай в памяти и храни сжатые. Как правило они очень хорошо жмутся.


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: ecspertiza от Март 30, 2012, 09:22
BRE, это как то так

псевдокод, на коленке пишу

Код:
QByteArray data;
QBuffer buff(data);
QImage img;
img.save(&buff,"PNG");
buff.close();

QByteArray data = qCompress(data, 7);

а последний байт аррей пишем в лист, для отката.


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: GreatSnake от Март 30, 2012, 09:36
А чем не устроил QGraphicsView?


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: Авварон от Март 30, 2012, 09:38
А ку пикча не для этого ли сделана?


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: ecspertiza от Март 30, 2012, 09:48
про QGraphicsView чет даже не подумал, насколько на нем будет быстрее отрисовка, и есть ли ф-йии отмены? ну то есть насколько будет целесообразно переписать под него?

QPicture, наверное сделан для этого, но пока не вижу разницы, между записью QImage в QByteArray и в список, или тоже самое делать с QPicture.


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: BRE от Март 30, 2012, 09:51
BRE, это как то так

псевдокод, на коленке пишу
Не обязательно сохранять в буфер (хотя и этого может оказаться достаточным), ты можешь получить указатель на распакованные данные и их длину для qCompress:
const uchar * QImage::constBits () const
int QImage::byteCount () const


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: ecspertiza от Март 30, 2012, 09:54
попробовал с QCompress разница есть, теперь отъедает где то 300 метров :) 


Название: Re: QPainter отмена(Ctrl + Z)
Отправлено: GreatSnake от Март 30, 2012, 10:05
про QGraphicsView чет даже не подумал, насколько на нем будет быстрее отрисовка, и есть ли ф-йии отмены? ну то есть насколько будет целесообразно переписать под него?
Скорость, может даже будет быстрее, т.к. работать придётся с векторными примитивами, а не с растром. Да и по памяти будет громадный выигрыш. К тому же там уже есть возможность выделения и многое другое. Кстати, как ты будешь, если понадобится, масштабировать растр? Ведь будут потери?
Undo/redo там нет, но слепить очередь из QGraphicsItem элементарно.