C++/Qt/QGraphicsItem
Interact with QGraphicsItem
Foundations of Qt Development\Chapter07\graphicsview\interaction\handleitem.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "handleitem.h"
#include <QPainter>
#include <QPointF>
HandleItem::HandleItem( QGraphicsItem *item, QGraphicsScene *scene, QColor color, HandleItem::HandleRole role, QList<HandleItem*> handles ) : QGraphicsItem( 0, scene )
{
m_role = role;
m_color = color;
m_item = item;
m_handles = handles;
m_pressed = false;
setZValue( 100 );
setFlag( ItemIsMovable );
}
void HandleItem::paint( QPainter *paint, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
paint->setPen( m_color );
paint->setBrush( m_color );
QRectF rect = boundingRect();
QVector<QPointF> points;
switch( m_role )
{
case CenterHandle:
paint->drawEllipse( rect );
break;
case RightHandle:
points << rect.center()+QPointF(3,0) << rect.center()+QPointF(-3,-5) << rect.center()+QPointF(-3,5);
paint->drawConvexPolygon( QPolygonF(points) );
break;
case TopHandle:
points << rect.center()+QPointF(0,-3) << rect.center()+QPointF(-5,3) << rect.center()+QPointF(5,3);
paint->drawConvexPolygon( QPolygonF(points) );
break;
}
}
QRectF HandleItem::boundingRect() const
{
QPointF point = m_item->boundingRect().center();
switch( m_role )
{
case CenterHandle:
return QRectF( point-QPointF(5, 5), QSize( 10, 10 ) );
case RightHandle:
point.setX( m_item->boundingRect().right() );
return QRectF( point-QPointF(3, 5), QSize( 6, 10 ) );
case TopHandle:
point.setY( m_item->boundingRect().top() );
return QRectF( point-QPointF(5, 3), QSize( 10, 6 ) );
}
return QRectF();
}
QVariant HandleItem::itemChange( GraphicsItemChange change, const QVariant &data )
{
if( change == ItemPositionChange && m_pressed )
{
QPointF movement = data.toPoint() - pos();
QPointF center = m_item->boundingRect().center();
switch( m_role )
{
case CenterHandle:
m_item->moveBy( movement.x(), movement.y() );
foreach( HandleItem *handle, m_handles )
handle->translate( movement.x(), movement.y() );
break;
case RightHandle:
if( 2*movement.x() + m_item->sceneBoundingRect().width() <= 5 )
return QGraphicsItem::itemChange( change, pos() );
movement.setY( 0 );
m_item->translate( center.x(), center.y() );
m_item->scale( 1.0+2.0*movement.x()/(m_item->sceneBoundingRect().width()), 1 );
m_item->translate( -center.x(), -center.y() );
break;
case TopHandle:
if( -2*movement.y() + m_item->sceneBoundingRect().height() <= 5 )
return QGraphicsItem::itemChange( change, pos() );
movement.setX( 0 );
m_item->translate( center.x(), center.y() );
m_item->scale( 1, 1.0-2.0*movement.y()/(m_item->sceneBoundingRect().height()) );
m_item->translate( -center.x(), -center.y() );
break;
}
return QGraphicsItem::itemChange( change, pos()+movement );
}
return QGraphicsItem::itemChange( change, data );
}
void HandleItem::mousePressEvent( QGraphicsSceneMouseEvent *event )
{
m_pressed = true;
QGraphicsItem::mousePressEvent( event );
}
void HandleItem::mouseReleaseEvent( QGraphicsSceneMouseEvent *event )
{
m_pressed = false;
QGraphicsItem::mouseReleaseEvent( event );
}
Foundations of Qt Development\Chapter07\graphicsview\interaction\handleitem.h
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef HANDLEITEM_H
#define HANDLEITEM_H
#include <QGraphicsItem>
class HandleItem;
class HandleItem : public QGraphicsItem
{
public:
enum HandleRole
{
CenterHandle,
RightHandle,
TopHandle
};
HandleItem( QGraphicsItem *item, QGraphicsScene *scene, QColor color, HandleRole role = CenterHandle, QList<HandleItem*> handles = QList<HandleItem*>() );
void paint( QPainter *paint, const QStyleOptionGraphicsItem *option, QWidget *widget );
QRectF boundingRect() const;
protected:
void mousePressEvent( QGraphicsSceneMouseEvent *event );
void mouseReleaseEvent( QGraphicsSceneMouseEvent *event );
QVariant itemChange( GraphicsItemChange change, const QVariant &data );
private:
QGraphicsItem *m_item;
HandleRole m_role;
QColor m_color;
QList<HandleItem*> m_handles;
bool m_pressed;
};
#endif // HANDLEITEM_H
Foundations of Qt Development\Chapter07\graphicsview\interaction\main.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsEllipseItem>
#include "handleitem.h"
int main( int argc, char **argv )
{
QApplication app( argc, argv );
QGraphicsScene scene( 0, 0, 200, 200 );
QGraphicsRectItem *rectItem = new QGraphicsRectItem( QRect( 10, 10, 50, 100 ), 0, &scene );
QGraphicsEllipseItem *elItem = new QGraphicsEllipseItem( QRect( 80, 40, 100, 80 ), 0, &scene );
HandleItem *trh = new HandleItem( rectItem, &scene, Qt::red, HandleItem::TopHandle );
HandleItem *rrh = new HandleItem( rectItem, &scene, Qt::red, HandleItem::RightHandle );
HandleItem *crh = new HandleItem( rectItem, &scene, Qt::red, HandleItem::CenterHandle, QList<HandleItem*>() << trh << rrh );
HandleItem *teh = new HandleItem( elItem, &scene, Qt::green, HandleItem::TopHandle );
HandleItem *reh = new HandleItem( elItem, &scene, Qt::green, HandleItem::RightHandle );
HandleItem *ceh = new HandleItem( elItem, &scene, Qt::green, HandleItem::CenterHandle, QList<HandleItem*>() << teh << reh );
QGraphicsView view;
view.setScene( &scene );
view.show();
int res = app.exec();
delete crh;
delete trh;
delete rrh;
delete ceh;
delete teh;
delete reh;
return res;
}
Translate and scale QGraphicsItem
Foundations of Qt Development\Chapter07\graphicsview\transformations\main.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
QGraphicsItem *createItem( int x, QGraphicsScene *scene )
{
QGraphicsRectItem *rectItem = new QGraphicsRectItem( QRect( x+40, 40, 120, 120 ), 0, scene );
rectItem->setPen( QPen(Qt::black) );
rectItem->setBrush( Qt::gray );
QGraphicsRectItem *innerRectItem = new QGraphicsRectItem( QRect( x+50, 50, 45, 100 ), rectItem, scene );
innerRectItem->setPen( QPen(Qt::black) );
innerRectItem->setBrush( Qt::white );
QGraphicsEllipseItem *ellipseItem = new QGraphicsEllipseItem( QRect( x+105, 50, 45, 100 ), rectItem, scene );
ellipseItem->setPen( QPen(Qt::black) );
ellipseItem->setBrush( Qt::white );
return rectItem;
}
int main( int argc, char **argv )
{
QApplication app( argc, argv );
QGraphicsScene scene( QRect( 0, 00, 1000, 200 ) );
QGraphicsItem *item1 = createItem( 0, &scene );
QGraphicsItem *item2 = createItem( 200, &scene );
item2->translate( 300, 100 );
item2->rotate( 30 );
item2->translate( -300, -100 );
QGraphicsItem *item3 = createItem( 400, &scene );
item3->translate( 500, 100 );
item3->scale( 0.5, 0.7 );
item3->translate( -500, -100 );
QGraphicsItem *item4 = createItem( 600, &scene );
item4->translate( 700, 100 );
item4->shear( 0.1, 0.3 );
item4->translate( -700, -100 );
QGraphicsItem *item5 = createItem( 800, &scene );
item5->translate( 900, 100 );
item5->scale( 0.5, 0.7 );
item5->rotate( 30 );
item5->shear( 0.1, 0.3 );
item5->translate( -900, -100 );
QGraphicsView view;
view.setScene( &scene );
view.show();
return app.exec();
}