Sophie

Sophie

distrib > Mageia > 6 > armv5tl > media > core-updates > by-pkgid > 768f7d9f703884aa2562bf0a651086df > files > 3885

qtbase5-doc-5.9.4-1.1.mga6.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- diagramscene.qdoc -->
  <title>Diagram Scene Example | Qt Widgets 5.9</title>
  <link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
  <script type="text/javascript">
    document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
    // loading style sheet breaks anchors that were jumped to before
    // so force jumping to anchor again
    setTimeout(function() {
        var anchor = location.hash;
        // need to jump to different anchor first (e.g. none)
        location.hash = "#";
        setTimeout(function() {
            location.hash = anchor;
        }, 0);
    }, 0);
  </script>
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="main">
    <div class="main-rounded">
      <div class="navigationbar">
        <table><tr>
<td >Qt 5.9</td><td ><a href="qtwidgets-index.html">Qt Widgets</a></td><td >Diagram Scene Example</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right">Qt 5.9.4 Reference Documentation</td>
        </tr></table>
      </div>
    </div>
<div class="content">
<div class="line">
<div class="content mainContent">
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#mainwindow-class-definition">MainWindow Class Definition</a></li>
<li class="level1"><a href="#mainwindow-class-implementation">MainWindow Class Implementation</a></li>
<li class="level1"><a href="#diagramscene-class-definition">DiagramScene Class Definition</a></li>
<li class="level1"><a href="#diagramscene-class-implementation">DiagramScene Class Implementation</a></li>
<li class="level1"><a href="#diagramitem-class-definition">DiagramItem Class Definition</a></li>
<li class="level1"><a href="#diagramitem-class-implementation">DiagramItem Class Implementation</a></li>
<li class="level1"><a href="#diagramtextitem-class-definition">DiagramTextItem Class Definition</a></li>
<li class="level1"><a href="#diagramtextitem-implementation">DiagramTextItem Implementation</a></li>
<li class="level1"><a href="#arrow-class-definition">Arrow Class Definition</a></li>
<li class="level1"><a href="#arrow-class-implementation">Arrow Class Implementation</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Diagram Scene Example</h1>
<span class="subtitle"></span>
<!-- $$$graphicsview/diagramscene-description -->
<div class="descr"> <a name="details"></a>
<p class="centerAlign"><img src="images/diagramscene.png" alt="" /></p><p>The Diagram Scene example is an application in which you can create a flowchart diagram. It is possible to add flowchart shapes and text and connect the shapes by arrows as shown in the image above. The shapes, arrows, and text can be given different colors, and it is possible to change the font, style, and underline of the text.</p>
<p>The Qt graphics view framework is designed to manage and display custom 2D graphics items. The main classes of the framework are <a href="qgraphicsitem.html">QGraphicsItem</a>, <a href="qgraphicsscene.html">QGraphicsScene</a> and <a href="qgraphicsview.html">QGraphicsView</a>. The graphics scene manages the items and provides a surface for them. <a href="qgraphicsview.html">QGraphicsView</a> is a widget that is used to render a scene on the screen. See the <a href="graphicsview.html">Graphics View Framework</a> for a more detailed description of the framework.</p>
<p>In this example we show how to create such custom graphics scenes and items by implementing classes that inherit <a href="qgraphicsscene.html">QGraphicsScene</a> and <a href="qgraphicsitem.html">QGraphicsItem</a>.</p>
<p>In particular we show how to:</p>
<ul>
<li>Create custom graphics items.</li>
<li>Handle mouse events and movement of items.</li>
<li>Implement a graphics scene that can manage our custom items.</li>
<li>Custom painting of items.</li>
<li>Create a movable and editable text item.</li>
</ul>
<p>The example consists of the following classes:</p>
<ul>
<li><code>MainWindow</code> creates the widgets and display them in a <a href="qmainwindow.html">QMainWindow</a>. It also manages the interaction between the widgets and the graphics scene, view and items.</li>
<li><code>DiagramItem</code> inherits <a href="qgraphicspolygonitem.html">QGraphicsPolygonItem</a> and represents a flowchart shape.</li>
<li><code>TextDiagramItem</code> inherits <a href="qgraphicstextitem.html">QGraphicsTextItem</a> and represents text items in the diagram. The class adds support for moving the item with the mouse, which is not supported by <a href="qgraphicstextitem.html">QGraphicsTextItem</a>.</li>
<li><code>Arrow</code> inherits <a href="qgraphicslineitem.html">QGraphicsLineItem</a> and is an arrow that connect two DiagramItems.</li>
<li><code>DiagramScene</code> inherits QGraphicsDiagramScene and provides support for <code>DiagramItem</code>, <code>Arrow</code> and <code>DiagramTextItem</code> (In addition to the support already handled by <a href="qgraphicsscene.html">QGraphicsScene</a>).</li>
</ul>
<a name="mainwindow-class-definition"></a>
<h2 id="mainwindow-class-definition">MainWindow Class Definition</h2>
<pre class="cpp">

  <span class="keyword">class</span> MainWindow : <span class="keyword">public</span> <span class="type"><a href="qmainwindow.html">QMainWindow</a></span>
  {
      Q_OBJECT

  <span class="keyword">public</span>:
     MainWindow();

  <span class="keyword">private</span> <span class="keyword">slots</span>:
      <span class="type">void</span> backgroundButtonGroupClicked(<span class="type"><a href="qabstractbutton.html">QAbstractButton</a></span> <span class="operator">*</span>button);
      <span class="type">void</span> buttonGroupClicked(<span class="type">int</span> id);
      <span class="type">void</span> deleteItem();
      <span class="type">void</span> pointerGroupClicked(<span class="type">int</span> id);
      <span class="type">void</span> bringToFront();
      <span class="type">void</span> sendToBack();
      <span class="type">void</span> itemInserted(DiagramItem <span class="operator">*</span>item);
      <span class="type">void</span> textInserted(<span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span> <span class="operator">*</span>item);
      <span class="type">void</span> currentFontChanged(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qfont.html">QFont</a></span> <span class="operator">&amp;</span>font);
      <span class="type">void</span> fontSizeChanged(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>size);
      <span class="type">void</span> sceneScaleChanged(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>scale);
      <span class="type">void</span> textColorChanged();
      <span class="type">void</span> itemColorChanged();
      <span class="type">void</span> lineColorChanged();
      <span class="type">void</span> textButtonTriggered();
      <span class="type">void</span> fillButtonTriggered();
      <span class="type">void</span> lineButtonTriggered();
      <span class="type">void</span> handleFontChange();
      <span class="type">void</span> itemSelected(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item);
      <span class="type">void</span> about();

  <span class="keyword">private</span>:
      <span class="type">void</span> createToolBox();
      <span class="type">void</span> createActions();
      <span class="type">void</span> createMenus();
      <span class="type">void</span> createToolbars();
      <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>createBackgroundCellWidget(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>text<span class="operator">,</span>
                                          <span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>image);
      <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>createCellWidget(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>text<span class="operator">,</span>
                                DiagramItem<span class="operator">::</span>DiagramType type);
      <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>createColorMenu(<span class="keyword">const</span> <span class="type">char</span> <span class="operator">*</span>slot<span class="operator">,</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> defaultColor);
      <span class="type"><a href="../qtgui/qicon.html">QIcon</a></span> createColorToolButtonIcon(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>image<span class="operator">,</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> color);
      <span class="type"><a href="../qtgui/qicon.html">QIcon</a></span> createColorIcon(<span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> color);

      DiagramScene <span class="operator">*</span>scene;
      <span class="type"><a href="qgraphicsview.html">QGraphicsView</a></span> <span class="operator">*</span>view;

      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>exitAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>addAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>deleteAction;

      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>toFrontAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>sendBackAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>aboutAction;

      <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>fileMenu;
      <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>itemMenu;
      <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>aboutMenu;

      <span class="type"><a href="qtoolbar.html">QToolBar</a></span> <span class="operator">*</span>textToolBar;
      <span class="type"><a href="qtoolbar.html">QToolBar</a></span> <span class="operator">*</span>editToolBar;
      <span class="type"><a href="qtoolbar.html">QToolBar</a></span> <span class="operator">*</span>colorToolBar;
      <span class="type"><a href="qtoolbar.html">QToolBar</a></span> <span class="operator">*</span>pointerToolbar;

      <span class="type"><a href="qcombobox.html">QComboBox</a></span> <span class="operator">*</span>sceneScaleCombo;
      <span class="type"><a href="qcombobox.html">QComboBox</a></span> <span class="operator">*</span>itemColorCombo;
      <span class="type"><a href="qcombobox.html">QComboBox</a></span> <span class="operator">*</span>textColorCombo;
      <span class="type"><a href="qcombobox.html">QComboBox</a></span> <span class="operator">*</span>fontSizeCombo;
      <span class="type"><a href="qfontcombobox.html">QFontComboBox</a></span> <span class="operator">*</span>fontCombo;

      <span class="type"><a href="qtoolbox.html">QToolBox</a></span> <span class="operator">*</span>toolBox;
      <span class="type"><a href="qbuttongroup.html">QButtonGroup</a></span> <span class="operator">*</span>buttonGroup;
      <span class="type"><a href="qbuttongroup.html">QButtonGroup</a></span> <span class="operator">*</span>pointerTypeGroup;
      <span class="type"><a href="qbuttongroup.html">QButtonGroup</a></span> <span class="operator">*</span>backgroundButtonGroup;
      <span class="type"><a href="qtoolbutton.html">QToolButton</a></span> <span class="operator">*</span>fontColorToolButton;
      <span class="type"><a href="qtoolbutton.html">QToolButton</a></span> <span class="operator">*</span>fillColorToolButton;
      <span class="type"><a href="qtoolbutton.html">QToolButton</a></span> <span class="operator">*</span>lineColorToolButton;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>boldAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>underlineAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>italicAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>textAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>fillAction;
      <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>lineAction;
  };

</pre>
<p>The <code>MainWindow</code> class creates and lays out the widgets in a <a href="qmainwindow.html">QMainWindow</a>. The class forwards input from the widgets to the DiagramScene. It also updates its widgets when the diagram scene's text item changes, or a diagram item or a diagram text item is inserted into the scene.</p>
<p>The class also deletes items from the scene and handles the z-ordering, which decides the order in which items are drawn when they overlap each other.</p>
<a name="mainwindow-class-implementation"></a>
<h2 id="mainwindow-class-implementation">MainWindow Class Implementation</h2>
<p>We start with a look at the constructor:</p>
<pre class="cpp">

  MainWindow<span class="operator">::</span>MainWindow()
  {
      createActions();
      createToolBox();
      createMenus();

      scene <span class="operator">=</span> <span class="keyword">new</span> DiagramScene(itemMenu<span class="operator">,</span> <span class="keyword">this</span>);
      scene<span class="operator">-</span><span class="operator">&gt;</span>setSceneRect(<span class="type"><a href="../qtcore/qrectf.html">QRectF</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">5000</span><span class="operator">,</span> <span class="number">5000</span>));
      connect(scene<span class="operator">,</span> SIGNAL(itemInserted(DiagramItem<span class="operator">*</span>))<span class="operator">,</span>
              <span class="keyword">this</span><span class="operator">,</span> SLOT(itemInserted(DiagramItem<span class="operator">*</span>)));
      connect(scene<span class="operator">,</span> SIGNAL(textInserted(<span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span><span class="operator">*</span>))<span class="operator">,</span>
              <span class="keyword">this</span><span class="operator">,</span> SLOT(textInserted(<span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span><span class="operator">*</span>)));
      connect(scene<span class="operator">,</span> SIGNAL(itemSelected(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">*</span>))<span class="operator">,</span>
              <span class="keyword">this</span><span class="operator">,</span> SLOT(itemSelected(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">*</span>)));
      createToolbars();

      <span class="type"><a href="qhboxlayout.html">QHBoxLayout</a></span> <span class="operator">*</span>layout <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qhboxlayout.html">QHBoxLayout</a></span>;
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(toolBox);
      view <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgraphicsview.html">QGraphicsView</a></span>(scene);
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(view);

      <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>widget <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qwidget.html">QWidget</a></span>;
      widget<span class="operator">-</span><span class="operator">&gt;</span>setLayout(layout);

      setCentralWidget(widget);
      setWindowTitle(tr(<span class="string">&quot;Diagramscene&quot;</span>));
      setUnifiedTitleAndToolBarOnMac(<span class="keyword">true</span>);
  }

</pre>
<p>In the constructor we call methods to create the widgets and layouts of the example before we create the diagram scene. The toolbars must be created after the scene as they connect to its signals. We then lay the widgets out in the window.</p>
<p>We connect to the <code>itemInserted()</code> and <code>textInserted()</code> slots of the diagram scenes as we want to uncheck the buttons in the tool box when an item is inserted. When an item is selected in the scene we receive the <code>itemSelected()</code> signal. We use this to update the widgets that display font properties if the item selected is a <code>DiagramTextItem</code>.</p>
<p>The <code>createToolBox()</code> function creates and lays out the widgets of the <code>toolBox</code> <a href="qtoolbox.html">QToolBox</a>. We will not examine it with a high level of detail as it does not deal with graphics framework specific functionality. Here is its implementation:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>createToolBox()
  {
      buttonGroup <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qbuttongroup.html">QButtonGroup</a></span>(<span class="keyword">this</span>);
      buttonGroup<span class="operator">-</span><span class="operator">&gt;</span>setExclusive(<span class="keyword">false</span>);
      connect(buttonGroup<span class="operator">,</span> SIGNAL(buttonClicked(<span class="type">int</span>))<span class="operator">,</span>
              <span class="keyword">this</span><span class="operator">,</span> SLOT(buttonGroupClicked(<span class="type">int</span>)));
      <span class="type"><a href="qgridlayout.html">QGridLayout</a></span> <span class="operator">*</span>layout <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgridlayout.html">QGridLayout</a></span>;
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(createCellWidget(tr(<span class="string">&quot;Conditional&quot;</span>)<span class="operator">,</span> DiagramItem<span class="operator">::</span>Conditional)<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>);
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(createCellWidget(tr(<span class="string">&quot;Process&quot;</span>)<span class="operator">,</span> DiagramItem<span class="operator">::</span>Step)<span class="operator">,</span><span class="number">0</span><span class="operator">,</span> <span class="number">1</span>);
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(createCellWidget(tr(<span class="string">&quot;Input/Output&quot;</span>)<span class="operator">,</span> DiagramItem<span class="operator">::</span>Io)<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span>);

</pre>
<p>This part of the function sets up the tabbed widget item that contains the flowchart shapes. An exclusive <a href="qbuttongroup.html">QButtonGroup</a> always keeps one button checked; we want the group to allow all buttons to be unchecked. We still use a button group since we can associate user data, which we use to store the diagram type, with each button. The <code>createCellWidget()</code> function sets up the buttons in the tabbed widget item and is examined later.</p>
<p>The buttons of the background tabbed widget item is set up in the same way, so we skip to the creation of the tool box:</p>
<pre class="cpp">

      toolBox <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qtoolbox.html">QToolBox</a></span>;
      toolBox<span class="operator">-</span><span class="operator">&gt;</span>setSizePolicy(<span class="type"><a href="qsizepolicy.html">QSizePolicy</a></span>(<span class="type"><a href="qsizepolicy.html">QSizePolicy</a></span><span class="operator">::</span>Maximum<span class="operator">,</span> <span class="type"><a href="qsizepolicy.html">QSizePolicy</a></span><span class="operator">::</span>Ignored));
      toolBox<span class="operator">-</span><span class="operator">&gt;</span>setMinimumWidth(itemWidget<span class="operator">-</span><span class="operator">&gt;</span>sizeHint()<span class="operator">.</span>width());
      toolBox<span class="operator">-</span><span class="operator">&gt;</span>addItem(itemWidget<span class="operator">,</span> tr(<span class="string">&quot;Basic Flowchart Shapes&quot;</span>));
      toolBox<span class="operator">-</span><span class="operator">&gt;</span>addItem(backgroundWidget<span class="operator">,</span> tr(<span class="string">&quot;Backgrounds&quot;</span>));
  }

</pre>
<p>We set the preferred size of the toolbox as its maximum. This way, more space is given to the graphics view.</p>
<p>Here is the <code>createActions()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>createActions()
  {
      toFrontAction <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(<span class="type"><a href="../qtgui/qicon.html">QIcon</a></span>(<span class="string">&quot;:/images/bringtofront.png&quot;</span>)<span class="operator">,</span>
                                  tr(<span class="string">&quot;Bring to &amp;Front&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
      toFrontAction<span class="operator">-</span><span class="operator">&gt;</span>setShortcut(tr(<span class="string">&quot;Ctrl+F&quot;</span>));
      toFrontAction<span class="operator">-</span><span class="operator">&gt;</span>setStatusTip(tr(<span class="string">&quot;Bring item to front&quot;</span>));
      connect(toFrontAction<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(bringToFront()));

</pre>
<p>We show an example of the creation of an action. The functionality the actions trigger is discussed in the slots we connect the actions to. You can see the <a href="qtwidgets-mainwindows-application-example.html">application example</a> if you need a high-level introduction to actions.</p>
<p>The is the <code>createMenus()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>createMenus()
  {
      fileMenu <span class="operator">=</span> menuBar()<span class="operator">-</span><span class="operator">&gt;</span>addMenu(tr(<span class="string">&quot;&amp;File&quot;</span>));
      fileMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(exitAction);

      itemMenu <span class="operator">=</span> menuBar()<span class="operator">-</span><span class="operator">&gt;</span>addMenu(tr(<span class="string">&quot;&amp;Item&quot;</span>));
      itemMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(deleteAction);
      itemMenu<span class="operator">-</span><span class="operator">&gt;</span>addSeparator();
      itemMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(toFrontAction);
      itemMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(sendBackAction);

      aboutMenu <span class="operator">=</span> menuBar()<span class="operator">-</span><span class="operator">&gt;</span>addMenu(tr(<span class="string">&quot;&amp;Help&quot;</span>));
      aboutMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(aboutAction);
  }

</pre>
<p>We create the three menus' of the example.</p>
<p>The <code>createToolbars()</code> function sets up the examples tool bars. The three <a href="qtoolbutton.html">QToolButton</a>s in the <code>colorToolBar</code>, the <code>fontColorToolButton</code>, <code>fillColorToolButton</code>, and <code>lineColorToolButton</code>, are interesting as we create icons for them by drawing on a <a href="../qtgui/qpixmap.html">QPixmap</a> with a <a href="../qtgui/qpainter.html">QPainter</a>. We show how the <code>fillColorToolButton</code> is created. This button lets the user select a color for the diagram items.</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>createToolbars()
  {
      ...
      fillColorToolButton <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qtoolbutton.html">QToolButton</a></span>;
      fillColorToolButton<span class="operator">-</span><span class="operator">&gt;</span>setPopupMode(<span class="type"><a href="qtoolbutton.html">QToolButton</a></span><span class="operator">::</span>MenuButtonPopup);
      fillColorToolButton<span class="operator">-</span><span class="operator">&gt;</span>setMenu(createColorMenu(SLOT(itemColorChanged())<span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>white));
      fillAction <span class="operator">=</span> fillColorToolButton<span class="operator">-</span><span class="operator">&gt;</span>menu()<span class="operator">-</span><span class="operator">&gt;</span>defaultAction();
      fillColorToolButton<span class="operator">-</span><span class="operator">&gt;</span>setIcon(createColorToolButtonIcon(
                                       <span class="string">&quot;:/images/floodfill.png&quot;</span><span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>white));
      connect(fillColorToolButton<span class="operator">,</span> SIGNAL(clicked())<span class="operator">,</span>
              <span class="keyword">this</span><span class="operator">,</span> SLOT(fillButtonTriggered()));

</pre>
<p>We set the menu of the tool button with <a href="qtoolbutton.html#setMenu">setMenu()</a>. We need the <code>fillAction</code> <a href="qaction.html">QAction</a> object to always be pointing to the selected action of the menu. The menu is created with the <code>createColorMenu()</code> function and, as we shall see later, contains one menu item for each color that the items can have. When the user presses the button, which trigger the <a href="qabstractbutton.html#clicked">clicked()</a> signal, we can set the color of the selected item to the color of <code>fillAction</code>. It is with <code>createColorToolButtonIcon()</code> we create the icon for the button.</p>
<pre class="qml">

      ...
  }

</pre>
<p>Here is the <code>createBackgroundCellWidget()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>MainWindow<span class="operator">::</span>createBackgroundCellWidget(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>text<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>image)
  {
      <span class="type"><a href="qtoolbutton.html">QToolButton</a></span> <span class="operator">*</span>button <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qtoolbutton.html">QToolButton</a></span>;
      button<span class="operator">-</span><span class="operator">&gt;</span>setText(text);
      button<span class="operator">-</span><span class="operator">&gt;</span>setIcon(<span class="type"><a href="../qtgui/qicon.html">QIcon</a></span>(image));
      button<span class="operator">-</span><span class="operator">&gt;</span>setIconSize(<span class="type"><a href="../qtcore/qsize.html">QSize</a></span>(<span class="number">50</span><span class="operator">,</span> <span class="number">50</span>));
      button<span class="operator">-</span><span class="operator">&gt;</span>setCheckable(<span class="keyword">true</span>);
      backgroundButtonGroup<span class="operator">-</span><span class="operator">&gt;</span>addButton(button);

      <span class="type"><a href="qgridlayout.html">QGridLayout</a></span> <span class="operator">*</span>layout <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgridlayout.html">QGridLayout</a></span>;
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(button<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>AlignHCenter);
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(<span class="keyword">new</span> <span class="type"><a href="qlabel.html">QLabel</a></span>(text)<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>AlignCenter);

      <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>widget <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qwidget.html">QWidget</a></span>;
      widget<span class="operator">-</span><span class="operator">&gt;</span>setLayout(layout);

      <span class="keyword">return</span> widget;
  }

</pre>
<p>This function creates <a href="qwidget.html">QWidget</a>s containing a tool button and a label. The widgets created with this function are used for the background tabbed widget item in the tool box.</p>
<p>Here is the <code>createCellWidget()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>MainWindow<span class="operator">::</span>createCellWidget(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>text<span class="operator">,</span> DiagramItem<span class="operator">::</span>DiagramType type)
  {

      DiagramItem item(type<span class="operator">,</span> itemMenu);
      <span class="type"><a href="../qtgui/qicon.html">QIcon</a></span> icon(item<span class="operator">.</span>image());

      <span class="type"><a href="qtoolbutton.html">QToolButton</a></span> <span class="operator">*</span>button <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qtoolbutton.html">QToolButton</a></span>;
      button<span class="operator">-</span><span class="operator">&gt;</span>setIcon(icon);
      button<span class="operator">-</span><span class="operator">&gt;</span>setIconSize(<span class="type"><a href="../qtcore/qsize.html">QSize</a></span>(<span class="number">50</span><span class="operator">,</span> <span class="number">50</span>));
      button<span class="operator">-</span><span class="operator">&gt;</span>setCheckable(<span class="keyword">true</span>);
      buttonGroup<span class="operator">-</span><span class="operator">&gt;</span>addButton(button<span class="operator">,</span> <span class="type">int</span>(type));

      <span class="type"><a href="qgridlayout.html">QGridLayout</a></span> <span class="operator">*</span>layout <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgridlayout.html">QGridLayout</a></span>;
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(button<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>AlignHCenter);
      layout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(<span class="keyword">new</span> <span class="type"><a href="qlabel.html">QLabel</a></span>(text)<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>AlignCenter);

      <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>widget <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qwidget.html">QWidget</a></span>;
      widget<span class="operator">-</span><span class="operator">&gt;</span>setLayout(layout);

      <span class="keyword">return</span> widget;
  }

</pre>
<p>This function returns a <a href="qwidget.html">QWidget</a> containing a <a href="qtoolbutton.html">QToolButton</a> with an image of one of the <code>DiagramItems</code>, i.e&#x2e;, flowchart shapes. The image is created by the <code>DiagramItem</code> through the <code>image()</code> function. The <a href="qbuttongroup.html">QButtonGroup</a> class lets us attach an id (int) with each button; we store the diagram's type, i.e&#x2e;, the DiagramItem::DiagramType enum. We use the stored diagram type when we create new diagram items for the scene. The widgets created with this function is used in the tool box.</p>
<p>Here is the <code>createColorMenu()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>MainWindow<span class="operator">::</span>createColorMenu(<span class="keyword">const</span> <span class="type">char</span> <span class="operator">*</span>slot<span class="operator">,</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> defaultColor)
  {
      <span class="type"><a href="../qtcore/qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="../qtgui/qcolor.html">QColor</a></span><span class="operator">&gt;</span> colors;
      colors <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>black <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>white <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>red <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>blue <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>yellow;
      <span class="type"><a href="../qtcore/qstringlist.html">QStringList</a></span> names;
      names <span class="operator">&lt;</span><span class="operator">&lt;</span> tr(<span class="string">&quot;black&quot;</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> tr(<span class="string">&quot;white&quot;</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> tr(<span class="string">&quot;red&quot;</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> tr(<span class="string">&quot;blue&quot;</span>)
            <span class="operator">&lt;</span><span class="operator">&lt;</span> tr(<span class="string">&quot;yellow&quot;</span>);

      <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>colorMenu <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qmenu.html">QMenu</a></span>(<span class="keyword">this</span>);
      <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator">&lt;</span> colors<span class="operator">.</span>count(); <span class="operator">+</span><span class="operator">+</span>i) {
          <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>action <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(names<span class="operator">.</span>at(i)<span class="operator">,</span> <span class="keyword">this</span>);
          action<span class="operator">-</span><span class="operator">&gt;</span>setData(colors<span class="operator">.</span>at(i));
          action<span class="operator">-</span><span class="operator">&gt;</span>setIcon(createColorIcon(colors<span class="operator">.</span>at(i)));
          connect(action<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> slot);
          colorMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(action);
          <span class="keyword">if</span> (colors<span class="operator">.</span>at(i) <span class="operator">=</span><span class="operator">=</span> defaultColor)
              colorMenu<span class="operator">-</span><span class="operator">&gt;</span>setDefaultAction(action);
      }
      <span class="keyword">return</span> colorMenu;
  }

</pre>
<p>This function creates a color menu that is used as the drop-down menu for the tool buttons in the <code>colorToolBar</code>. We create an action for each color that we add to the menu. We fetch the actions data when we set the color of items, lines, and text.</p>
<p>Here is the <code>createColorToolButtonIcon()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="../qtgui/qicon.html">QIcon</a></span> MainWindow<span class="operator">::</span>createColorToolButtonIcon(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>imageFile<span class="operator">,</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> color)
  {
      <span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span> pixmap(<span class="number">50</span><span class="operator">,</span> <span class="number">80</span>);
      pixmap<span class="operator">.</span>fill(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>transparent);
      <span class="type"><a href="../qtgui/qpainter.html">QPainter</a></span> painter(<span class="operator">&amp;</span>pixmap);
      <span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span> image(imageFile);
      <span class="comment">// Draw icon centred horizontally on button.</span>
      <span class="type"><a href="../qtcore/qrect.html">QRect</a></span> target(<span class="number">4</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">42</span><span class="operator">,</span> <span class="number">43</span>);
      <span class="type"><a href="../qtcore/qrect.html">QRect</a></span> source(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">42</span><span class="operator">,</span> <span class="number">43</span>);
      painter<span class="operator">.</span>fillRect(<span class="type"><a href="../qtcore/qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">60</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">80</span>)<span class="operator">,</span> color);
      painter<span class="operator">.</span>drawPixmap(target<span class="operator">,</span> image<span class="operator">,</span> source);

      <span class="keyword">return</span> <span class="type"><a href="../qtgui/qicon.html">QIcon</a></span>(pixmap);
  }

</pre>
<p>This function is used to create the <a href="../qtgui/qicon.html">QIcon</a> of the <code>fillColorToolButton</code>, <code>fontColorToolButton</code>, and <code>lineColorToolButton</code>. The <i>imageFile</i> string is either the text, flood-fill, or line symbol that is used for the buttons. Beneath the image we draw a filled rectangle using <i>color</i>.</p>
<p>Here is the <code>createColorIcon()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="../qtgui/qicon.html">QIcon</a></span> MainWindow<span class="operator">::</span>createColorIcon(<span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> color)
  {
      <span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span> pixmap(<span class="number">20</span><span class="operator">,</span> <span class="number">20</span>);
      <span class="type"><a href="../qtgui/qpainter.html">QPainter</a></span> painter(<span class="operator">&amp;</span>pixmap);
      painter<span class="operator">.</span>setPen(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>NoPen);
      painter<span class="operator">.</span>fillRect(<span class="type"><a href="../qtcore/qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">20</span><span class="operator">,</span> <span class="number">20</span>)<span class="operator">,</span> color);

      <span class="keyword">return</span> <span class="type"><a href="../qtgui/qicon.html">QIcon</a></span>(pixmap);
  }

</pre>
<p>This function creates an icon with a filled rectangle in the color of <i>color</i>. It is used for creating icons for the color menus in the <code>fillColorToolButton</code>, <code>fontColorToolButton</code>, and <code>lineColorToolButton</code>.</p>
<p>Here is the <code>backgroundButtonGroupClicked()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>backgroundButtonGroupClicked(<span class="type"><a href="qabstractbutton.html">QAbstractButton</a></span> <span class="operator">*</span>button)
  {
      <span class="type"><a href="../qtcore/qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="qabstractbutton.html">QAbstractButton</a></span> <span class="operator">*</span><span class="operator">&gt;</span> buttons <span class="operator">=</span> backgroundButtonGroup<span class="operator">-</span><span class="operator">&gt;</span>buttons();
      foreach (<span class="type"><a href="qabstractbutton.html">QAbstractButton</a></span> <span class="operator">*</span>myButton<span class="operator">,</span> buttons) {
          <span class="keyword">if</span> (myButton <span class="operator">!</span><span class="operator">=</span> button)
              button<span class="operator">-</span><span class="operator">&gt;</span>setChecked(<span class="keyword">false</span>);
      }
      <span class="type"><a href="../qtcore/qstring.html">QString</a></span> text <span class="operator">=</span> button<span class="operator">-</span><span class="operator">&gt;</span>text();
      <span class="keyword">if</span> (text <span class="operator">=</span><span class="operator">=</span> tr(<span class="string">&quot;Blue Grid&quot;</span>))
          scene<span class="operator">-</span><span class="operator">&gt;</span>setBackgroundBrush(<span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span>(<span class="string">&quot;:/images/background1.png&quot;</span>));
      <span class="keyword">else</span> <span class="keyword">if</span> (text <span class="operator">=</span><span class="operator">=</span> tr(<span class="string">&quot;White Grid&quot;</span>))
          scene<span class="operator">-</span><span class="operator">&gt;</span>setBackgroundBrush(<span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span>(<span class="string">&quot;:/images/background2.png&quot;</span>));
      <span class="keyword">else</span> <span class="keyword">if</span> (text <span class="operator">=</span><span class="operator">=</span> tr(<span class="string">&quot;Gray Grid&quot;</span>))
          scene<span class="operator">-</span><span class="operator">&gt;</span>setBackgroundBrush(<span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span>(<span class="string">&quot;:/images/background3.png&quot;</span>));
      <span class="keyword">else</span>
          scene<span class="operator">-</span><span class="operator">&gt;</span>setBackgroundBrush(<span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span>(<span class="string">&quot;:/images/background4.png&quot;</span>));

      scene<span class="operator">-</span><span class="operator">&gt;</span>update();
      view<span class="operator">-</span><span class="operator">&gt;</span>update();
  }

</pre>
<p>In this function we set the <a href="../qtgui/qbrush.html">QBrush</a> that is used to draw the background of the diagramscene. The background can be a grid of squares of blue, gray, or white tiles, or no grid at all. We have <a href="../qtgui/qpixmap.html">QPixmap</a>s of the tiles from png files that we create the brush with.</p>
<p>When one of the buttons in the background tabbed widget item is clicked we change the brush; we find out which button it is by checking its text.</p>
<p>Here is the implementation of <code>buttonGroupClicked()</code>:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>buttonGroupClicked(<span class="type">int</span> id)
  {
      <span class="type"><a href="../qtcore/qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="qabstractbutton.html">QAbstractButton</a></span> <span class="operator">*</span><span class="operator">&gt;</span> buttons <span class="operator">=</span> buttonGroup<span class="operator">-</span><span class="operator">&gt;</span>buttons();
      foreach (<span class="type"><a href="qabstractbutton.html">QAbstractButton</a></span> <span class="operator">*</span>button<span class="operator">,</span> buttons) {
          <span class="keyword">if</span> (buttonGroup<span class="operator">-</span><span class="operator">&gt;</span>button(id) <span class="operator">!</span><span class="operator">=</span> button)
              button<span class="operator">-</span><span class="operator">&gt;</span>setChecked(<span class="keyword">false</span>);
      }
      <span class="keyword">if</span> (id <span class="operator">=</span><span class="operator">=</span> InsertTextButton) {
          scene<span class="operator">-</span><span class="operator">&gt;</span>setMode(DiagramScene<span class="operator">::</span>InsertText);
      } <span class="keyword">else</span> {
          scene<span class="operator">-</span><span class="operator">&gt;</span>setItemType(DiagramItem<span class="operator">::</span>DiagramType(id));
          scene<span class="operator">-</span><span class="operator">&gt;</span>setMode(DiagramScene<span class="operator">::</span>InsertItem);
      }
  }

</pre>
<p>This slot is called when a button in <code>buttonGroup</code> is checked. When a button is checked the user can click on the graphics view and a <code>DiagramItem</code> of the selected type will be inserted into the <code>DiagramScene</code>. We must loop through the buttons in the group to uncheck other buttons as only one button is allowed to be checked at a time.</p>
<p><code>QButtonGroup</code> assigns an id to each button. We have set the id of each button to the diagram type, as given by DiagramItem::DiagramType that will be inserted into the scene when it is clicked. We can then use the button id when we set the diagram type with <code>setItemType()</code>. In the case of text we assigned an id that has a value that is not in the DiagramType enum.</p>
<p>Here is the implementation of <code>deleteItem()</code>:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>deleteItem()
  {
      foreach (<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item<span class="operator">,</span> scene<span class="operator">-</span><span class="operator">&gt;</span>selectedItems()) {
          <span class="keyword">if</span> (item<span class="operator">-</span><span class="operator">&gt;</span>type() <span class="operator">=</span><span class="operator">=</span> Arrow<span class="operator">::</span>Type) {
              scene<span class="operator">-</span><span class="operator">&gt;</span>removeItem(item);
              Arrow <span class="operator">*</span>arrow <span class="operator">=</span> qgraphicsitem_cast<span class="operator">&lt;</span>Arrow <span class="operator">*</span><span class="operator">&gt;</span>(item);
              arrow<span class="operator">-</span><span class="operator">&gt;</span>startItem()<span class="operator">-</span><span class="operator">&gt;</span>removeArrow(arrow);
              arrow<span class="operator">-</span><span class="operator">&gt;</span>endItem()<span class="operator">-</span><span class="operator">&gt;</span>removeArrow(arrow);
              <span class="keyword">delete</span> item;
          }
      }

      foreach (<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item<span class="operator">,</span> scene<span class="operator">-</span><span class="operator">&gt;</span>selectedItems()) {
           <span class="keyword">if</span> (item<span class="operator">-</span><span class="operator">&gt;</span>type() <span class="operator">=</span><span class="operator">=</span> DiagramItem<span class="operator">::</span>Type)
               qgraphicsitem_cast<span class="operator">&lt;</span>DiagramItem <span class="operator">*</span><span class="operator">&gt;</span>(item)<span class="operator">-</span><span class="operator">&gt;</span>removeArrows();
           scene<span class="operator">-</span><span class="operator">&gt;</span>removeItem(item);
           <span class="keyword">delete</span> item;
       }
  }

</pre>
<p>This slot deletes the selected item, if any, from the scene. It deletes the arrows first in order to avoid to delete them twice. If the item to be deleted is a <code>DiagramItem</code>, we also need to delete arrows connected to it; we don't want arrows in the scene that aren't connected to items in both ends.</p>
<p>This is the implementation of pointerGroupClicked():</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>pointerGroupClicked(<span class="type">int</span>)
  {
      scene<span class="operator">-</span><span class="operator">&gt;</span>setMode(DiagramScene<span class="operator">::</span>Mode(pointerTypeGroup<span class="operator">-</span><span class="operator">&gt;</span>checkedId()));
  }

</pre>
<p>The <code>pointerTypeGroup</code> decides whether the scene is in ItemMove or InsertLine mode. This button group is exclusive, i.e&#x2e;, only one button is checked at any time. As with the <code>buttonGroup</code> above we have assigned an id to the buttons that matches values of the DiagramScene::Mode enum, so that we can use the id to set the correct mode.</p>
<p>Here is the <code>bringToFront()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>bringToFront()
  {
      <span class="keyword">if</span> (scene<span class="operator">-</span><span class="operator">&gt;</span>selectedItems()<span class="operator">.</span>isEmpty())
          <span class="keyword">return</span>;

      <span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>selectedItem <span class="operator">=</span> scene<span class="operator">-</span><span class="operator">&gt;</span>selectedItems()<span class="operator">.</span>first();
      <span class="type"><a href="../qtcore/qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span><span class="operator">&gt;</span> overlapItems <span class="operator">=</span> selectedItem<span class="operator">-</span><span class="operator">&gt;</span>collidingItems();

      <span class="type"><a href="../qtcore/qtglobal.html#qreal-typedef">qreal</a></span> zValue <span class="operator">=</span> <span class="number">0</span>;
      foreach (<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item<span class="operator">,</span> overlapItems) {
          <span class="keyword">if</span> (item<span class="operator">-</span><span class="operator">&gt;</span>zValue() <span class="operator">&gt;</span><span class="operator">=</span> zValue <span class="operator">&amp;</span><span class="operator">&amp;</span> item<span class="operator">-</span><span class="operator">&gt;</span>type() <span class="operator">=</span><span class="operator">=</span> DiagramItem<span class="operator">::</span>Type)
              zValue <span class="operator">=</span> item<span class="operator">-</span><span class="operator">&gt;</span>zValue() <span class="operator">+</span> <span class="number">0.1</span>;
      }
      selectedItem<span class="operator">-</span><span class="operator">&gt;</span>setZValue(zValue);
  }

</pre>
<p>Several items may collide, i.e&#x2e;, overlap, with each other in the scene. This slot is called when the user requests that an item should be placed on top of the items it collides with. <a href="qgraphicsitem.html">QGrapicsItems</a> have a z-value that decides the order in which items are stacked in the scene; you can think of it as the z-axis in a 3D coordinate system. When items collide the items with higher z-values will be drawn on top of items with lower values. When we bring an item to the front we can loop through the items it collides with and set a z-value that is higher than all of them.</p>
<p>Here is the <code>sendToBack()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>sendToBack()
  {
      <span class="keyword">if</span> (scene<span class="operator">-</span><span class="operator">&gt;</span>selectedItems()<span class="operator">.</span>isEmpty())
          <span class="keyword">return</span>;

      <span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>selectedItem <span class="operator">=</span> scene<span class="operator">-</span><span class="operator">&gt;</span>selectedItems()<span class="operator">.</span>first();
      <span class="type"><a href="../qtcore/qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span><span class="operator">&gt;</span> overlapItems <span class="operator">=</span> selectedItem<span class="operator">-</span><span class="operator">&gt;</span>collidingItems();

      <span class="type"><a href="../qtcore/qtglobal.html#qreal-typedef">qreal</a></span> zValue <span class="operator">=</span> <span class="number">0</span>;
      foreach (<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item<span class="operator">,</span> overlapItems) {
          <span class="keyword">if</span> (item<span class="operator">-</span><span class="operator">&gt;</span>zValue() <span class="operator">&lt;</span><span class="operator">=</span> zValue <span class="operator">&amp;</span><span class="operator">&amp;</span> item<span class="operator">-</span><span class="operator">&gt;</span>type() <span class="operator">=</span><span class="operator">=</span> DiagramItem<span class="operator">::</span>Type)
              zValue <span class="operator">=</span> item<span class="operator">-</span><span class="operator">&gt;</span>zValue() <span class="operator">-</span> <span class="number">0.1</span>;
      }
      selectedItem<span class="operator">-</span><span class="operator">&gt;</span>setZValue(zValue);
  }

</pre>
<p>This slot works in the same way as <code>bringToFront()</code> described above, but sets a z-value that is lower than items the item that should be send to the back collides with.</p>
<p>This is the implementation of <code>itemInserted()</code>:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>itemInserted(DiagramItem <span class="operator">*</span>item)
  {
      pointerTypeGroup<span class="operator">-</span><span class="operator">&gt;</span>button(<span class="type">int</span>(DiagramScene<span class="operator">::</span>MoveItem))<span class="operator">-</span><span class="operator">&gt;</span>setChecked(<span class="keyword">true</span>);
      scene<span class="operator">-</span><span class="operator">&gt;</span>setMode(DiagramScene<span class="operator">::</span>Mode(pointerTypeGroup<span class="operator">-</span><span class="operator">&gt;</span>checkedId()));
      buttonGroup<span class="operator">-</span><span class="operator">&gt;</span>button(<span class="type">int</span>(item<span class="operator">-</span><span class="operator">&gt;</span>diagramType()))<span class="operator">-</span><span class="operator">&gt;</span>setChecked(<span class="keyword">false</span>);
  }

</pre>
<p>This slot is called from the <code>DiagramScene</code> when an item has been added to the scene. We set the mode of the scene back to the mode before the item was inserted, which is ItemMove or InsertText depending on which button is checked in the <code>pointerTypeGroup</code>. We must also uncheck the button in the in the <code>buttonGroup</code>.</p>
<p>Here is the implementation of <code>textInserted()</code>:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>textInserted(<span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span> <span class="operator">*</span>)
  {
      buttonGroup<span class="operator">-</span><span class="operator">&gt;</span>button(InsertTextButton)<span class="operator">-</span><span class="operator">&gt;</span>setChecked(<span class="keyword">false</span>);
      scene<span class="operator">-</span><span class="operator">&gt;</span>setMode(DiagramScene<span class="operator">::</span>Mode(pointerTypeGroup<span class="operator">-</span><span class="operator">&gt;</span>checkedId()));
  }

</pre>
<p>We simply set the mode of the scene back to the mode it had before the text was inserted.</p>
<p>Here is the <code>currentFontChanged()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>currentFontChanged(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qfont.html">QFont</a></span> <span class="operator">&amp;</span>)
  {
      handleFontChange();
  }

</pre>
<p>When the user requests a font change, by using one of the widgets in the <code>fontToolBar</code>, we create a new <a href="../qtgui/qfont.html">QFont</a> object and set its properties to match the state of the widgets. This is done in <code>handleFontChange()</code>, so we simply call that slot.</p>
<p>Here is the <code>fontSizeChanged()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>fontSizeChanged(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>)
  {
      handleFontChange();
  }

</pre>
<p>When the user requests a font change, by using one of the widgets in the <code>fontToolBar</code>, we create a new <a href="../qtgui/qfont.html">QFont</a> object and set its properties to match the state of the widgets. This is done in <code>handleFontChange()</code>, so we simply call that slot.</p>
<p>Here is the implementation of <code>sceneScaleChanged()</code>:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>sceneScaleChanged(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>scale)
  {
      <span class="type">double</span> newScale <span class="operator">=</span> scale<span class="operator">.</span>left(scale<span class="operator">.</span>indexOf(tr(<span class="string">&quot;%&quot;</span>)))<span class="operator">.</span>toDouble() <span class="operator">/</span> <span class="number">100.0</span>;
      <span class="type"><a href="../qtgui/qmatrix.html">QMatrix</a></span> oldMatrix <span class="operator">=</span> view<span class="operator">-</span><span class="operator">&gt;</span>matrix();
      view<span class="operator">-</span><span class="operator">&gt;</span>resetMatrix();
      view<span class="operator">-</span><span class="operator">&gt;</span>translate(oldMatrix<span class="operator">.</span>dx()<span class="operator">,</span> oldMatrix<span class="operator">.</span>dy());
      view<span class="operator">-</span><span class="operator">&gt;</span>scale(newScale<span class="operator">,</span> newScale);
  }

</pre>
<p>The user can increase or decrease the scale, with the <code>sceneScaleCombo</code>, the scene is drawn in. It is not the scene itself that changes its scale, but only the view.</p>
<p>Here is the <code>textColorChanged()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>textColorChanged()
  {
      textAction <span class="operator">=</span> qobject_cast<span class="operator">&lt;</span><span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span><span class="operator">&gt;</span>(sender());
      fontColorToolButton<span class="operator">-</span><span class="operator">&gt;</span>setIcon(createColorToolButtonIcon(
                                       <span class="string">&quot;:/images/textpointer.png&quot;</span><span class="operator">,</span>
                                       qvariant_cast<span class="operator">&lt;</span><span class="type"><a href="../qtgui/qcolor.html">QColor</a></span><span class="operator">&gt;</span>(textAction<span class="operator">-</span><span class="operator">&gt;</span>data())));
      textButtonTriggered();
  }

</pre>
<p>This slot is called when an item in the drop-down menu of the <code>fontColorToolButton</code> is pressed. We need to change the icon on the button to the color of the selected <a href="qaction.html">QAction</a>. We keep a pointer to the selected action in <code>textAction</code>. It is in <code>textButtonTriggered()</code> we change the text color to the color of <code>textAction</code>, so we call that slot.</p>
<p>Here is the <code>itemColorChanged()</code> implementation:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>itemColorChanged()
  {
      fillAction <span class="operator">=</span> qobject_cast<span class="operator">&lt;</span><span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span><span class="operator">&gt;</span>(sender());
      fillColorToolButton<span class="operator">-</span><span class="operator">&gt;</span>setIcon(createColorToolButtonIcon(
                                       <span class="string">&quot;:/images/floodfill.png&quot;</span><span class="operator">,</span>
                                       qvariant_cast<span class="operator">&lt;</span><span class="type"><a href="../qtgui/qcolor.html">QColor</a></span><span class="operator">&gt;</span>(fillAction<span class="operator">-</span><span class="operator">&gt;</span>data())));
      fillButtonTriggered();
  }

</pre>
<p>This slot handles requests for changing the color of <code>DiagramItems</code> in the same manner as <code>textColorChanged()</code> does for <code>DiagramTextItems</code>.</p>
<p>Here is the implementation of <code>lineColorChanged()</code>:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>lineColorChanged()
  {
      lineAction <span class="operator">=</span> qobject_cast<span class="operator">&lt;</span><span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span><span class="operator">&gt;</span>(sender());
      lineColorToolButton<span class="operator">-</span><span class="operator">&gt;</span>setIcon(createColorToolButtonIcon(
                                       <span class="string">&quot;:/images/linecolor.png&quot;</span><span class="operator">,</span>
                                       qvariant_cast<span class="operator">&lt;</span><span class="type"><a href="../qtgui/qcolor.html">QColor</a></span><span class="operator">&gt;</span>(lineAction<span class="operator">-</span><span class="operator">&gt;</span>data())));
      lineButtonTriggered();
  }

</pre>
<p>This slot handles requests for changing the color of <code>Arrows</code> in the same manner that <code>textColorChanged()</code> does it for <code>DiagramTextItems</code>.</p>
<p>Here is the <code>textButtonTriggered()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>textButtonTriggered()
  {
      scene<span class="operator">-</span><span class="operator">&gt;</span>setTextColor(qvariant_cast<span class="operator">&lt;</span><span class="type"><a href="../qtgui/qcolor.html">QColor</a></span><span class="operator">&gt;</span>(textAction<span class="operator">-</span><span class="operator">&gt;</span>data()));
  }

</pre>
<p><code>textAction</code> points to the <a href="qaction.html">QAction</a> of the currently selected menu item in the <code>fontColorToolButton</code>'s color drop-down menu. We have set the data of the action to the <a href="../qtgui/qcolor.html">QColor</a> the action represents, so we can simply fetch this when we set the color of text with <code>setTextColor()</code>.</p>
<p>Here is the <code>fillButtonTriggered()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>fillButtonTriggered()
  {
      scene<span class="operator">-</span><span class="operator">&gt;</span>setItemColor(qvariant_cast<span class="operator">&lt;</span><span class="type"><a href="../qtgui/qcolor.html">QColor</a></span><span class="operator">&gt;</span>(fillAction<span class="operator">-</span><span class="operator">&gt;</span>data()));
  }

</pre>
<p><code>fillAction</code> points to the selected menu item in the drop-down menu of <code>fillColorToolButton()</code>. We can therefore use the data of this action when we set the item color with <code>setItemColor()</code>.</p>
<p>Here is the <code>lineButtonTriggered()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>lineButtonTriggered()
  {
      scene<span class="operator">-</span><span class="operator">&gt;</span>setLineColor(qvariant_cast<span class="operator">&lt;</span><span class="type"><a href="../qtgui/qcolor.html">QColor</a></span><span class="operator">&gt;</span>(lineAction<span class="operator">-</span><span class="operator">&gt;</span>data()));
  }

</pre>
<p><code>lineAction</code> point to the selected item in the drop-down menu of <code>lineColorToolButton</code>. We use its data when we set the arrow color with <code>setLineColor()</code>.</p>
<p>Here is the <code>handleFontChange()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>handleFontChange()
  {
      <span class="type"><a href="../qtgui/qfont.html">QFont</a></span> font <span class="operator">=</span> fontCombo<span class="operator">-</span><span class="operator">&gt;</span>currentFont();
      font<span class="operator">.</span>setPointSize(fontSizeCombo<span class="operator">-</span><span class="operator">&gt;</span>currentText()<span class="operator">.</span>toInt());
      font<span class="operator">.</span>setWeight(boldAction<span class="operator">-</span><span class="operator">&gt;</span>isChecked() <span class="operator">?</span> <span class="type"><a href="../qtgui/qfont.html">QFont</a></span><span class="operator">::</span>Bold : <span class="type"><a href="../qtgui/qfont.html">QFont</a></span><span class="operator">::</span>Normal);
      font<span class="operator">.</span>setItalic(italicAction<span class="operator">-</span><span class="operator">&gt;</span>isChecked());
      font<span class="operator">.</span>setUnderline(underlineAction<span class="operator">-</span><span class="operator">&gt;</span>isChecked());

      scene<span class="operator">-</span><span class="operator">&gt;</span>setFont(font);
  }

</pre>
<p><code>handleFontChange()</code> is called when any of the widgets that show font properties changes. We create a new <a href="../qtgui/qfont.html">QFont</a> object and set its properties based on the widgets. We then call the <code>setFont()</code> function of <code>DiagramScene</code>; it is the scene that set the font of the <code>DiagramTextItems</code> it manages.</p>
<p>Here is the <code>itemSelected()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>itemSelected(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item)
  {
      DiagramTextItem <span class="operator">*</span>textItem <span class="operator">=</span>
      qgraphicsitem_cast<span class="operator">&lt;</span>DiagramTextItem <span class="operator">*</span><span class="operator">&gt;</span>(item);

      <span class="type"><a href="../qtgui/qfont.html">QFont</a></span> font <span class="operator">=</span> textItem<span class="operator">-</span><span class="operator">&gt;</span>font();
      fontCombo<span class="operator">-</span><span class="operator">&gt;</span>setCurrentFont(font);
      fontSizeCombo<span class="operator">-</span><span class="operator">&gt;</span>setEditText(<span class="type"><a href="../qtcore/qstring.html">QString</a></span>()<span class="operator">.</span>setNum(font<span class="operator">.</span>pointSize()));
      boldAction<span class="operator">-</span><span class="operator">&gt;</span>setChecked(font<span class="operator">.</span>weight() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="../qtgui/qfont.html">QFont</a></span><span class="operator">::</span>Bold);
      italicAction<span class="operator">-</span><span class="operator">&gt;</span>setChecked(font<span class="operator">.</span>italic());
      underlineAction<span class="operator">-</span><span class="operator">&gt;</span>setChecked(font<span class="operator">.</span>underline());
  }

</pre>
<p>This slot is called when an item in the <code>DiagramScene</code> is selected. In the case of this example it is only text items that emit signals when they are selected, so we do not need to check what kind of graphics <i>item</i> is.</p>
<p>We set the state of the widgets to match the properties of the font of the selected text item.</p>
<p>This is the <code>about()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> MainWindow<span class="operator">::</span>about()
  {
      <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>about(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;About Diagram Scene&quot;</span>)<span class="operator">,</span>
                         tr(<span class="string">&quot;The &lt;b&gt;Diagram Scene&lt;/b&gt; example shows &quot;</span>
                            <span class="string">&quot;use of the graphics framework.&quot;</span>));
  }

</pre>
<p>This slot displays an about box for the example when the user selects the about menu item from the help menu.</p>
<a name="diagramscene-class-definition"></a>
<h2 id="diagramscene-class-definition">DiagramScene Class Definition</h2>
<p>The <code>DiagramScene</code> class inherits <a href="qgraphicsscene.html">QGraphicsScene</a> and adds functionality to handle <code>DiagramItems</code>, <code>Arrows</code>, and <code>DiagramTextItems</code> in addition to the items handled by its super class.</p>
<pre class="cpp">

  <span class="keyword">class</span> DiagramScene : <span class="keyword">public</span> <span class="type"><a href="qgraphicsscene.html">QGraphicsScene</a></span>
  {
      Q_OBJECT

  <span class="keyword">public</span>:
      <span class="keyword">enum</span> Mode { InsertItem<span class="operator">,</span> InsertLine<span class="operator">,</span> InsertText<span class="operator">,</span> MoveItem };

      <span class="keyword">explicit</span> DiagramScene(<span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>itemMenu<span class="operator">,</span> <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);
      <span class="type"><a href="../qtgui/qfont.html">QFont</a></span> font() <span class="keyword">const</span> { <span class="keyword">return</span> myFont; }
      <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> textColor() <span class="keyword">const</span> { <span class="keyword">return</span> myTextColor; }
      <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> itemColor() <span class="keyword">const</span> { <span class="keyword">return</span> myItemColor; }
      <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> lineColor() <span class="keyword">const</span> { <span class="keyword">return</span> myLineColor; }
      <span class="type">void</span> setLineColor(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color);
      <span class="type">void</span> setTextColor(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color);
      <span class="type">void</span> setItemColor(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color);
      <span class="type">void</span> setFont(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qfont.html">QFont</a></span> <span class="operator">&amp;</span>font);

  <span class="keyword">public</span> <span class="keyword">slots</span>:
      <span class="type">void</span> setMode(Mode mode);
      <span class="type">void</span> setItemType(DiagramItem<span class="operator">::</span>DiagramType type);
      <span class="type">void</span> editorLostFocus(DiagramTextItem <span class="operator">*</span>item);

  <span class="keyword">signals</span>:
      <span class="type">void</span> itemInserted(DiagramItem <span class="operator">*</span>item);
      <span class="type">void</span> textInserted(<span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span> <span class="operator">*</span>item);
      <span class="type">void</span> itemSelected(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item);

  <span class="keyword">protected</span>:
      <span class="type">void</span> mousePressEvent(<span class="type"><a href="qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>mouseEvent) override;
      <span class="type">void</span> mouseMoveEvent(<span class="type"><a href="qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>mouseEvent) override;
      <span class="type">void</span> mouseReleaseEvent(<span class="type"><a href="qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>mouseEvent) override;

  <span class="keyword">private</span>:
      bool isItemChange(<span class="type">int</span> type);

      DiagramItem<span class="operator">::</span>DiagramType myItemType;
      <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>myItemMenu;
      Mode myMode;
      bool leftButtonDown;
      <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span> startPoint;
      <span class="type"><a href="qgraphicslineitem.html">QGraphicsLineItem</a></span> <span class="operator">*</span>line;
      <span class="type"><a href="../qtgui/qfont.html">QFont</a></span> myFont;
      DiagramTextItem <span class="operator">*</span>textItem;
      <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> myTextColor;
      <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> myItemColor;
      <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> myLineColor;
  };

</pre>
<p>In the <code>DiagramScene</code> a mouse click can give three different actions: the item under the mouse can be moved, an item may be inserted, or an arrow may be connected between to diagram items. Which action a mouse click has depends on the mode, given by the Mode enum, the scene is in. The mode is set with the <code>setMode()</code> function.</p>
<p>The scene also sets the color of its items and the font of its text items. The colors and font used by the scene can be set with the <code>setLineColor()</code>, <code>setTextColor()</code>, <code>setItemColor()</code> and <code>setFont()</code> functions. The type of <code>DiagramItem</code>, given by the DiagramItem::DiagramType function, to be created when an item is inserted is set with the <code>setItemType()</code> slot.</p>
<p>The <code>MainWindow</code> and <code>DiagramScene</code> share responsibility for the examples functionality. <code>MainWindow</code> handles the following tasks: the deletion of items, text, and arrows; moving diagram items to the back and front; and setting the scale of the scene.</p>
<a name="diagramscene-class-implementation"></a>
<h2 id="diagramscene-class-implementation">DiagramScene Class Implementation</h2>
<p>We start with the constructor:</p>
<pre class="cpp">

  DiagramScene<span class="operator">::</span>DiagramScene(<span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>itemMenu<span class="operator">,</span> <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>parent)
      : <span class="type"><a href="qgraphicsscene.html">QGraphicsScene</a></span>(parent)
  {
      myItemMenu <span class="operator">=</span> itemMenu;
      myMode <span class="operator">=</span> MoveItem;
      myItemType <span class="operator">=</span> DiagramItem<span class="operator">::</span>Step;
      line <span class="operator">=</span> <span class="number">0</span>;
      textItem <span class="operator">=</span> <span class="number">0</span>;
      myItemColor <span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>white;
      myTextColor <span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>black;
      myLineColor <span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>black;
  }

</pre>
<p>The scene uses <code>myItemMenu</code> to set the context menu when it creates <code>DiagramItems</code>. We set the default mode to <code>DiagramScene::MoveItem</code> as this gives the default behavior of <a href="qgraphicsscene.html">QGraphicsScene</a>.</p>
<p>Here is the <code>setLineColor()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramScene<span class="operator">::</span>setLineColor(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color)
  {
      myLineColor <span class="operator">=</span> color;
      <span class="keyword">if</span> (isItemChange(Arrow<span class="operator">::</span>Type)) {
          Arrow <span class="operator">*</span>item <span class="operator">=</span> qgraphicsitem_cast<span class="operator">&lt;</span>Arrow <span class="operator">*</span><span class="operator">&gt;</span>(selectedItems()<span class="operator">.</span>first());
          item<span class="operator">-</span><span class="operator">&gt;</span>setColor(myLineColor);
          update();
      }
  }

</pre>
<p>The <code>isItemChange</code> function returns true if an <code>Arrow</code> item is selected in the scene in which case we want to change its color. When the <code>DiagramScene</code> creates and adds new arrows to the scene it will also use the new <i>color</i>.</p>
<p>Here is the <code>setTextColor()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramScene<span class="operator">::</span>setTextColor(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color)
  {
      myTextColor <span class="operator">=</span> color;
      <span class="keyword">if</span> (isItemChange(DiagramTextItem<span class="operator">::</span>Type)) {
          DiagramTextItem <span class="operator">*</span>item <span class="operator">=</span> qgraphicsitem_cast<span class="operator">&lt;</span>DiagramTextItem <span class="operator">*</span><span class="operator">&gt;</span>(selectedItems()<span class="operator">.</span>first());
          item<span class="operator">-</span><span class="operator">&gt;</span>setDefaultTextColor(myTextColor);
      }
  }

</pre>
<p>This function sets the color of <code>DiagramTextItems</code> equal to the way <code>setLineColor()</code> sets the color of <code>Arrows</code>.</p>
<p>Here is the <code>setItemColor()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramScene<span class="operator">::</span>setItemColor(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color)
  {
      myItemColor <span class="operator">=</span> color;
      <span class="keyword">if</span> (isItemChange(DiagramItem<span class="operator">::</span>Type)) {
          DiagramItem <span class="operator">*</span>item <span class="operator">=</span> qgraphicsitem_cast<span class="operator">&lt;</span>DiagramItem <span class="operator">*</span><span class="operator">&gt;</span>(selectedItems()<span class="operator">.</span>first());
          item<span class="operator">-</span><span class="operator">&gt;</span>setBrush(myItemColor);
      }
  }

</pre>
<p>This function sets the color the scene will use when creating <code>DiagramItems</code>. It also changes the color of a selected <code>DiagramItem</code>.</p>
<p>This is the implementation of <code>setFont()</code>:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramScene<span class="operator">::</span>setFont(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qfont.html">QFont</a></span> <span class="operator">&amp;</span>font)
  {
      myFont <span class="operator">=</span> font;

      <span class="keyword">if</span> (isItemChange(DiagramTextItem<span class="operator">::</span>Type)) {
          <span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span> <span class="operator">*</span>item <span class="operator">=</span> qgraphicsitem_cast<span class="operator">&lt;</span>DiagramTextItem <span class="operator">*</span><span class="operator">&gt;</span>(selectedItems()<span class="operator">.</span>first());
          <span class="comment">//At this point the selection can change so the first selected item might not be a DiagramTextItem</span>
          <span class="keyword">if</span> (item)
              item<span class="operator">-</span><span class="operator">&gt;</span>setFont(myFont);
      }
  }

</pre>
<p>Set the font to use for new and selected, if a text item is selected, <code>DiagramTextItems</code>.</p>
<p>This is the implementation of <code>editorLostFocus()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramScene<span class="operator">::</span>editorLostFocus(DiagramTextItem <span class="operator">*</span>item)
  {
      <span class="type"><a href="../qtgui/qtextcursor.html">QTextCursor</a></span> cursor <span class="operator">=</span> item<span class="operator">-</span><span class="operator">&gt;</span>textCursor();
      cursor<span class="operator">.</span>clearSelection();
      item<span class="operator">-</span><span class="operator">&gt;</span>setTextCursor(cursor);

      <span class="keyword">if</span> (item<span class="operator">-</span><span class="operator">&gt;</span>toPlainText()<span class="operator">.</span>isEmpty()) {
          removeItem(item);
          item<span class="operator">-</span><span class="operator">&gt;</span>deleteLater();
      }
  }

</pre>
<p><code>DiagramTextItems</code> emit a signal when they lose focus, which is connected to this slot. We remove the item if it has no text. If not, we would leak memory and confuse the user as the items will be edited when pressed on by the mouse.</p>
<p>The <code>mousePressEvent()</code> function handles mouse press event's different depending on which mode the <code>DiagramScene</code> is in. We examine its implementation for each mode:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramScene<span class="operator">::</span>mousePressEvent(<span class="type"><a href="qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>mouseEvent)
  {
      <span class="keyword">if</span> (mouseEvent<span class="operator">-</span><span class="operator">&gt;</span>button() <span class="operator">!</span><span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>LeftButton)
          <span class="keyword">return</span>;

      DiagramItem <span class="operator">*</span>item;
      <span class="keyword">switch</span> (myMode) {
          <span class="keyword">case</span> InsertItem:
              item <span class="operator">=</span> <span class="keyword">new</span> DiagramItem(myItemType<span class="operator">,</span> myItemMenu);
              item<span class="operator">-</span><span class="operator">&gt;</span>setBrush(myItemColor);
              addItem(item);
              item<span class="operator">-</span><span class="operator">&gt;</span>setPos(mouseEvent<span class="operator">-</span><span class="operator">&gt;</span>scenePos());
              <span class="keyword">emit</span> itemInserted(item);
              <span class="keyword">break</span>;

</pre>
<p>We simply create a new <code>DiagramItem</code> and add it to the scene at the position the mouse was pressed. Note that the origin of its local coordinate system will be under the mouse pointer position.</p>
<pre class="cpp">

          <span class="keyword">case</span> InsertLine:
              line <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgraphicslineitem.html">QGraphicsLineItem</a></span>(<span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span>(mouseEvent<span class="operator">-</span><span class="operator">&gt;</span>scenePos()<span class="operator">,</span>
                                          mouseEvent<span class="operator">-</span><span class="operator">&gt;</span>scenePos()));
              line<span class="operator">-</span><span class="operator">&gt;</span>setPen(<span class="type"><a href="../qtgui/qpen.html">QPen</a></span>(myLineColor<span class="operator">,</span> <span class="number">2</span>));
              addItem(line);
              <span class="keyword">break</span>;

</pre>
<p>The user adds <code>Arrows</code> to the scene by stretching a line between the items the arrow should connect. The start of the line is fixed in the place the user clicked the mouse and the end follows the mouse pointer as long as the button is held down. When the user releases the mouse button an <code>Arrow</code> will be added to the scene if there is a <code>DiagramItem</code> under the start and end of the line. We will see how this is implemented later; here we simply add the line.</p>
<pre class="cpp">

          <span class="keyword">case</span> InsertText:
              textItem <span class="operator">=</span> <span class="keyword">new</span> DiagramTextItem();
              textItem<span class="operator">-</span><span class="operator">&gt;</span>setFont(myFont);
              textItem<span class="operator">-</span><span class="operator">&gt;</span>setTextInteractionFlags(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>TextEditorInteraction);
              textItem<span class="operator">-</span><span class="operator">&gt;</span>setZValue(<span class="number">1000.0</span>);
              connect(textItem<span class="operator">,</span> SIGNAL(lostFocus(DiagramTextItem<span class="operator">*</span>))<span class="operator">,</span>
                      <span class="keyword">this</span><span class="operator">,</span> SLOT(editorLostFocus(DiagramTextItem<span class="operator">*</span>)));
              connect(textItem<span class="operator">,</span> SIGNAL(selectedChange(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">*</span>))<span class="operator">,</span>
                      <span class="keyword">this</span><span class="operator">,</span> SIGNAL(itemSelected(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">*</span>)));
              addItem(textItem);
              textItem<span class="operator">-</span><span class="operator">&gt;</span>setDefaultTextColor(myTextColor);
              textItem<span class="operator">-</span><span class="operator">&gt;</span>setPos(mouseEvent<span class="operator">-</span><span class="operator">&gt;</span>scenePos());
              <span class="keyword">emit</span> textInserted(textItem);

</pre>
<p>The <code>DiagramTextItem</code> is editable when the <a href="../qtcore/qt.html#TextInteractionFlag-enum">Qt::TextEditorInteraction</a> flag is set, else it is movable by the mouse. We always want the text to be drawn on top of the other items in the scene, so we set the value to a number higher than other items in the scene.</p>
<pre class="cpp">

      <span class="keyword">default</span>:
          ;
      }
      <span class="type"><a href="qgraphicsscene.html">QGraphicsScene</a></span><span class="operator">::</span>mousePressEvent(mouseEvent);
  }

</pre>
<p>We are in MoveItem mode if we get to the default switch; we can then call the <a href="qgraphicsscene.html">QGraphicsScene</a> implementation, which handles movement of items with the mouse. We make this call even if we are in another mode making it possible to add an item and then keep the mouse button pressed down and start moving the item. In the case of text items, this is not possible as they do not propagate mouse events when they are editable.</p>
<p>This is the <code>mouseMoveEvent()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramScene<span class="operator">::</span>mouseMoveEvent(<span class="type"><a href="qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>mouseEvent)
  {
      <span class="keyword">if</span> (myMode <span class="operator">=</span><span class="operator">=</span> InsertLine <span class="operator">&amp;</span><span class="operator">&amp;</span> line <span class="operator">!</span><span class="operator">=</span> <span class="number">0</span>) {
          <span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span> newLine(line<span class="operator">-</span><span class="operator">&gt;</span>line()<span class="operator">.</span>p1()<span class="operator">,</span> mouseEvent<span class="operator">-</span><span class="operator">&gt;</span>scenePos());
          line<span class="operator">-</span><span class="operator">&gt;</span>setLine(newLine);
      } <span class="keyword">else</span> <span class="keyword">if</span> (myMode <span class="operator">=</span><span class="operator">=</span> MoveItem) {
          <span class="type"><a href="qgraphicsscene.html">QGraphicsScene</a></span><span class="operator">::</span>mouseMoveEvent(mouseEvent);
      }
  }

</pre>
<p>We must draw the line if we are in InsertMode and the mouse button is pressed down (the line is not 0). As discussed in <code>mousePressEvent()</code> the line is drawn from the position the mouse was pressed to the current position of the mouse.</p>
<p>If we are in MoveItem mode, we call the <a href="qgraphicsscene.html">QGraphicsScene</a> implementation, which handles movement of items.</p>
<p>In the <code>mouseReleaseEvent()</code> function we need to check if an arrow should be added to the scene:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramScene<span class="operator">::</span>mouseReleaseEvent(<span class="type"><a href="qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>mouseEvent)
  {
      <span class="keyword">if</span> (line <span class="operator">!</span><span class="operator">=</span> <span class="number">0</span> <span class="operator">&amp;</span><span class="operator">&amp;</span> myMode <span class="operator">=</span><span class="operator">=</span> InsertLine) {
          <span class="type"><a href="../qtcore/qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span><span class="operator">&gt;</span> startItems <span class="operator">=</span> items(line<span class="operator">-</span><span class="operator">&gt;</span>line()<span class="operator">.</span>p1());
          <span class="keyword">if</span> (startItems<span class="operator">.</span>count() <span class="operator">&amp;</span><span class="operator">&amp;</span> startItems<span class="operator">.</span>first() <span class="operator">=</span><span class="operator">=</span> line)
              startItems<span class="operator">.</span>removeFirst();
          <span class="type"><a href="../qtcore/qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span><span class="operator">&gt;</span> endItems <span class="operator">=</span> items(line<span class="operator">-</span><span class="operator">&gt;</span>line()<span class="operator">.</span>p2());
          <span class="keyword">if</span> (endItems<span class="operator">.</span>count() <span class="operator">&amp;</span><span class="operator">&amp;</span> endItems<span class="operator">.</span>first() <span class="operator">=</span><span class="operator">=</span> line)
              endItems<span class="operator">.</span>removeFirst();

          removeItem(line);
          <span class="keyword">delete</span> line;

</pre>
<p>First we need to get the items (if any) under the line's start and end points. The line itself is the first item at these points, so we remove it from the lists. As a precaution, we check if the lists are empty, but this should never happen.</p>
<pre class="cpp">

          <span class="keyword">if</span> (startItems<span class="operator">.</span>count() <span class="operator">&gt;</span> <span class="number">0</span> <span class="operator">&amp;</span><span class="operator">&amp;</span> endItems<span class="operator">.</span>count() <span class="operator">&gt;</span> <span class="number">0</span> <span class="operator">&amp;</span><span class="operator">&amp;</span>
              startItems<span class="operator">.</span>first()<span class="operator">-</span><span class="operator">&gt;</span>type() <span class="operator">=</span><span class="operator">=</span> DiagramItem<span class="operator">::</span>Type <span class="operator">&amp;</span><span class="operator">&amp;</span>
              endItems<span class="operator">.</span>first()<span class="operator">-</span><span class="operator">&gt;</span>type() <span class="operator">=</span><span class="operator">=</span> DiagramItem<span class="operator">::</span>Type <span class="operator">&amp;</span><span class="operator">&amp;</span>
              startItems<span class="operator">.</span>first() <span class="operator">!</span><span class="operator">=</span> endItems<span class="operator">.</span>first()) {
              DiagramItem <span class="operator">*</span>startItem <span class="operator">=</span> qgraphicsitem_cast<span class="operator">&lt;</span>DiagramItem <span class="operator">*</span><span class="operator">&gt;</span>(startItems<span class="operator">.</span>first());
              DiagramItem <span class="operator">*</span>endItem <span class="operator">=</span> qgraphicsitem_cast<span class="operator">&lt;</span>DiagramItem <span class="operator">*</span><span class="operator">&gt;</span>(endItems<span class="operator">.</span>first());
              Arrow <span class="operator">*</span>arrow <span class="operator">=</span> <span class="keyword">new</span> Arrow(startItem<span class="operator">,</span> endItem);
              arrow<span class="operator">-</span><span class="operator">&gt;</span>setColor(myLineColor);
              startItem<span class="operator">-</span><span class="operator">&gt;</span>addArrow(arrow);
              endItem<span class="operator">-</span><span class="operator">&gt;</span>addArrow(arrow);
              arrow<span class="operator">-</span><span class="operator">&gt;</span>setZValue(<span class="operator">-</span><span class="number">1000.0</span>);
              addItem(arrow);
              arrow<span class="operator">-</span><span class="operator">&gt;</span>updatePosition();
          }
      }

</pre>
<p>Now we check if there are two different <code>DiagramItems</code> under the lines start and end points. If there are we can create an <code>Arrow</code> with the two items. The arrow is then added to each item and finally the scene. The arrow must be updated to adjust its start and end points to the items. We set the z-value of the arrow to -1000.0 because we always want it to be drawn under the items.</p>
<pre class="cpp">

      line <span class="operator">=</span> <span class="number">0</span>;
      <span class="type"><a href="qgraphicsscene.html">QGraphicsScene</a></span><span class="operator">::</span>mouseReleaseEvent(mouseEvent);
  }

</pre>
<p>Here is the <code>isItemChange()</code> function:</p>
<pre class="cpp">

  bool DiagramScene<span class="operator">::</span>isItemChange(<span class="type">int</span> type)
  {
      foreach (<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item<span class="operator">,</span> selectedItems()) {
          <span class="keyword">if</span> (item<span class="operator">-</span><span class="operator">&gt;</span>type() <span class="operator">=</span><span class="operator">=</span> type)
              <span class="keyword">return</span> <span class="keyword">true</span>;
      }
      <span class="keyword">return</span> <span class="keyword">false</span>;
  }

</pre>
<p>The scene has single selection, i.e&#x2e;, only one item can be selected at any given time. The foreach will then loop one time with the selected item or none if no item is selected. <code>isItemChange()</code> is used to check whether a selected item exists and also is of the specified diagram <i>type</i>.</p>
<a name="diagramitem-class-definition"></a>
<h2 id="diagramitem-class-definition">DiagramItem Class Definition</h2>
<pre class="cpp">

  <span class="keyword">class</span> DiagramItem : <span class="keyword">public</span> <span class="type"><a href="qgraphicspolygonitem.html">QGraphicsPolygonItem</a></span>
  {
  <span class="keyword">public</span>:
      <span class="keyword">enum</span> { Type <span class="operator">=</span> UserType <span class="operator">+</span> <span class="number">15</span> };
      <span class="keyword">enum</span> DiagramType { Step<span class="operator">,</span> Conditional<span class="operator">,</span> StartEnd<span class="operator">,</span> Io };

      DiagramItem(DiagramType diagramType<span class="operator">,</span> <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>contextMenu<span class="operator">,</span> <span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);

      <span class="type">void</span> removeArrow(Arrow <span class="operator">*</span>arrow);
      <span class="type">void</span> removeArrows();
      DiagramType diagramType() <span class="keyword">const</span> { <span class="keyword">return</span> myDiagramType; }
      <span class="type"><a href="../qtgui/qpolygonf.html">QPolygonF</a></span> polygon() <span class="keyword">const</span> { <span class="keyword">return</span> myPolygon; }
      <span class="type">void</span> addArrow(Arrow <span class="operator">*</span>arrow);
      <span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span> image() <span class="keyword">const</span>;
      <span class="type">int</span> type() <span class="keyword">const</span> override { <span class="keyword">return</span> Type;}

  <span class="keyword">protected</span>:
      <span class="type">void</span> contextMenuEvent(<span class="type"><a href="qgraphicsscenecontextmenuevent.html">QGraphicsSceneContextMenuEvent</a></span> <span class="operator">*</span>event) override;
      <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> itemChange(GraphicsItemChange change<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> <span class="operator">&amp;</span>value) override;

  <span class="keyword">private</span>:
      DiagramType myDiagramType;
      <span class="type"><a href="../qtgui/qpolygonf.html">QPolygonF</a></span> myPolygon;
      <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>myContextMenu;
      <span class="type"><a href="../qtcore/qlist.html">QList</a></span><span class="operator">&lt;</span>Arrow <span class="operator">*</span><span class="operator">&gt;</span> arrows;
  };

</pre>
<p>The <code>DiagramItem</code> represents a flowchart shape in the <code>DiagramScene</code>. It inherits <a href="qgraphicspolygonitem.html">QGraphicsPolygonItem</a> and has a polygon for each shape. The enum DiagramType has a value for each of the flowchart shapes.</p>
<p>The class has a list of the arrows that are connected to it. This is necessary because only the item knows when it is being moved (with the <code>itemChanged()</code> function) at which time the arrows must be updated. The item can also draw itself onto a <a href="../qtgui/qpixmap.html">QPixmap</a> with the <code>image()</code> function. This is used for the tool buttons in <code>MainWindow</code>, see <code>createColorToolButtonIcon()</code> in <code>MainWindow</code>.</p>
<p>The Type enum is a unique identifier of the class. It is used by <code>qgraphicsitem_cast()</code>, which does dynamic casts of graphics items. The UserType constant is the minimum value a custom graphics item type can be.</p>
<a name="diagramitem-class-implementation"></a>
<h2 id="diagramitem-class-implementation">DiagramItem Class Implementation</h2>
<p>We start with a look at the constructor:</p>
<pre class="cpp">

  DiagramItem<span class="operator">::</span>DiagramItem(DiagramType diagramType<span class="operator">,</span> <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>contextMenu<span class="operator">,</span>
               <span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>parent)
      : <span class="type"><a href="qgraphicspolygonitem.html">QGraphicsPolygonItem</a></span>(parent)
  {
      myDiagramType <span class="operator">=</span> diagramType;
      myContextMenu <span class="operator">=</span> contextMenu;

      <span class="type"><a href="../qtgui/qpainterpath.html">QPainterPath</a></span> path;
      <span class="keyword">switch</span> (myDiagramType) {
          <span class="keyword">case</span> StartEnd:
              path<span class="operator">.</span>moveTo(<span class="number">200</span><span class="operator">,</span> <span class="number">50</span>);
              path<span class="operator">.</span>arcTo(<span class="number">150</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">90</span>);
              path<span class="operator">.</span>arcTo(<span class="number">50</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">90</span><span class="operator">,</span> <span class="number">90</span>);
              path<span class="operator">.</span>arcTo(<span class="number">50</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">180</span><span class="operator">,</span> <span class="number">90</span>);
              path<span class="operator">.</span>arcTo(<span class="number">150</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">50</span><span class="operator">,</span> <span class="number">270</span><span class="operator">,</span> <span class="number">90</span>);
              path<span class="operator">.</span>lineTo(<span class="number">200</span><span class="operator">,</span> <span class="number">25</span>);
              myPolygon <span class="operator">=</span> path<span class="operator">.</span>toFillPolygon();
              <span class="keyword">break</span>;
          <span class="keyword">case</span> Conditional:
              myPolygon <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="operator">-</span><span class="number">100</span><span class="operator">,</span> <span class="number">0</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">100</span>)
                        <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="number">100</span><span class="operator">,</span> <span class="number">0</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="operator">-</span><span class="number">100</span>)
                        <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="operator">-</span><span class="number">100</span><span class="operator">,</span> <span class="number">0</span>);
              <span class="keyword">break</span>;
          <span class="keyword">case</span> Step:
              myPolygon <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="operator">-</span><span class="number">100</span><span class="operator">,</span> <span class="operator">-</span><span class="number">100</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="number">100</span><span class="operator">,</span> <span class="operator">-</span><span class="number">100</span>)
                        <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="number">100</span><span class="operator">,</span> <span class="number">100</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="operator">-</span><span class="number">100</span><span class="operator">,</span> <span class="number">100</span>)
                        <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="operator">-</span><span class="number">100</span><span class="operator">,</span> <span class="operator">-</span><span class="number">100</span>);
              <span class="keyword">break</span>;
          <span class="keyword">default</span>:
              myPolygon <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="operator">-</span><span class="number">120</span><span class="operator">,</span> <span class="operator">-</span><span class="number">80</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="operator">-</span><span class="number">70</span><span class="operator">,</span> <span class="number">80</span>)
                        <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="number">120</span><span class="operator">,</span> <span class="number">80</span>) <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="number">70</span><span class="operator">,</span> <span class="operator">-</span><span class="number">80</span>)
                        <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(<span class="operator">-</span><span class="number">120</span><span class="operator">,</span> <span class="operator">-</span><span class="number">80</span>);
              <span class="keyword">break</span>;
      }
      setPolygon(myPolygon);
      setFlag(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">::</span>ItemIsMovable<span class="operator">,</span> <span class="keyword">true</span>);
      setFlag(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">::</span>ItemIsSelectable<span class="operator">,</span> <span class="keyword">true</span>);
      setFlag(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">::</span>ItemSendsGeometryChanges<span class="operator">,</span> <span class="keyword">true</span>);
  }

</pre>
<p>In the constructor we create the items polygon according to <i>diagramType</i>. <a href="qgraphicsitem.html">QGraphicsItem</a>s are not movable or selectable by default, so we must set these properties.</p>
<p>Here is the <code>removeArrow()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramItem<span class="operator">::</span>removeArrow(Arrow <span class="operator">*</span>arrow)
  {
      <span class="type">int</span> index <span class="operator">=</span> arrows<span class="operator">.</span>indexOf(arrow);

      <span class="keyword">if</span> (index <span class="operator">!</span><span class="operator">=</span> <span class="operator">-</span><span class="number">1</span>)
          arrows<span class="operator">.</span>removeAt(index);
  }

</pre>
<p><code>removeArrow()</code> is used to remove <code>Arrow</code> items when they or <code>DiagramItems</code> they are connected to are removed from the scene.</p>
<p>Here is the <code>removeArrows()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramItem<span class="operator">::</span>removeArrows()
  {
      foreach (Arrow <span class="operator">*</span>arrow<span class="operator">,</span> arrows) {
          arrow<span class="operator">-</span><span class="operator">&gt;</span>startItem()<span class="operator">-</span><span class="operator">&gt;</span>removeArrow(arrow);
          arrow<span class="operator">-</span><span class="operator">&gt;</span>endItem()<span class="operator">-</span><span class="operator">&gt;</span>removeArrow(arrow);
          scene()<span class="operator">-</span><span class="operator">&gt;</span>removeItem(arrow);
          <span class="keyword">delete</span> arrow;
      }
  }

</pre>
<p>This function is called when the item is removed from the scene and removes all arrows that are connected to this item. The arrow must be removed from the <code>arrows</code> list of both its start and end item.</p>
<p>Here is the <code>addArrow()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramItem<span class="operator">::</span>addArrow(Arrow <span class="operator">*</span>arrow)
  {
      arrows<span class="operator">.</span>append(arrow);
  }

</pre>
<p>This function simply adds the <i>arrow</i> to the items <code>arrows</code> list.</p>
<p>Here is the <code>image()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span> DiagramItem<span class="operator">::</span>image() <span class="keyword">const</span>
  {
      <span class="type"><a href="../qtgui/qpixmap.html">QPixmap</a></span> pixmap(<span class="number">250</span><span class="operator">,</span> <span class="number">250</span>);
      pixmap<span class="operator">.</span>fill(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>transparent);
      <span class="type"><a href="../qtgui/qpainter.html">QPainter</a></span> painter(<span class="operator">&amp;</span>pixmap);
      painter<span class="operator">.</span>setPen(<span class="type"><a href="../qtgui/qpen.html">QPen</a></span>(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>black<span class="operator">,</span> <span class="number">8</span>));
      painter<span class="operator">.</span>translate(<span class="number">125</span><span class="operator">,</span> <span class="number">125</span>);
      painter<span class="operator">.</span>drawPolyline(myPolygon);

      <span class="keyword">return</span> pixmap;
  }

</pre>
<p>This function draws the polygon of the item onto a <a href="../qtgui/qpixmap.html">QPixmap</a>. In this example we use this to create icons for the tool buttons in the tool box.</p>
<p>Here is the <code>contextMenuEvent()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramItem<span class="operator">::</span>contextMenuEvent(<span class="type"><a href="qgraphicsscenecontextmenuevent.html">QGraphicsSceneContextMenuEvent</a></span> <span class="operator">*</span>event)
  {
      scene()<span class="operator">-</span><span class="operator">&gt;</span>clearSelection();
      setSelected(<span class="keyword">true</span>);
      myContextMenu<span class="operator">-</span><span class="operator">&gt;</span>exec(event<span class="operator">-</span><span class="operator">&gt;</span>screenPos());
  }

</pre>
<p>We show the context menu. As right mouse clicks, which shows the menu, don't select items by default we set the item selected with <a href="qgraphicsitem.html#setSelected">setSelected()</a>. This is necessary since an item must be selected to change its elevation with the <code>bringToFront</code> and <code>sendToBack</code> actions.</p>
<p>This is the implementation of <code>itemChange()</code>:</p>
<pre class="cpp">

  <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> DiagramItem<span class="operator">::</span>itemChange(GraphicsItemChange change<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> <span class="operator">&amp;</span>value)
  {
      <span class="keyword">if</span> (change <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">::</span>ItemPositionChange) {
          foreach (Arrow <span class="operator">*</span>arrow<span class="operator">,</span> arrows) {
              arrow<span class="operator">-</span><span class="operator">&gt;</span>updatePosition();
          }
      }

      <span class="keyword">return</span> value;
  }

</pre>
<p>If the item has moved, we need to update the positions of the arrows connected to it. The implementation of <a href="qgraphicsitem.html">QGraphicsItem</a> does nothing, so we just return <i>value</i>.</p>
<a name="diagramtextitem-class-definition"></a>
<h2 id="diagramtextitem-class-definition">DiagramTextItem Class Definition</h2>
<p>The <code>TextDiagramItem</code> class inherits <a href="qgraphicstextitem.html">QGraphicsTextItem</a> and adds the possibility to move editable text items. Editable QGraphicsTextItems are designed to be fixed in place and editing starts when the user single clicks on the item. With <code>DiagramTextItem</code> the editing starts with a double click leaving single click available to interact with and move it.</p>
<pre class="cpp">

  <span class="keyword">class</span> DiagramTextItem : <span class="keyword">public</span> <span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span>
  {
      Q_OBJECT

  <span class="keyword">public</span>:
      <span class="keyword">enum</span> { Type <span class="operator">=</span> UserType <span class="operator">+</span> <span class="number">3</span> };

      DiagramTextItem(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);

      <span class="type">int</span> type() <span class="keyword">const</span> override { <span class="keyword">return</span> Type; }

  <span class="keyword">signals</span>:
      <span class="type">void</span> lostFocus(DiagramTextItem <span class="operator">*</span>item);
      <span class="type">void</span> selectedChange(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>item);

  <span class="keyword">protected</span>:
      <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> itemChange(GraphicsItemChange change<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> <span class="operator">&amp;</span>value) override;
      <span class="type">void</span> focusOutEvent(<span class="type"><a href="../qtgui/qfocusevent.html">QFocusEvent</a></span> <span class="operator">*</span>event) override;
      <span class="type">void</span> mouseDoubleClickEvent(<span class="type"><a href="qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event) override;
  };

</pre>
<p>We use <code>itemChange()</code> and <code>focusOutEvent()</code> to notify the <code>DiagramScene</code> when the text item loses focus and gets selected.</p>
<p>We reimplement the functions that handle mouse events to make it possible to alter the mouse behavior of <a href="qgraphicstextitem.html">QGraphicsTextItem</a>.</p>
<a name="diagramtextitem-implementation"></a>
<h2 id="diagramtextitem-implementation">DiagramTextItem Implementation</h2>
<p>We start with the constructor:</p>
<pre class="cpp">

  DiagramTextItem<span class="operator">::</span>DiagramTextItem(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>parent)
      : <span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span>(parent)
  {
      setFlag(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">::</span>ItemIsMovable);
      setFlag(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">::</span>ItemIsSelectable);
  }

</pre>
<p>We simply set the item movable and selectable, as these flags are off by default.</p>
<p>Here is the <code>itemChange()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> DiagramTextItem<span class="operator">::</span>itemChange(GraphicsItemChange change<span class="operator">,</span>
                       <span class="keyword">const</span> <span class="type"><a href="../qtcore/qvariant.html">QVariant</a></span> <span class="operator">&amp;</span>value)
  {
      <span class="keyword">if</span> (change <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">::</span>ItemSelectedHasChanged)
          <span class="keyword">emit</span> selectedChange(<span class="keyword">this</span>);
      <span class="keyword">return</span> value;
  }

</pre>
<p>When the item is selected we emit the selectedChanged signal. The <code>MainWindow</code> uses this signal to update the widgets that display font properties to the font of the selected text item.</p>
<p>Here is the <code>focusOutEvent()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramTextItem<span class="operator">::</span>focusOutEvent(<span class="type"><a href="../qtgui/qfocusevent.html">QFocusEvent</a></span> <span class="operator">*</span>event)
  {
      setTextInteractionFlags(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>NoTextInteraction);
      <span class="keyword">emit</span> lostFocus(<span class="keyword">this</span>);
      <span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span><span class="operator">::</span>focusOutEvent(event);
  }

</pre>
<p><code>DiagramScene</code> uses the signal emitted when the text item loses focus to remove the item if it is empty, i.e&#x2e;, it contains no text.</p>
<p>This is the implementation of <code>mouseDoubleClickEvent()</code>:</p>
<pre class="cpp">

  <span class="type">void</span> DiagramTextItem<span class="operator">::</span>mouseDoubleClickEvent(<span class="type"><a href="qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event)
  {
      <span class="keyword">if</span> (textInteractionFlags() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>NoTextInteraction)
          setTextInteractionFlags(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>TextEditorInteraction);
      <span class="type"><a href="qgraphicstextitem.html">QGraphicsTextItem</a></span><span class="operator">::</span>mouseDoubleClickEvent(event);
  }

</pre>
<p>When we receive a double click event, we make the item editable by calling <a href="qgraphicstextitem.html#setTextInteractionFlags">QGraphicsTextItem::setTextInteractionFlags</a>(). We then forward the double-click to the item itself.</p>
<a name="arrow-class-definition"></a>
<h2 id="arrow-class-definition">Arrow Class Definition</h2>
<p>The <code>Arrow</code> class is a graphics item that connects two <code>DiagramItems</code>. It draws an arrow head to one of the items. To achieve this the item needs to paint itself and also re implement methods used by the graphics scene to check for collisions and selections. The class inherits QGraphicsLine item, and draws the arrowhead and moves with the items it connects.</p>
<pre class="cpp">

  <span class="keyword">class</span> Arrow : <span class="keyword">public</span> <span class="type"><a href="qgraphicslineitem.html">QGraphicsLineItem</a></span>
  {
  <span class="keyword">public</span>:
      <span class="keyword">enum</span> { Type <span class="operator">=</span> UserType <span class="operator">+</span> <span class="number">4</span> };

      Arrow(DiagramItem <span class="operator">*</span>startItem<span class="operator">,</span> DiagramItem <span class="operator">*</span>endItem<span class="operator">,</span>
        <span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);

      <span class="type">int</span> type() <span class="keyword">const</span> override { <span class="keyword">return</span> Type; }
      <span class="type"><a href="../qtcore/qrectf.html">QRectF</a></span> boundingRect() <span class="keyword">const</span> override;
      <span class="type"><a href="../qtgui/qpainterpath.html">QPainterPath</a></span> shape() <span class="keyword">const</span> override;
      <span class="type">void</span> setColor(<span class="keyword">const</span> <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color) { myColor <span class="operator">=</span> color; }
      DiagramItem <span class="operator">*</span>startItem() <span class="keyword">const</span> { <span class="keyword">return</span> myStartItem; }
      DiagramItem <span class="operator">*</span>endItem() <span class="keyword">const</span> { <span class="keyword">return</span> myEndItem; }

      <span class="type">void</span> updatePosition();

  <span class="keyword">protected</span>:
      <span class="type">void</span> paint(<span class="type"><a href="../qtgui/qpainter.html">QPainter</a></span> <span class="operator">*</span>painter<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qstyleoptiongraphicsitem.html">QStyleOptionGraphicsItem</a></span> <span class="operator">*</span>option<span class="operator">,</span> <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>widget <span class="operator">=</span> <span class="number">0</span>) override;

  <span class="keyword">private</span>:
      DiagramItem <span class="operator">*</span>myStartItem;
      DiagramItem <span class="operator">*</span>myEndItem;
      <span class="type"><a href="../qtgui/qcolor.html">QColor</a></span> myColor;
      <span class="type"><a href="../qtgui/qpolygonf.html">QPolygonF</a></span> arrowHead;
  };

</pre>
<p>The item's color can be set with <code>setColor()</code>.</p>
<p><code>boundingRect()</code> and <code>shape()</code> are reimplemented from <a href="qgraphicslineitem.html">QGraphicsLineItem</a> and are used by the scene to check for collisions and selections.</p>
<p>Calling <code>updatePosition()</code> causes the arrow to recalculate its position and arrow head angle. <code>paint()</code> is reimplemented so that we can paint an arrow rather than just a line between items.</p>
<p><code>myStartItem</code> and <code>myEndItem</code> are the diagram items that the arrow connects. The arrow is drawn with its head to the end item. <code>arrowHead</code> is a polygon with three vertices's we use to draw the arrow head.</p>
<a name="arrow-class-implementation"></a>
<h2 id="arrow-class-implementation">Arrow Class Implementation</h2>
<p>The constructor of the <code>Arrow</code> class looks like this:</p>
<pre class="cpp">

  Arrow<span class="operator">::</span>Arrow(DiagramItem <span class="operator">*</span>startItem<span class="operator">,</span> DiagramItem <span class="operator">*</span>endItem<span class="operator">,</span> <span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>parent)
      : <span class="type"><a href="qgraphicslineitem.html">QGraphicsLineItem</a></span>(parent)
  {
      myStartItem <span class="operator">=</span> startItem;
      myEndItem <span class="operator">=</span> endItem;
      setFlag(<span class="type"><a href="qgraphicsitem.html">QGraphicsItem</a></span><span class="operator">::</span>ItemIsSelectable<span class="operator">,</span> <span class="keyword">true</span>);
      myColor <span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>black;
      setPen(<span class="type"><a href="../qtgui/qpen.html">QPen</a></span>(myColor<span class="operator">,</span> <span class="number">2</span><span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>SolidLine<span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>RoundCap<span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>RoundJoin));
  }

</pre>
<p>We set the start and end diagram items of the arrow. The arrow head will be drawn where the line intersects the end item.</p>
<p>Here is the <code>boundingRect()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="../qtcore/qrectf.html">QRectF</a></span> Arrow<span class="operator">::</span>boundingRect() <span class="keyword">const</span>
  {
      <span class="type"><a href="../qtcore/qtglobal.html#qreal-typedef">qreal</a></span> extra <span class="operator">=</span> (pen()<span class="operator">.</span>width() <span class="operator">+</span> <span class="number">20</span>) <span class="operator">/</span> <span class="number">2.0</span>;

      <span class="keyword">return</span> <span class="type"><a href="../qtcore/qrectf.html">QRectF</a></span>(line()<span class="operator">.</span>p1()<span class="operator">,</span> <span class="type"><a href="../qtcore/qsizef.html">QSizeF</a></span>(line()<span class="operator">.</span>p2()<span class="operator">.</span>x() <span class="operator">-</span> line()<span class="operator">.</span>p1()<span class="operator">.</span>x()<span class="operator">,</span>
                                        line()<span class="operator">.</span>p2()<span class="operator">.</span>y() <span class="operator">-</span> line()<span class="operator">.</span>p1()<span class="operator">.</span>y()))
          <span class="operator">.</span>normalized()
          <span class="operator">.</span>adjusted(<span class="operator">-</span>extra<span class="operator">,</span> <span class="operator">-</span>extra<span class="operator">,</span> extra<span class="operator">,</span> extra);
  }

</pre>
<p>We need to reimplement this function because the arrow is larger than the bounding rectangle of the <a href="qgraphicslineitem.html">QGraphicsLineItem</a>. The graphics scene uses the bounding rectangle to know which regions of the scene to update.</p>
<p>Here is the <code>shape()</code> function:</p>
<pre class="cpp">

  <span class="type"><a href="../qtgui/qpainterpath.html">QPainterPath</a></span> Arrow<span class="operator">::</span>shape() <span class="keyword">const</span>
  {
      <span class="type"><a href="../qtgui/qpainterpath.html">QPainterPath</a></span> path <span class="operator">=</span> <span class="type"><a href="qgraphicslineitem.html">QGraphicsLineItem</a></span><span class="operator">::</span>shape();
      path<span class="operator">.</span>addPolygon(arrowHead);
      <span class="keyword">return</span> path;
  }

</pre>
<p>The shape function returns a <a href="../qtgui/qpainterpath.html">QPainterPath</a> that is the exact shape of the item. The <a href="qgraphicslineitem.html#shape">QGraphicsLineItem::shape</a>() returns a path with a line drawn with the current pen, so we only need to add the arrow head. This function is used to check for collisions and selections with the mouse.</p>
<p>Here is the <code>updatePosition()</code> slot:</p>
<pre class="cpp">

  <span class="type">void</span> Arrow<span class="operator">::</span>updatePosition()
  {
      <span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span> line(mapFromItem(myStartItem<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>)<span class="operator">,</span> mapFromItem(myEndItem<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>));
      setLine(line);
  }

</pre>
<p>This slot updates the arrow by setting the start and end points of its line to the center of the items it connects.</p>
<p>Here is the <code>paint()</code> function:</p>
<pre class="cpp">

  <span class="type">void</span> Arrow<span class="operator">::</span>paint(<span class="type"><a href="../qtgui/qpainter.html">QPainter</a></span> <span class="operator">*</span>painter<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qstyleoptiongraphicsitem.html">QStyleOptionGraphicsItem</a></span> <span class="operator">*</span><span class="operator">,</span>
            <span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>)
  {
      <span class="keyword">if</span> (myStartItem<span class="operator">-</span><span class="operator">&gt;</span>collidesWithItem(myEndItem))
          <span class="keyword">return</span>;

      <span class="type"><a href="../qtgui/qpen.html">QPen</a></span> myPen <span class="operator">=</span> pen();
      myPen<span class="operator">.</span>setColor(myColor);
      <span class="type"><a href="../qtcore/qtglobal.html#qreal-typedef">qreal</a></span> arrowSize <span class="operator">=</span> <span class="number">20</span>;
      painter<span class="operator">-</span><span class="operator">&gt;</span>setPen(myPen);
      painter<span class="operator">-</span><span class="operator">&gt;</span>setBrush(myColor);

</pre>
<p>If the start and end items collide we do not draw the arrow; the algorithm we use to find the point the arrow should be drawn at may fail if the items collide.</p>
<p>We first set the pen and brush we will use for drawing the arrow.</p>
<pre class="cpp">

      <span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span> centerLine(myStartItem<span class="operator">-</span><span class="operator">&gt;</span>pos()<span class="operator">,</span> myEndItem<span class="operator">-</span><span class="operator">&gt;</span>pos());
      <span class="type"><a href="../qtgui/qpolygonf.html">QPolygonF</a></span> endPolygon <span class="operator">=</span> myEndItem<span class="operator">-</span><span class="operator">&gt;</span>polygon();
      <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span> p1 <span class="operator">=</span> endPolygon<span class="operator">.</span>first() <span class="operator">+</span> myEndItem<span class="operator">-</span><span class="operator">&gt;</span>pos();
      <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span> p2;
      <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span> intersectPoint;
      <span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span> polyLine;
      <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> <span class="number">1</span>; i <span class="operator">&lt;</span> endPolygon<span class="operator">.</span>count(); <span class="operator">+</span><span class="operator">+</span>i) {
          p2 <span class="operator">=</span> endPolygon<span class="operator">.</span>at(i) <span class="operator">+</span> myEndItem<span class="operator">-</span><span class="operator">&gt;</span>pos();
          polyLine <span class="operator">=</span> <span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span>(p1<span class="operator">,</span> p2);
          <span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span><span class="operator">::</span>IntersectType intersectType <span class="operator">=</span>
              polyLine<span class="operator">.</span>intersect(centerLine<span class="operator">,</span> <span class="operator">&amp;</span>intersectPoint);
          <span class="keyword">if</span> (intersectType <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span><span class="operator">::</span>BoundedIntersection)
              <span class="keyword">break</span>;
          p1 <span class="operator">=</span> p2;
      }

      setLine(<span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span>(intersectPoint<span class="operator">,</span> myStartItem<span class="operator">-</span><span class="operator">&gt;</span>pos()));

</pre>
<p>We then need to find the position at which to draw the arrowhead. The head should be drawn where the line and the end item intersects. This is done by taking the line between each point in the polygon and check if it intersects with the line of the arrow. Since the line start and end points are set to the center of the items the arrow line should intersect one and only one of the lines of the polygon. Note that the points in the polygon are relative to the local coordinate system of the item. We must therefore add the position of the end item to make the coordinates relative to the scene.</p>
<pre class="cpp">

      <span class="type">double</span> angle <span class="operator">=</span> <span class="operator">::</span>acos(line()<span class="operator">.</span>dx() <span class="operator">/</span> line()<span class="operator">.</span>length());
      <span class="keyword">if</span> (line()<span class="operator">.</span>dy() <span class="operator">&gt;</span><span class="operator">=</span> <span class="number">0</span>)
          angle <span class="operator">=</span> (Pi <span class="operator">*</span> <span class="number">2</span>) <span class="operator">-</span> angle;

      <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span> arrowP1 <span class="operator">=</span> line()<span class="operator">.</span>p1() <span class="operator">+</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(sin(angle <span class="operator">+</span> Pi <span class="operator">/</span> <span class="number">3</span>) <span class="operator">*</span> arrowSize<span class="operator">,</span>
                                      cos(angle <span class="operator">+</span> Pi <span class="operator">/</span> <span class="number">3</span>) <span class="operator">*</span> arrowSize);
      <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span> arrowP2 <span class="operator">=</span> line()<span class="operator">.</span>p1() <span class="operator">+</span> <span class="type"><a href="../qtcore/qpointf.html">QPointF</a></span>(sin(angle <span class="operator">+</span> Pi <span class="operator">-</span> Pi <span class="operator">/</span> <span class="number">3</span>) <span class="operator">*</span> arrowSize<span class="operator">,</span>
                                      cos(angle <span class="operator">+</span> Pi <span class="operator">-</span> Pi <span class="operator">/</span> <span class="number">3</span>) <span class="operator">*</span> arrowSize);

      arrowHead<span class="operator">.</span>clear();
      arrowHead <span class="operator">&lt;</span><span class="operator">&lt;</span> line()<span class="operator">.</span>p1() <span class="operator">&lt;</span><span class="operator">&lt;</span> arrowP1 <span class="operator">&lt;</span><span class="operator">&lt;</span> arrowP2;

</pre>
<p>We calculate the angle between the x-axis and the line of the arrow. We need to turn the arrow head to this angle so that it follows the direction of the arrow. If the angle is negative we must turn the direction of the arrow.</p>
<p>We can then calculate the three points of the arrow head polygon. One of the points is the end of the line, which now is the intersection between the arrow line and the end polygon. Then we clear the <code>arrowHead</code> polygon from the previous calculated arrow head and set these new points.</p>
<pre class="cpp">

      painter<span class="operator">-</span><span class="operator">&gt;</span>drawLine(line());
      painter<span class="operator">-</span><span class="operator">&gt;</span>drawPolygon(arrowHead);
      <span class="keyword">if</span> (isSelected()) {
          painter<span class="operator">-</span><span class="operator">&gt;</span>setPen(<span class="type"><a href="../qtgui/qpen.html">QPen</a></span>(myColor<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>DashLine));
          <span class="type"><a href="../qtcore/qlinef.html">QLineF</a></span> myLine <span class="operator">=</span> line();
          myLine<span class="operator">.</span>translate(<span class="number">0</span><span class="operator">,</span> <span class="number">4.0</span>);
          painter<span class="operator">-</span><span class="operator">&gt;</span>drawLine(myLine);
          myLine<span class="operator">.</span>translate(<span class="number">0</span><span class="operator">,</span><span class="operator">-</span><span class="number">8.0</span>);
          painter<span class="operator">-</span><span class="operator">&gt;</span>drawLine(myLine);
      }
  }

</pre>
<p>If the line is selected, we draw two dotted lines that are parallel with the line of the arrow. We do not use the default implementation, which uses <a href="qgraphicsitem.html#boundingRect">boundingRect()</a> because the <a href="../qtcore/qrect.html">QRect</a> bounding rectangle is considerably larger than the line.</p>
<p>Files:</p>
<ul>
<li><a href="qtwidgets-graphicsview-diagramscene-arrow-cpp.html">graphicsview/diagramscene/arrow.cpp</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-arrow-h.html">graphicsview/diagramscene/arrow.h</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-diagramitem-cpp.html">graphicsview/diagramscene/diagramitem.cpp</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-diagramitem-h.html">graphicsview/diagramscene/diagramitem.h</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-diagramscene-cpp.html">graphicsview/diagramscene/diagramscene.cpp</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-diagramscene-h.html">graphicsview/diagramscene/diagramscene.h</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-diagramtextitem-cpp.html">graphicsview/diagramscene/diagramtextitem.cpp</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-diagramtextitem-h.html">graphicsview/diagramscene/diagramtextitem.h</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-mainwindow-cpp.html">graphicsview/diagramscene/mainwindow.cpp</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-mainwindow-h.html">graphicsview/diagramscene/mainwindow.h</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-main-cpp.html">graphicsview/diagramscene/main.cpp</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-diagramscene-pro.html">graphicsview/diagramscene/diagramscene.pro</a></li>
<li><a href="qtwidgets-graphicsview-diagramscene-diagramscene-qrc.html">graphicsview/diagramscene/diagramscene.qrc</a></li>
</ul>
<p>Images:</p>
<ul>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/background1.png">graphicsview/diagramscene/images/background1.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/background2.png">graphicsview/diagramscene/images/background2.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/background3.png">graphicsview/diagramscene/images/background3.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/background4.png">graphicsview/diagramscene/images/background4.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/bold.png">graphicsview/diagramscene/images/bold.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/bringtofront.png">graphicsview/diagramscene/images/bringtofront.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/delete.png">graphicsview/diagramscene/images/delete.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/floodfill.png">graphicsview/diagramscene/images/floodfill.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/italic.png">graphicsview/diagramscene/images/italic.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/linecolor.png">graphicsview/diagramscene/images/linecolor.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/linepointer.png">graphicsview/diagramscene/images/linepointer.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/pointer.png">graphicsview/diagramscene/images/pointer.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/sendtoback.png">graphicsview/diagramscene/images/sendtoback.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/textpointer.png">graphicsview/diagramscene/images/textpointer.png</a></li>
<li><a href="images/used-in-examples/graphicsview/diagramscene/images/underline.png">graphicsview/diagramscene/images/underline.png</a></li>
</ul>
</div>
<!-- @@@graphicsview/diagramscene -->
        </div>
       </div>
   </div>
   </div>
</div>
<div class="footer">
   <p>
   <acronym title="Copyright">&copy;</acronym> 2017 The Qt Company Ltd.
   Documentation contributions included herein are the copyrights of
   their respective owners.<br>    The documentation provided herein is licensed under the terms of the    <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation    License version 1.3</a> as published by the Free Software Foundation.<br>    Qt and respective logos are trademarks of The Qt Company Ltd.     in Finland and/or other countries worldwide. All other trademarks are property
   of their respective owners. </p>
</div>
</body>
</html>