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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: рисование мышкой  (Прочитано 19291 раз)
diva
Гость
« : Март 09, 2005, 14:28 »

Подскажите пожалуйста, как в qt можно рисовать с помощью мышки квадраты круги и т.д.
Записан
Sergeich
Гость
« Ответ #1 : Март 09, 2005, 16:13 »

Обрабатываешь мышиные события с помощью QWidget::mousePressEvent(), QWidget::mouseReleaseEvent(), и QWidget::mouseMoveEvent() и рисуешь QPainter'ом
Записан
diva
Гость
« Ответ #2 : Март 10, 2005, 10:42 »

Да я согласен. Но как именно рисовать QPainter. В общем-то я новичок и если можно то подкинте алгоритм.
Записан
Sergeich
Гость
« Ответ #3 : Март 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
Гость
« Ответ #4 : Март 11, 2005, 09:25 »

Что-то вроде я делал. Только мне нужно реализовать что-то вроде Paint, чтобы фигуры задавались не статически, а рисовались от мыши. Начальные и конечные кординаты брались от мыши. Пример ответа я там не нашел. Пробывал сам но у меня при каждом движении мыши рисует новый елипс, а старый остается.
Записан
Sergeich
Гость
« Ответ #5 : Март 11, 2005, 12:04 »

Не понимаю в чем проблема... На mousePressEvent запоминаешь точку, на mouseMoveEvent() затираешь старый объект и рисуешь новый...
Записан
diva
Гость
« Ответ #6 : Март 14, 2005, 15:31 »

Я незнаю как это сделать. Пробывал пример scrible, но ничего не получилось. Жаль исходники забыл. Но когда я рисую новый объект(круг), то старый (который был до этого нарисован, и который мне нужен), затирается полосами. Может что-то я непонимаю. Грустный
Записан
Zigmar
Гость
« Ответ #7 : Март 14, 2005, 22:24 »

Полосы, потому что перерисовавть надо. Если ты нарсовал, скажем, квадрат, а потом чего-то поверх нарисовал/стер, или окно другое поверху прошло - будут "дырки" и картинку надо перерисовывать - она нигде не сохраняется. Вариантов несколько - например можно хранить все нарисованные фигуры и в paintEvent всех рисовать. Можно, если не важно что картинку будет затираться другими окнами или при ресайзе - рисовать XOR-ом пока "тянешь" мышкой - один раз она рисует, а второй раз (если наприсовать тоже самое) - стирает не изменив того что было до этого. А когда отпустил мышку - наримовать обычным способом (не XOR-ом). А вообще, скорее всего можно просто воспользоваться QCanvas'ом - тогда не надо заботиться о перерисовке. Просто создаешь и добавляешь фигуры, а он уже сам их будет рисовать.
Записан
diva
Гость
« Ответ #8 : Март 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
Гость
« Ответ #9 : Март 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 пропадает (в твоём случае надо будет нарисовать фигуру определённым цветом.)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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