C++/Qt/Draw Shape

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

Draw line

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the documentation of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.0 as published by the Free Software
    • Foundation and appearing in the file LICENSE.GPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. include <QtGui>

class MyWidget : public QWidget { public:

   MyWidget();

protected:

   void paintEvent(QPaintEvent *);

}; MyWidget::MyWidget() {

   QPalette palette(MyWidget::palette());
   palette.setColor(backgroundRole(), Qt::white);
   setPalette(palette);

} void MyWidget::paintEvent(QPaintEvent *) {

   QPainter painter(this);
   painter.setRenderHint(QPainter::Antialiasing);
   painter.setPen(Qt::darkGreen);
   painter.drawRect(1, 2, 6, 4);
   painter.setPen(Qt::darkGray);
   painter.drawLine(2, 8, 6, 2);

} int main(int argc, char *argv[]) {

   QApplication app(argc, argv);
   MyWidget widget;
   widget.show();
   return app.exec();

}


 </source>


Draw lines

<source lang="cpp">

Foundations of Qt Development\Chapter07\drawlines\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 <QPixmap>
  3. include <QPainter>

int main( int argc, char **argv ) {

 QApplication app( argc, argv );
 QPixmap pixmap( 200, 100 );
 pixmap.fill( Qt::white );
 QPainter painter( &pixmap );
 painter.setPen( Qt::black );
 
 QVector<QPoint> polyPoints;
 polyPoints << QPoint( 60, 10 ) << QPoint( 80, 90 ) << QPoint( 75, 10 ) << QPoint( 110, 90 );
 QVector<QPoint> linePoints;
 foreach( QPoint point, polyPoints )
   linePoints << point + QPoint( 80, 0 );
 
 painter.drawLine( QPoint( 10, 10 ), QPoint( 30, 90 ) );
 painter.drawPolyline( polyPoints );
 painter.drawLines( linePoints );
 pixmap.save( "drawlines.png" );
 return 0;

}


 </source>


Draw polylines

<source lang="cpp"> Foundations of Qt Development\Chapter07\drawlines\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 <QPixmap>
  3. include <QPainter>

int main( int argc, char **argv ) {

 QApplication app( argc, argv );
 QPixmap pixmap( 200, 100 );
 pixmap.fill( Qt::white );
 QPainter painter( &pixmap );
 painter.setPen( Qt::black );
 
 QVector<QPoint> polyPoints;
 polyPoints << QPoint( 60, 10 ) << QPoint( 80, 90 ) << QPoint( 75, 10 ) << QPoint( 110, 90 );
 QVector<QPoint> linePoints;
 foreach( QPoint point, polyPoints )
   linePoints << point + QPoint( 80, 0 );
 
 painter.drawLine( QPoint( 10, 10 ), QPoint( 30, 90 ) );
 painter.drawPolyline( polyPoints );
 painter.drawLines( linePoints );
 pixmap.save( "drawlines.png" );
 return 0;

}


 </source>


Draw rectangle

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the documentation of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.0 as published by the Free Software
    • Foundation and appearing in the file LICENSE.GPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. include <QtGui>

class MyWidget : public QWidget { public:

   MyWidget();

protected:

   void paintEvent(QPaintEvent *);

}; MyWidget::MyWidget() {

   QPalette palette(MyWidget::palette());
   palette.setColor(backgroundRole(), Qt::white);
   setPalette(palette);

} void MyWidget::paintEvent(QPaintEvent *) {

   QPainter painter(this);
   painter.setRenderHint(QPainter::Antialiasing);
   painter.setPen(Qt::darkGreen);
   painter.drawRect(1, 2, 6, 4);
   painter.setPen(Qt::darkGray);
   painter.drawLine(2, 8, 6, 2);

} int main(int argc, char *argv[]) {

   QApplication app(argc, argv);
   MyWidget widget;
   widget.show();
   return app.exec();

}


 </source>


Draw round rectangle

<source lang="cpp">

