Название: рисование мышкой
Отправлено: diva от Март 09, 2005, 14:28
Подскажите пожалуйста, как в qt можно рисовать с помощью мышки квадраты круги и т.д.
Название: рисование мышкой
Отправлено: Sergeich от Март 09, 2005, 16:13
Обрабатываешь мышиные события с помощью QWidget::mousePressEvent(), QWidget::mouseReleaseEvent(), и QWidget::mouseMoveEvent() и рисуешь QPainter'ом
Название: рисование мышкой
Отправлено: diva от Март 10, 2005, 10:42
Да я согласен. Но как именно рисовать QPainter. В общем-то я новичок и если можно то подкинте алгоритм.
Название: рисование мышкой
Отправлено: Sergeich от Март 10, 2005, 11:28
Смотря что рисовать. Если круги и квадраты, то где-то так : void SomeWidget::paintEvent( QPaintEvent* e ) { // рисуем два круга и квадрат QPainter p( this ); p.setPen( QPen( Qt::black ), 3 ); p.setBrush( QBrush( Qt::blue ) ); p.drawEllipse( 100, 150, 50, 50); p.setBrush( QBrush( Qt::red ) ); p.drawEllipse( 200, 450, 25, 25); p.setPen( QPen( Qt::black ), 1 ); p.drawRect( 200, 200, 40, 40 ); }
Вообщем читай доку по QPainter и посмотри кутешный икземпл scribble
Название: рисование мышкой
Отправлено: diva от Март 11, 2005, 09:25
Что-то вроде я делал. Только мне нужно реализовать что-то вроде Paint, чтобы фигуры задавались не статически, а рисовались от мыши. Начальные и конечные кординаты брались от мыши. Пример ответа я там не нашел. Пробывал сам но у меня при каждом движении мыши рисует новый елипс, а старый остается.
Название: рисование мышкой
Отправлено: Sergeich от Март 11, 2005, 12:04
Не понимаю в чем проблема... На mousePressEvent запоминаешь точку, на mouseMoveEvent() затираешь старый объект и рисуешь новый...
Название: рисование мышкой
Отправлено: diva от Март 14, 2005, 15:31
Я незнаю как это сделать. Пробывал пример scrible, но ничего не получилось. Жаль исходники забыл. Но когда я рисую новый объект(круг), то старый (который был до этого нарисован, и который мне нужен), затирается полосами. Может что-то я непонимаю. :(
Название: рисование мышкой
Отправлено: Zigmar от Март 14, 2005, 22:24
Полосы, потому что перерисовавть надо. Если ты нарсовал, скажем, квадрат, а потом чего-то поверх нарисовал/стер, или окно другое поверху прошло - будут "дырки" и картинку надо перерисовывать - она нигде не сохраняется. Вариантов несколько - например можно хранить все нарисованные фигуры и в paintEvent всех рисовать. Можно, если не важно что картинку будет затираться другими окнами или при ресайзе - рисовать XOR-ом пока "тянешь" мышкой - один раз она рисует, а второй раз (если наприсовать тоже самое) - стирает не изменив того что было до этого. А когда отпустил мышку - наримовать обычным способом (не XOR-ом). А вообще, скорее всего можно просто воспользоваться QCanvas'ом - тогда не надо заботиться о перерисовке. Просто создаешь и добавляешь фигуры, а он уже сам их будет рисовать.
Название: рисование мышкой
Отправлено: diva от Март 17, 2005, 12:19
В общем-то я взял готовый исходник scrible и немного переделывал под то что мне нужно. Я конечно очень плохо разбираюсь в Qt но хотелось знать получше. Вот и решил изучать по мере написания программ. Вот дошел до реализации гафики и напоролся на много непонятного. Я приведу коды, а вы, если сможете, то подскажите что там не то, и как сделать правильно. Не судите строго. scribble.h
/**************************************************************************** ** $Id: qt/scribble.h 3.1.2 edited Nov 8 10:35 $ ** ** Copyright ( C ) 1992-2000 Trolltech AS. All rights reserved. ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/
#ifndef SCRIBBLE_H #define SCRIBBLE_H
#include <qmainwindow.h> #include <qpen.h> #include <qpoint.h> #include <qpixmap.h> #include <qwidget.h> #include <qstring.h> #include <qpointarray.h>
class QMouseEvent; class QResizeEvent; class QPaintEvent; class QToolButton; class QSpinBox;
class Canvas : public QWidget { Q_OBJECT
public: Canvas( QWidget *parent = 0, const char *name = 0 );
void setPenColor( const QColor &c ) { pen.setColor( c ); } void setBrushColor( const QColor &c ) { brush.setColor( c ); }
void setPenWidth( int w ) { pen.setWidth( w ); }
QColor penColor() { return pen.color(); } QColor brushColor() { return brush.color(); }
int penWidth() { return pen.width(); }
void save( const QString &filename, const QString &format );
void clearScreen();
protected: void mousePressEvent( QMouseEvent *e ); void mouseReleaseEvent( QMouseEvent *e ); void mouseMoveEvent( QMouseEvent *e ); void resizeEvent( QResizeEvent *e ); void paintEvent( QPaintEvent *e );
QPen pen; QBrush brush; QPointArray polyline;
bool mousePressed;
QPixmap buffer;
};
class Scribble : public QMainWindow { Q_OBJECT
public: Scribble( QWidget *parent = 0, const char *name = 0 );
protected: Canvas* canvas;
QSpinBox *bPWidth; QSpinBox *wWidth; QToolButton *bPColor, *bBColor, *bSave, *bClear;
protected slots: void slotSave(); void slotPenColor(); void slotBrushColor(); void slotWidth( int ); // Start void slotwWidth(); // void slothWidth( int ); // End void slotClear();
};
#endif
/**************************************************************************** ** $Id: qt/scribble.cpp 3.1.2 edited Nov 8 10:35 $ ** ** Copyright ( C ) 1992-2000 Trolltech AS. All rights reserved. ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/
#include "scribble.h"
#include <qapplication.h> #include <qevent.h> #include <qpainter.h> #include <qtoolbar.h> #include <qtoolbutton.h> #include <qspinbox.h> #include <qtooltip.h> #include <qrect.h> #include <qpoint.h> #include <qcolordialog.h> #include <qfiledialog.h> #include <qcursor.h> #include <qimage.h> #include <qstrlist.h> #include <qpopupmenu.h> #include <qintdict.h> #include <qglobal.h>
const bool no_writing = FALSE;
int i, h, w;
int MyX, MyY;
Canvas::Canvas( QWidget *parent, const char *name ) : QWidget( parent, name, WStaticContents ), pen(Qt::red, Qt::DotLine), brush(Qt::green,Qt::CrossPattern), polyline(2), mousePressed( FALSE ), buffer( width(), height() ) {
if ((qApp->argc() > 0) && !buffer.load(qApp->argv()[1])) buffer.fill( colorGroup().base() ); setBackgroundMode( QWidget::PaletteBase ); #ifndef QT_NO_CURSOR setCursor( Qt::crossCursor ); #endif }
void Canvas::save( const QString &filename, const QString &format ) { if ( !no_writing ) buffer.save( filename, format.upper() ); }
void Canvas::clearScreen() { buffer.fill( colorGroup().base() ); repaint( FALSE ); }
void Canvas::mousePressEvent( QMouseEvent *e ) { mousePressed = TRUE; /*polyline[3] = polyline[2] = polyline[1] = polyline[0] = e->pos();*/ MyX= e->pos().x(); MyY= e->pos().y(); }
void Canvas::mouseReleaseEvent( QMouseEvent *) { mousePressed = FALSE;
}
void Canvas::mouseMoveEvent( QMouseEvent *e ) {
if ( mousePressed ) {
pen.setStyle(SolidLine); //pen.setCapStyle(FlatCap); //pen.setJoinStyle(RoundJoin); brush.setStyle(SolidPattern);
QPixmap tmp (buffer); QPainter painter/*(&tmp,this)*/; painter.begin(&tmp,this); painter.setPen(pen); painter.setBrush(brush); //painter.drawEllipse(e->pos().x()-(qRound(w/2)),e->pos().y()-(qRound(w/2)),w,w); painter.drawRect(MyX,MyY,e->pos().x()-MyX,e->pos().y()-MyY); painter.end();
//bitBlt( this,e->pos().x(),e->pos().y() , &buffer, e->pos().x(),e->pos().y() ); //bitBlt( this,e->pos().x()-w,e->pos().y()-w,&tmp,e->pos().x()-w,e->pos().y()-w); bitBlt( this,MyX,MyY,&tmp,MyX,MyY,e->pos().x()-MyX,e->pos().y()-MyY); } }
void Canvas::resizeEvent( QResizeEvent *e ) { QWidget::resizeEvent( e );
int w = width() > buffer.width() ? width() : buffer.width(); int h = height() > buffer.height() ? height() : buffer.height();
QPixmap tmp( buffer ); buffer.resize( w, h ); buffer.fill( colorGroup().base() ); bitBlt( &buffer, 0, 0, &tmp, 0, 0, tmp.width(), tmp.height() ); }
void Canvas::paintEvent( QPaintEvent *e ) { /* QWidget::paintEvent( e );
QMemArray<QRect> rects = e->region().rects(); for ( uint i = 0; i < rects.count(); i++ ) { QRect r = rects[(int)i]; bitBlt( this,e->pos().x(),e->pos().y(),&buffer,e->pos().x(),e->pos().y()); bitBlt( this, r.x(), r.y(), &buffer, r.x(), r.y(), r.width(), r.height() ); }*/ }
//------------------------------------------------------
Scribble::Scribble( QWidget *parent, const char *name ) : QMainWindow( parent, name ) { canvas = new Canvas( this ); setCentralWidget( canvas );
QToolBar *tools = new QToolBar( this );
bSave = new QToolButton( QPixmap(), "Save", "Save as PNG image", this, SLOT( slotSave() ), tools ); bSave->setText( "Save as..." );
tools->addSeparator();
bPColor = new QToolButton( QPixmap(), "Choose Pen Color", "Choose Pen Color", this, SLOT( slotPenColor() ), tools ); bPColor->setText( "PColor..." );
tools->addSeparator(); // Start bBColor = new QToolButton( QPixmap(), "Choose Brush Color", "Choose Brush Color", this, SLOT( slotBrushColor() ), tools ); bBColor->setText( "BColor..." ); // End tools->addSeparator();
bPWidth = new QSpinBox( 1, 20, 1, tools ); QToolTip::add( bPWidth, "Choose Pen Width" ); connect( bPWidth, SIGNAL( valueChanged( int ) ), this, SLOT( slotWidth(int) ) ); bPWidth->setValue( 3 ); tools->addSeparator(); // Start wWidth = new QSpinBox( 1, 100, 1, tools ); QToolTip::add( wWidth, "Choose Pen Width" ); connect( wWidth, SIGNAL( valueChanged( int ) ), this, SLOT( slotwWidth() ) ); wWidth->setValue(30); // End tools->addSeparator();
bClear = new QToolButton( QPixmap(), "Clear Screen", "Clear Screen", this, SLOT( slotClear() ), tools ); bClear->setText( "ClrScr" ); }
void Scribble::slotSave() { QPopupMenu *menu = new QPopupMenu( 0 ); QIntDict<QString> formats; formats.setAutoDelete( TRUE );
for ( unsigned int i = 0; i < QImageIO::outputFormats().count(); i++ ) { QString str = QString( QImageIO::outputFormats().at( i ) ); formats.insert( menu->insertItem( QString( "%1..." ).arg( str ) ), new QString( str ) ); }
menu->setMouseTracking( TRUE ); int id = menu->exec( bSave->mapToGlobal( QPoint( 0, bSave->height() + 1 ) ) );
if ( id != -1 ) { QString format = *formats[ id ];
QString filename = QFileDialog::getSaveFileName( QString::null, QString( "*.%1" ).arg( format.lower() ), this ); if ( !filename.isEmpty() ) canvas->save( filename, format ); }
delete menu; }
void Scribble::slotPenColor() { QColor c = QColorDialog::getColor( canvas->penColor(), this ); if ( c.isValid() ) canvas->setPenColor( c ); }
void Scribble::slotBrushColor() { QColor c = QColorDialog::getColor( canvas->brushColor(), this ); if ( c.isValid() ) canvas->setBrushColor( c ); }
void Scribble::slotWidth( int w ) { canvas->setPenWidth( w ); i=bPWidth->value(); }
// Start void Scribble::slotwWidth() { w=wWidth->value(); } // End
void Scribble::slotClear() { canvas->clearScreen(); }
В общем у меня рисует квадрат, но когда я его тяну назад то он оставляет след.
Название: рисование мышкой
Отправлено: Keiko от Март 17, 2005, 22:18
используй QPainter::setRasterOp ( RasterOp r ) с r == Qt::XorROP. Когда мышь отпускаешь - рисуешь уже статический квадрат нужным цветом. Например (если разберёшься) void SQ_GLWidget::mousePressEvent(QMouseEvent *e) { if(e->button() == Qt::RightButton) { stopAnimation(); setCursor(cZoomIn); pRect = new QPainter(this); pRect->setPen(QPen(white, 2)); pRect->setRasterOp(Qt::XorROP); lastRect = QRect(); xmoveold = e->x(); ymoveold = e->y(); inMouse = true; crossDrawn = false; } else e->accept(); }
void SQ_GLWidget::mouseMoveEvent(QMouseEvent *e) { if(!inMouse) { e->accept(); return; }
if(e->state() == Qt::RightButton) { int X, Y, Xmin, Ymin; xmove = e->x(); ymove = e->y();
X = QMAX(xmove, xmoveold); Y = QMAX(ymove, ymoveold); Xmin = QMIN(xmove, xmoveold); Ymin = QMIN(ymove, ymoveold);
QRect rect(Xmin, Ymin, X-Xmin, Y-Ymin);
QPoint lastC = lastRect.center(); pRect->drawRect(lastRect); if(crossDrawn) { pRect->drawLine(lastC.x(), lastC.y() - len, lastC.x(), lastC.y() + len); pRect->drawLine(lastC.x() - len, lastC.y(), lastC.x() + len, lastC.y()); }
crossDrawn = !(rect.width() < len*2 + 2 || rect.height() < len*2 + 2);
QPoint C = rect.center(); pRect->drawRect(rect);
if(crossDrawn) { pRect->drawLine(C.x(), C.y() - len, C.x(), C.y() + len); pRect->drawLine(C.x() - len, C.y(), C.x() + len, C.y()); }
lastRect = rect; } else e->accept(); }
void SQ_GLWidget::mouseReleaseEvent(QMouseEvent *e) { if(e->state() == Qt::RightButton) { setCursor(cusual);
QPoint lastC = lastRect.center(); QPoint O(width() / 2, height() / 2);
delete pRect;
updateGL();
if(lastRect.width() > 2 && lastRect.height() > 2) { bool lastReset = reset_mode; reset_mode = true; float X = MATRIX_X, Y = MATRIX_Y; matrix_move(O.x() - lastC.x(), lastC.y() - O.y()); reset_mode = lastReset; bool zoomed = zoomRect(lastRect);
if(!zoomed) { MATRIX_X = X; MATRIX_Y = Y; write_gl_matrix(); } }
updateGL();
if(!manualBlocked()) startAnimation(); } else e->accept();
inMouse = false; }
Этот пример рисует zoom box (извини, не знаю как по русски :) ) в текущем ваджете, геометрия прямоугольника меняется от точки нажатия до текущего положения мыши. Когда мышь отпускается - zoom box пропадает (в твоём случае надо будет нарисовать фигуру определённым цветом.)
|