(C++) QGraphicsPathItem example 3: Bezier quadratic lines again
February 24, 2017 · View on GitHub
(C++)
QGraphicsPathItem example 3: Bezier quadratic lines again
QGraphicsPathItem example 3: Bezier quadratic lines again is a QGraphicsPathItem example. This example shows how to use QGraphicsRectItems to manipulatie QGraphicsPathItems, resulting in quadratic Bezier curves.
- View a screenshot of 'CppQGraphicsPathItemExample3' (png)
Download the Qt Creator project
'CppQGraphicsPathItemExample3' (zip)
Technical facts
Operating system(s) or programming environment(s)
Lubuntu 12.10 (quantal)
Qt Creator 2.5.2
- G++ 4.7.2
Libraries used:
Qt project file: CppQGraphicsPathItemExample3.pro
QT += core gui QMAKE_CXXFLAGS += -std=c++11 -Wall -Wextra -Werror TARGET = CppQGraphicsPathItemExample3 TEMPLATE = app SOURCES += \ qtmain.cpp \ qtwidget.cpp \ qtpathitem.cpp \ qtrectitem.cpp HEADERS += \ qtwidget.h \ qtpathitem.h \ qtrectitem.h
qtmain.cpp
#include <QApplication> #include <QDesktopWidget> #include "qtwidget.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QtWidget w; { //Resize the dialog and put it in the screen center w.setGeometry(0,0,600,400); const QRect screen = QApplication::desktop()->screenGeometry(); w.move( screen.center() - w.rect().center() ); } w.show(); return a.exec(); }
qtpathitem.h
#ifndef QTPATHITEM_H #define QTPATHITEM_H #include <QGraphicsPathItem> struct QtRectItem; struct QtPathItem : public QGraphicsPathItem { QtPathItem( const QtRectItem * const from, const QtRectItem * const mid, const QtRectItem * const to, QGraphicsItem *parent = 0, QGraphicsScene *scene = 0); protected: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: const QtRectItem * const m_from; const QtRectItem * const m_mid; const QtRectItem * const m_to; }; #endif // QTPATHITEM_H
qtpathitem.cpp
#include <cassert> #include <QPainter> #include "qtpathitem.h" #include "qtrectitem.h" QtPathItem::QtPathItem( const QtRectItem * const from, const QtRectItem * const mid, const QtRectItem * const to, QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsPathItem(parent,scene), m_from(from), m_mid(mid), m_to(to) { assert(!(flags() & QGraphicsItem::ItemIsMovable) ); assert(!(flags() & QGraphicsItem::ItemIsSelectable) ); } void QtPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { QPainterPath path; path.moveTo(m_from->pos()); //Line must go _though_ mid pos, instead of using it as a virtual hinge point //Solution: // - define point p as the middle between from and to // - define point q as the mirror point of q, using mid_pos as a mirror const QPointF p((m_from->pos() + m_to->pos()) / 2.0); const double dx = m_mid->pos().x() - p.x(); const double dy = m_mid->pos().y() - p.y(); const QPointF q(p.x() + dx + dx, p.y() + dy + dy); path.quadTo(q,m_to->pos()); this->setPath(path); QGraphicsPathItem::paint(painter,option,widget); }
qtrectitem.h
#ifndef QTRECTITEM_H #define QTRECTITEM_H #include <QGraphicsRectItem> struct QtRectItem : public QGraphicsRectItem { QtRectItem(QGraphicsItem *parent = 0, QGraphicsScene *scene = 0); }; #endif // QTRECTITEM_H
qtrectitem.cpp
#include "qtrectitem.h" QtRectItem::QtRectItem(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsRectItem(parent,scene) { this->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); const double length = 8; this->setRect(-length/2.0,-length/2.0,length,length); }
qtwidget.h
#ifndef QTWIDGET_H #define QTWIDGET_H #include <QGraphicsView> ///The widget holding the items struct QtWidget : public QGraphicsView { QtWidget(QWidget *parent = 0); }; #endif // QTWIDGET_H
qtwidget.cpp
#include <cassert> #include <QGraphicsScene> #include "qtrectitem.h" #include "qtpathitem.h" #include "qtwidget.h" QtWidget::QtWidget(QWidget *parent) : QGraphicsView(new QGraphicsScene,parent) { const int n_items = 18; std::vector<QtRectItem *> rects; for (int i=0; i!=n_items; ++i) { const double angle = 2.0 * M_PI * (static_cast<double>(i) / static_cast<double>(n_items)); const double x1 = std::sin(angle) * 100.0; const double y1 = -std::cos(angle) * 100.0; QtRectItem * const rect = new QtRectItem; rect->setPos(x1,y1); scene()->addItem(rect); rects.push_back(rect); } for (int i=0; i<n_items-2; i+=3) { assert(i + 2 < n_items); QtPathItem * const item = new QtPathItem( rects[(i+0) % n_items], rects[(i+1) % n_items], rects[(i+2) % n_items]); scene()->addItem(item); } }