Foundations of Qt Development\Chapter07\rects\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 <QPixmap>
  3. include <QPainter>

int main( int argc, char **argv ) {

 QApplication app( argc, argv );
 QPixmap pixmap( 200, 100 );
 pixmap.fill( Qt::white );
 QPainter painter( &pixmap );
 painter.setPen( Qt::black );
   
 painter.drawRect( 10, 10, 85, 35 );
 painter.drawRoundRect( 10, 55, 85, 35 );
 
 QRect rect( 105, 10, 85, 35 );
 
 painter.drawRoundRect( rect );
 painter.drawRect( rect.translated( 0, 45 ) );
 
 pixmap.save( "rects.png" );
 return 0;

}


 </source>


QPolygon demo

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the documentation of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.0 as published by the Free Software
    • Foundation and appearing in the file LICENSE.GPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. include <QtGui>

int main() {

   {
       QPolygon polygon;
       polygon << QPoint(10, 20) << QPoint(20, 30);
   }
   {
       QPolygonF polygon;
       polygon << QPointF(10.4, 20.5) << QPointF(20.2, 30.2);
   }
   {
       static const int points[] = { 10, 20, 30, 40 };
       QPolygon polygon;
       polygon.setPoints(2, points);
   }
   {
       QPolygon polygon;
       polygon.setPoints(2, 10, 20, 30, 40);
   }
   {
       QPolygon polygon(1);
       polygon[0] = QPoint(4, 5);
       polygon.putPoints(1, 2, 6,7, 8,9);
   }
   {
       QPolygon polygon(3);
       polygon.putPoints(0, 3, 4,5, 0,0, 8,9);
       polygon.putPoints(1, 1, 6,7);
   }
   {
       QPolygon polygon1;
       polygon1.putPoints(0, 3, 1,2, 0,0, 5,6);
       // polygon1 is now the three-point polygon(1,2, 0,0, 5,6);
       QPolygon polygon2;
       polygon2.putPoints(0, 3, 4,4, 5,5, 6,6);
       // polygon2 is now (4,4, 5,5, 6,6);
       polygon1.putPoints(2, 3, polygon2);
       // polygon1 is now the five-point polygon(1,2, 0,0, 4,4, 5,5, 6,6);
   }
   return 0;

}


 </source>


Shaped clock

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the examples of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.0 as published by the Free Software
    • Foundation and appearing in the file LICENSE.GPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. ifndef SHAPEDCLOCK_H
  2. define SHAPEDCLOCK_H
  3. include <QWidget>

class ShapedClock : public QWidget {

   Q_OBJECT

public:

   ShapedClock(QWidget *parent = 0);
   QSize sizeHint() const;

protected:

   void mouseMoveEvent(QMouseEvent *event);
   void mousePressEvent(QMouseEvent *event);
   void paintEvent(QPaintEvent *event);
   void resizeEvent(QResizeEvent *event);

private:

   QPoint dragPosition;

};

  1. endif


  1. include <QtGui>
  2. include "shapedclock.h"

ShapedClock::ShapedClock(QWidget *parent)

   : QWidget(parent, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint)

{

   QTimer *timer = new QTimer(this);
   connect(timer, SIGNAL(timeout()), this, SLOT(update()));
   timer->start(1000);
   QAction *quitAction = new QAction(tr("E&xit"), this);
   quitAction->setShortcut(tr("Ctrl+Q"));
   connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
   addAction(quitAction);
   setContextMenuPolicy(Qt::ActionsContextMenu);
   setToolTip(tr("Drag the clock with the left mouse button.\n"
                 "Use the right mouse button to open a context menu."));
   setWindowTitle(tr("Shaped Analog Clock"));

}

void ShapedClock::mousePressEvent(QMouseEvent *event) {

   if (event->button() == Qt::LeftButton) {
       dragPosition = event->globalPos() - frameGeometry().topLeft();
       event->accept();
   }

}

void ShapedClock::mouseMoveEvent(QMouseEvent *event) {

   if (event->buttons() & Qt::LeftButton) {
       move(event->globalPos() - dragPosition);
       event->accept();
   }

}

