QtBase  v6.3.1
graphwidget.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** BSD License Usage
18 ** Alternatively, you may use this file under the terms of the BSD license
19 ** as follows:
20 **
21 ** "Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions are
23 ** met:
24 ** * Redistributions of source code must retain the above copyright
25 ** notice, this list of conditions and the following disclaimer.
26 ** * Redistributions in binary form must reproduce the above copyright
27 ** notice, this list of conditions and the following disclaimer in
28 ** the documentation and/or other materials provided with the
29 ** distribution.
30 ** * Neither the name of The Qt Company Ltd nor the names of its
31 ** contributors may be used to endorse or promote products derived
32 ** from this software without specific prior written permission.
33 **
34 **
35 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46 **
47 ** $QT_END_LICENSE$
48 **
49 ****************************************************************************/
50 
51 #include "graphwidget.h"
52 #include "edge.h"
53 #include "node.h"
54 
55 #include <math.h>
56 
57 #include <QKeyEvent>
58 #include <QRandomGenerator>
59 
63 {
64  QGraphicsScene *scene = new QGraphicsScene(this);
66  scene->setSceneRect(-200, -200, 400, 400);
67  setScene(scene);
72  scale(qreal(0.8), qreal(0.8));
73  setMinimumSize(400, 400);
74  setWindowTitle(tr("Elastic Nodes"));
76 
78  Node *node1 = new Node(this);
79  Node *node2 = new Node(this);
80  Node *node3 = new Node(this);
81  Node *node4 = new Node(this);
82  centerNode = new Node(this);
83  Node *node6 = new Node(this);
84  Node *node7 = new Node(this);
85  Node *node8 = new Node(this);
86  Node *node9 = new Node(this);
87  scene->addItem(node1);
88  scene->addItem(node2);
89  scene->addItem(node3);
90  scene->addItem(node4);
91  scene->addItem(centerNode);
92  scene->addItem(node6);
93  scene->addItem(node7);
94  scene->addItem(node8);
95  scene->addItem(node9);
96  scene->addItem(new Edge(node1, node2));
97  scene->addItem(new Edge(node2, node3));
98  scene->addItem(new Edge(node2, centerNode));
99  scene->addItem(new Edge(node3, node6));
100  scene->addItem(new Edge(node4, node1));
101  scene->addItem(new Edge(node4, centerNode));
102  scene->addItem(new Edge(centerNode, node6));
103  scene->addItem(new Edge(centerNode, node8));
104  scene->addItem(new Edge(node6, node9));
105  scene->addItem(new Edge(node7, node4));
106  scene->addItem(new Edge(node8, node7));
107  scene->addItem(new Edge(node9, node8));
108 
109  node1->setPos(-50, -50);
110  node2->setPos(0, -50);
111  node3->setPos(50, -50);
112  node4->setPos(-50, 0);
113  centerNode->setPos(0, 0);
114  node6->setPos(50, 0);
115  node7->setPos(-50, 50);
116  node8->setPos(0, 50);
117  node9->setPos(50, 50);
118 }
120 
123 {
124  if (!timerId)
125  timerId = startTimer(1000 / 25);
126 }
128 
131 {
132  switch (event->key()) {
133  case Qt::Key_Up:
134  centerNode->moveBy(0, -20);
135  break;
136  case Qt::Key_Down:
137  centerNode->moveBy(0, 20);
138  break;
139  case Qt::Key_Left:
140  centerNode->moveBy(-20, 0);
141  break;
142  case Qt::Key_Right:
143  centerNode->moveBy(20, 0);
144  break;
145  case Qt::Key_Plus:
146  zoomIn();
147  break;
148  case Qt::Key_Minus:
149  zoomOut();
150  break;
151  case Qt::Key_Space:
152  case Qt::Key_Enter:
153  shuffle();
154  break;
155  default:
157  }
158 }
160 
163 {
164  Q_UNUSED(event);
165 
166  QList<Node *> nodes;
168  for (QGraphicsItem *item : items) {
169  if (Node *node = qgraphicsitem_cast<Node *>(item))
170  nodes << node;
171  }
172 
173  for (Node *node : qAsConst(nodes))
174  node->calculateForces();
175 
176  bool itemsMoved = false;
177  for (Node *node : qAsConst(nodes)) {
178  if (node->advancePosition())
179  itemsMoved = true;
180  }
181 
182  if (!itemsMoved) {
183  killTimer(timerId);
184  timerId = 0;
185  }
186 }
188 
189 #if QT_CONFIG(wheelevent)
191 void GraphWidget::wheelEvent(QWheelEvent *event)
192 {
193  scaleView(pow(2., -event->angleDelta().y() / 240.0));
194 }
196 #endif
197 
200 {
201  Q_UNUSED(rect);
202 
203  // Shadow
204  QRectF sceneRect = this->sceneRect();
205  QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
206  QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
207  if (rightShadow.intersects(rect) || rightShadow.contains(rect))
208  painter->fillRect(rightShadow, Qt::darkGray);
209  if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
210  painter->fillRect(bottomShadow, Qt::darkGray);
211 
212  // Fill
214  gradient.setColorAt(0, Qt::white);
215  gradient.setColorAt(1, Qt::lightGray);
216  painter->fillRect(rect.intersected(sceneRect), gradient);
219 
220  // Text
221  QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4,
222  sceneRect.width() - 4, sceneRect.height() - 4);
223  QString message(tr("Click and drag the nodes around, and zoom with the mouse "
224  "wheel or the '+' and '-' keys"));
225 
226  QFont font = painter->font();
227  font.setBold(true);
228  font.setPointSize(14);
229  painter->setFont(font);
234 }
236 
238 void GraphWidget::scaleView(qreal scaleFactor)
239 {
240  qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
241  if (factor < 0.07 || factor > 100)
242  return;
243 
244  scale(scaleFactor, scaleFactor);
245 }
247 
249 {
251  for (QGraphicsItem *item : items) {
252  if (qgraphicsitem_cast<Node *>(item))
253  item->setPos(-150 + QRandomGenerator::global()->bounded(300), -150 + QRandomGenerator::global()->bounded(300));
254  }
255 }
256 
258 {
259  scaleView(qreal(1.2));
260 }
261 
263 {
264  scaleView(1 / qreal(1.2));
265 }
void timerEvent(QTimerEvent *event) override
[3]
void itemMoved()
[1]
void scaleView(qreal scaleFactor)
[6]
GraphWidget(QWidget *parent=nullptr)
[0]
Definition: graphwidget.cpp:61
void shuffle()
[7]
void drawBackground(QPainter *painter, const QRectF &rect) override
[4]
void keyPressEvent(QKeyEvent *event) override
[2]
void zoomOut()
[0]
Definition: node.h:62
The QFont class specifies a query for a font used for drawing text.
Definition: qfont.h:56
void setPointSize(int)
Definition: qfont.cpp:1006
void setBold(bool)
Definition: qfont.h:335
void setColorAt(qreal pos, const QColor &color)
Definition: qbrush.cpp:1596
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:83
void moveBy(qreal dx, qreal dy)
void setPos(const QPointF &pos)
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items.
QList< QGraphicsItem * > items(Qt::SortOrder order=Qt::DescendingOrder) const
void addItem(QGraphicsItem *item)
void setItemIndexMethod(ItemIndexMethod method)
void setSceneRect(const QRectF &rect)
The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene.
Definition: qgraphicsview.h:60
QList< QGraphicsItem * > items() const
QTransform transform() const
QRectF sceneRect
the area of the scene visualized by this view.
Definition: qgraphicsview.h:66
void scale(qreal sx, qreal sy)
void setCacheMode(CacheMode mode)
void setRenderHint(QPainter::RenderHint hint, bool enabled=true)
void keyPressEvent(QKeyEvent *event) override
void setScene(QGraphicsScene *scene)
friend class QGraphicsScene
@ BoundingRectViewportUpdate
void setTransformationAnchor(ViewportAnchor anchor)
QGraphicsScene * scene() const
void setViewportUpdateMode(ViewportUpdateMode mode)
The QKeyEvent class describes a key event.
Definition: qevent.h:471
The QLinearGradient class is used in combination with QBrush to specify a linear gradient brush.
Definition: qbrush.h:430
Definition: qlist.h:108
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:82
void drawRect(const QRectF &rect)
Definition: qpainter.h:554
void setPen(const QColor &color)
Definition: qpainter.cpp:3640
const QFont & font() const
Definition: qpainter.cpp:3890
void setFont(const QFont &f)
Definition: qpainter.cpp:3866
void drawText(const QPointF &p, const QString &s)
Definition: qpainter.cpp:5444
void setBrush(const QBrush &brush)
Definition: qpainter.cpp:3755
@ Antialiasing
Definition: qpainter.h:88
void fillRect(const QRectF &, const QBrush &)
Definition: qpainter.cpp:6644
static Q_DECL_CONST_FUNCTION QRandomGenerator * global()
Definition: qrandom.h:311
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
constexpr qreal bottom() const noexcept
Definition: qrect.h:527
constexpr qreal height() const noexcept
Definition: qrect.h:741
constexpr qreal width() const noexcept
Definition: qrect.h:738
bool contains(const QRectF &r) const noexcept
Definition: qrect.cpp:2006
constexpr qreal left() const noexcept
Definition: qrect.h:524
bool intersects(const QRectF &r) const noexcept
Definition: qrect.cpp:2284
constexpr QPointF topLeft() const noexcept
Definition: qrect.h:538
constexpr QPointF bottomRight() const noexcept
Definition: qrect.h:539
constexpr qreal top() const noexcept
Definition: qrect.h:525
constexpr qreal right() const noexcept
Definition: qrect.h:526
constexpr int width() const noexcept
Definition: qrect.h:263
constexpr QRect translated(int dx, int dy) const noexcept
Definition: qrect.h:288
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:367
QTransform & scale(qreal sx, qreal sy)
Definition: qtransform.cpp:460
QRect mapRect(const QRect &) const
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
float factor
rect
[4]
QRect textRect
QPainterPath node()
Definition: paths.cpp:574
@ white
Definition: qnamespace.h:62
@ darkGray
Definition: qnamespace.h:63
@ black
Definition: qnamespace.h:61
@ lightGray
Definition: qnamespace.h:65
@ Key_Plus
Definition: qnamespace.h:550
@ Key_Right
Definition: qnamespace.h:700
@ Key_Enter
Definition: qnamespace.h:689
@ Key_Space
Definition: qnamespace.h:538
@ Key_Left
Definition: qnamespace.h:698
@ Key_Up
Definition: qnamespace.h:699
@ Key_Minus
Definition: qnamespace.h:552
@ Key_Down
Definition: qnamespace.h:701
@ NoBrush
Definition: qnamespace.h:1140
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: qopengl.h:270
struct _cl_event * event
Definition: qopenglext.h:2998
#define tr(X)
Q_UNUSED(salary)
[21]
QGraphicsItem * item
QPainter painter(this)
[7]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent