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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: рисование карандашом на виджете  (Прочитано 8847 раз)
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« : Январь 03, 2009, 18:54 »

Как наиболее простым способом заставить рисовать как бы карандашом сверху фона (кот. из себф представляет простой рисунок) - рисование хочется производить мышкой?

Наверное правильнее создать свой виджет (или нет?)

Можно ли как то заюзать существующие - например выводить фон с помощью QLabel и только рисовать сверху перехватывая смобытия мышки?
Или правильнее использовать QGraphicsView - если да то как?
Записан
Dendy
Гость
« Ответ #1 : Январь 03, 2009, 19:07 »

Свой виджет, что хранит QImage и перехватывая события мыши дорисовывает в него QPainter'ом. Эту картирку рисует сам в paintEvent().
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #2 : Январь 03, 2009, 19:12 »

Да это как раз понятно - вопрос можно ли без создания своего виджета?
Записан
Dendy
Гость
« Ответ #3 : Январь 03, 2009, 19:20 »

Думаю можно, а толку? Классы должны писаться всегда, когда создаётся новая сущность. Даже если технически можно обойтись без создания оного.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #4 : Январь 03, 2009, 19:46 »

Мне нужно наиболее простое решение задачи у кот. четкое т.з. и новосозданный компонент (если его все же прийдется писать) больше никогда не будет использоваться. Поэтому и создавать его не хочется.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #5 : Январь 03, 2009, 20:00 »

Пока нашел такое решение:

void CMyForm::mouseMoveEvent ( QMouseEvent * event )
{
   QPixmap * pix = (QPixmap*)ui.lbClearImage->pixmap();
   QImage  image = pix->toImage();
   
   image.setPixel( event->pos(), 1 );
   
   
   ui.lbClearImage->setPixmap( QPixmap::fromImage( image ) );
};

На форме лежит QLabel (ui.lbClearImage) с картинкой - рисовать на нем получается - осталось толко как то правильно преобразовать координаты от мыши event->pos().
Записан
Dendy
Гость
« Ответ #6 : Январь 03, 2009, 20:10 »

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

Одна из главных ошибок начинающих программистов. Даже если класс будет использоваться всего в одном месте - его всё равно нужно писать. Для того чтобы функционал в коде не был смешан в кашу и легко понимался. Даже если новый класс будет содержать всего пару строчек кода. Дело вовсе не в количестве строк кода или точек инстанцирования - дело в том что это новая сущность. QLabel - это высокоуровневый готовый класс, предназначеный для других целей, хотя тоже может показывать картинку.

Мой совет - вам самому нужно писать paintEvent(). Желательно в собственном классе.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #7 : Январь 03, 2009, 20:27 »

1) Выходит что в QT нет готового класса -сущности для рисования на нем мышкой?
2) Перекрывая PainEvent - я могу как угодно разрисовать свой виджет - но события от мыши для QWidget ловятся в mouseEvent - как их правильно связать?
Записан
Dendy
Гость
« Ответ #8 : Январь 03, 2009, 20:39 »

1) Выходит что в QT нет готового класса -сущности для рисования на нем мышкой?

А также нет утилиты для чтения мыслей девелопера и генерации исходного кода из астрала. Во блин.

2) Перекрывая PainEvent - я могу как угодно разрисовать свой виджет - но события от мыши для QWidget ловятся в mouseEvent - как их правильно связать?

Вот видите, вы мыслите в верном направлении. События мыши должны быть энкапсулированы в тот же класс что и показывает картинку на экран.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #9 : Январь 03, 2009, 20:41 »

Запоминать позиции полученные в MouseEvent и вызывать update() - в котором по всем этим позициям пройдет прорисовка?
Записан
Dendy
Гость
« Ответ #10 : Январь 03, 2009, 21:03 »

Развлёкся, нарисовал код.

Код:
#include <QApplication>
#include <QPainter>
#include <QImage>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QWidget>


class Pa : public QWidget
{
public:
Pa()
{
pixmap_ = QPixmap( 4096, 4096 );
pixmap_.fill( 0xffffffff );
pen_ = QPen( QBrush( Qt::black ), 5.0f );
}

protected:
void mousePressEvent( QMouseEvent * e )
{
if ( e->button() == Qt::LeftButton )
{
QPainter p( &pixmap_ );
p.setPen( pen_ );
p.drawPoint( e->pos() );
p.end();

lastPoint_ = e->pos();

update();
}
}

void mouseMoveEvent( QMouseEvent * e )
{
if ( e->buttons() & Qt::LeftButton )
{
QPainter p( &pixmap_ );
p.setPen( pen_ );
p.drawLine( lastPoint_, e->pos() );
p.end();

lastPoint_ = e->pos();

update();
}
}

void paintEvent( QPaintEvent * )
{
QPainter p( this );
p.setCompositionMode( QPainter::CompositionMode_Source );
p.drawPixmap( QPoint(), pixmap_ );
}

private:
QPen pen_;
QPixmap pixmap_;
QPoint lastPoint_;
};




int main( int argc, char ** argv )
{
QApplication app( argc, argv );

Pa pa;
pa.show();

return app.exec();
}
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #11 : Январь 04, 2009, 01:02 »

Спасибо!
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #12 : Январь 04, 2009, 01:18 »

Еще маленький вопросик - при выводе фонового изображения как сделать чтобы была возможность изменения внутренней картинки под размеры виджета. То что достигалось свойством scaledContents в QLabel?
Записан
Dendy
Гость
« Ответ #13 : Январь 04, 2009, 01:31 »

Фоновое - это на котором мы рисуем? Оно растровое, размер менять нельзя. Если про картинку на фоне - лучше один раз растянуть и закешировать через QPixmap::scaled() внутри resizeEvent(), а потом подкладывать под рисуемую картинку. Или тайлить оригинал. Главное понять суть задачи.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #14 : Январь 04, 2009, 04:37 »

Ok! Спасибо!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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