void ShapedClock::paintEvent(QPaintEvent *) {

   static const QPoint hourHand[3] = {
       QPoint(7, 8),
       QPoint(-7, 8),
       QPoint(0, -40)
   };
   static const QPoint minuteHand[3] = {
       QPoint(7, 8),
       QPoint(-7, 8),
       QPoint(0, -70)
   };
   QColor hourColor(127, 0, 127);
   QColor minuteColor(0, 127, 127, 191);
   int side = qMin(width(), height());
   QTime time = QTime::currentTime();
   QPainter painter(this);
   painter.setRenderHint(QPainter::Antialiasing);
   painter.translate(width() / 2, height() / 2);
   painter.scale(side / 200.0, side / 200.0);
   painter.setPen(Qt::NoPen);
   painter.setBrush(hourColor);
   painter.save();
   painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
   painter.drawConvexPolygon(hourHand, 3);
   painter.restore();
   painter.setPen(hourColor);
   for (int i = 0; i < 12; ++i) {
       painter.drawLine(88, 0, 96, 0);
       painter.rotate(30.0);
   }
   painter.setPen(Qt::NoPen);
   painter.setBrush(minuteColor);
   painter.save();
   painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
   painter.drawConvexPolygon(minuteHand, 3);
   painter.restore();
   painter.setPen(minuteColor);
   for (int j = 0; j < 60; ++j) {
       if ((j % 5) != 0)
           painter.drawLine(92, 0, 96, 0);
       painter.rotate(6.0);
   }

}

void ShapedClock::resizeEvent(QResizeEvent * /* event */) {

   int side = qMin(width(), height());
   QRegion maskedRegion(width() / 2 - side / 2, height() / 2 - side / 2, side,
                        side, QRegion::Ellipse);
   setMask(maskedRegion);

}

QSize ShapedClock::sizeHint() const {

   return QSize(100, 100);

}


  1. include <QApplication>
  2. include "shapedclock.h"

int main(int argc, char *argv[]) {

   QApplication app(argc, argv);
   ShapedClock clock;
   clock.show();
   return app.exec();

}


 </source>


Shape item widget

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the examples of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.0 as published by the Free Software
    • Foundation and appearing in the file LICENSE.GPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. ifndef SHAPEITEM_H
  2. define SHAPEITEM_H
  3. include <QColor>
  4. include <QPainterPath>
  5. include <QPoint>

class ShapeItem { public:

   void setPath(const QPainterPath &path);
   void setToolTip(const QString &toolTip);
   void setPosition(const QPoint &position);
   void setColor(const QColor &color);
   QPainterPath path() const;
   QPoint position() const;
   QColor color() const;
   QString toolTip() const;

private:

   QPainterPath myPath;
   QPoint myPosition;
   QColor myColor;
   QString myToolTip;

};

  1. endif


  1. include <QtGui>
  2. include "shapeitem.h"

QPainterPath ShapeItem::path() const {

   return myPath;

}

QPoint ShapeItem::position() const {

   return myPosition;

}

QColor ShapeItem::color() const {

   return myColor;

}

QString ShapeItem::toolTip() const {

   return myToolTip;

}

void ShapeItem::setPath(const QPainterPath &path) {

   myPath = path;

}

void ShapeItem::setToolTip(const QString &toolTip) {

   myToolTip = toolTip;

}

void ShapeItem::setPosition(const QPoint &position) {

   myPosition = position;

}

void ShapeItem::setColor(const QColor &color) {

   myColor = color;

}


  1. ifndef SORTINGBOX_H
  2. define SORTINGBOX_H
  3. include <QWidget>
  4. include "shapeitem.h"

QT_BEGIN_NAMESPACE class QAction; class QPoint; class QToolButton; QT_END_NAMESPACE

class SortingBox : public QWidget {

   Q_OBJECT

public:

   SortingBox();

protected:

