C++/Qt/QGraphicsItem

Материал из C\C++ эксперт
Перейти к: навигация, поиск

Interact with QGraphicsItem

<source lang="cpp">

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.
*
*/
  1. include "handleitem.h"
  2. include <QPainter>
  3. 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.
*
*/
  1. ifndef HANDLEITEM_H
  2. define HANDLEITEM_H
  3. 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;

};

  1. 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.
*
*/
  1. include <QApplication>
  2. include <QGraphicsScene>
  3. include <QGraphicsView>
  4. include <QGraphicsRectItem>
  5. include <QGraphicsEllipseItem>
  6. 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;

}


 </source>


Translate and scale QGraphicsItem

<source lang="cpp">

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.
*
*/
  1. include <QApplication>
  2. include <QGraphicsScene>
  3. include <QGraphicsView>
  4. 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();

}


 </source>