   bool event(QEvent *event);
   void resizeEvent(QResizeEvent *event);
   void paintEvent(QPaintEvent *event);
   void mousePressEvent(QMouseEvent *event);
   void mouseMoveEvent(QMouseEvent *event);
   void mouseReleaseEvent(QMouseEvent *event);

private slots:

   void createNewCircle();
   void createNewSquare();
   void createNewTriangle();

private:

   int updateButtonGeometry(QToolButton *button, int x, int y);
   void createShapeItem(const QPainterPath &path, const QString &toolTip,
                        const QPoint &pos, const QColor &color);
   int itemAt(const QPoint &pos);
   void moveItemTo(const QPoint &pos);
   QPoint initialItemPosition(const QPainterPath &path);
   QPoint randomItemPosition();
   QColor initialItemColor();
   QColor randomItemColor();
   QToolButton *createToolButton(const QString &toolTip, const QIcon &icon,
                                 const char *member);
   QList<ShapeItem> shapeItems;
   QPainterPath circlePath;
   QPainterPath squarePath;
   QPainterPath trianglePath;
   QPoint previousPosition;
   ShapeItem *itemInMotion;
   QToolButton *newCircleButton;
   QToolButton *newSquareButton;
   QToolButton *newTriangleButton;

};

  1. endif


  1. include <QtGui>
  2. include <stdlib.h>
  3. include "sortingbox.h"

SortingBox::SortingBox() {

   setMouseTracking(true);

   setBackgroundRole(QPalette::Base);
   itemInMotion = 0;
   newCircleButton = createToolButton(tr("New Circle"),
                                      QIcon(":/images/circle.png"),
                                      SLOT(createNewCircle()));
   newSquareButton = createToolButton(tr("New Square"),
                                      QIcon(":/images/square.png"),
                                      SLOT(createNewSquare()));
   newTriangleButton = createToolButton(tr("New Triangle"),
                                        QIcon(":/images/triangle.png"),
                                        SLOT(createNewTriangle()));
   circlePath.addEllipse(QRect(0, 0, 100, 100));
   squarePath.addRect(QRect(0, 0, 100, 100));
   qreal x = trianglePath.currentPosition().x();
   qreal y = trianglePath.currentPosition().y();
   trianglePath.moveTo(x + 120 / 2, y);
   trianglePath.lineTo(0, 100);
   trianglePath.lineTo(120, 100);
   trianglePath.lineTo(x + 120 / 2, y);

   setWindowTitle(tr("Tool Tips"));
   resize(500, 300);
   createShapeItem(circlePath, tr("Circle"), initialItemPosition(circlePath),
                   initialItemColor());
   createShapeItem(squarePath, tr("Square"), initialItemPosition(squarePath),
                   initialItemColor());
   createShapeItem(trianglePath, tr("Triangle"),
                   initialItemPosition(trianglePath), initialItemColor());

}

bool SortingBox::event(QEvent *event) {

   if (event->type() == QEvent::ToolTip) {
       QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
       int index = itemAt(helpEvent->pos());
       if (index != -1) {
           QToolTip::showText(helpEvent->globalPos(), shapeItems[index].toolTip());
       } else {
           QToolTip::hideText();
           event->ignore();
       }
       return true;
   }
   return QWidget::event(event);

}

void SortingBox::resizeEvent(QResizeEvent * /* event */) {

   int margin = style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
   int x = width() - margin;
   int y = height() - margin;
   y = updateButtonGeometry(newCircleButton, x, y);
   y = updateButtonGeometry(newSquareButton, x, y);
   updateButtonGeometry(newTriangleButton, x, y);

}

void SortingBox::paintEvent(QPaintEvent * /* event */) {

   QPainter painter(this);
   painter.setRenderHint(QPainter::Antialiasing);
   foreach (ShapeItem shapeItem, shapeItems) {

       painter.translate(shapeItem.position());

       painter.setBrush(shapeItem.color());
       painter.drawPath(shapeItem.path());
       painter.translate(-shapeItem.position());
   }

}

void SortingBox::mousePressEvent(QMouseEvent *event) {

   if (event->button() == Qt::LeftButton) {
       int index = itemAt(event->pos());
       if (index != -1) {
           itemInMotion = &shapeItems[index];
           previousPosition = event->pos();
           shapeItems.move(index, shapeItems.size() - 1);
           update();
       }
   }

}

void SortingBox::mouseMoveEvent(QMouseEvent *event) {

   if ((event->buttons() & Qt::LeftButton) && itemInMotion)
       moveItemTo(event->pos());

}

void SortingBox::mouseReleaseEvent(QMouseEvent *event) {

   if (event->button() == Qt::LeftButton && itemInMotion) {
       moveItemTo(event->pos());
       itemInMotion = 0;
   }

}

void SortingBox::createNewCircle() {

   static int count = 1;
   createShapeItem(circlePath, tr("Circle <%1>").arg(++count),
                   randomItemPosition(), randomItemColor());

}

void SortingBox::createNewSquare() {

   static int count = 1;
   createShapeItem(squarePath, tr("Square <%1>").arg(++count),
                   randomItemPosition(), randomItemColor());

}

void SortingBox::createNewTriangle() {

   static int count = 1;
   createShapeItem(trianglePath, tr("Triangle <%1>").arg(++count),
                   randomItemPosition(), randomItemColor());

}

int SortingBox::itemAt(const QPoint &pos) {

   for (int i = shapeItems.size() - 1; i >= 0; --i) {
       const ShapeItem &item = shapeItems[i];
       if (item.path().contains(pos - item.position()))
           return i;
   }
   return -1;

}

void SortingBox::moveItemTo(const QPoint &pos) {

   QPoint offset = pos - previousPosition;
   itemInMotion->setPosition(itemInMotion->position() + offset);

   previousPosition = pos;
   update();

}

int SortingBox::updateButtonGeometry(QToolButton *button, int x, int y) {

   QSize size = button->sizeHint();
   button->setGeometry(x - size.rwidth(), y - size.rheight(),
                       size.rwidth(), size.rheight());
   return y - size.rheight()
          - style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);

}

void SortingBox::createShapeItem(const QPainterPath &path,

                                const QString &toolTip, const QPoint &pos,
                                const QColor &color)

{

   ShapeItem shapeItem;
   shapeItem.setPath(path);
   shapeItem.setToolTip(toolTip);
   shapeItem.setPosition(pos);
   shapeItem.setColor(color);
   shapeItems.append(shapeItem);
   update();

}

QToolButton *SortingBox::createToolButton(const QString &toolTip,

                                         const QIcon &icon, const char *member)

{

   QToolButton *button = new QToolButton(this);
   button->setToolTip(toolTip);
   button->setIcon(icon);
   button->setIconSize(QSize(32, 32));
   connect(button, SIGNAL(clicked()), this, member);
   return button;

}

QPoint SortingBox::initialItemPosition(const QPainterPath &path) {

   int x;
   int y = (height() - (int)path.controlPointRect().height()) / 2;
   if (shapeItems.size() == 0)
       x = ((3 * width()) / 2 - (int)path.controlPointRect().width()) / 2;
   else
       x = (width() / shapeItems.size()
            - (int)path.controlPointRect().width()) / 2;
   return QPoint(x, y);

}

QPoint SortingBox::randomItemPosition() {

   return QPoint(qrand() % (width() - 120), qrand() % (height() - 120));

}

QColor SortingBox::initialItemColor() {

   return QColor::fromHsv(((shapeItems.size() + 1) * 85) % 256, 255, 190);

}

QColor SortingBox::randomItemColor() {

   return QColor::fromHsv(qrand() % 256, 255, 190);

}


  1. include <QtGui>
  2. include "sortingbox.h"

int main(int argc, char *argv[]) {

   Q_INIT_RESOURCE(tooltips);
   QApplication app(argc, argv);
   qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
   SortingBox sortingBox;
   sortingBox.show();
   return app.exec();

}


 </source>