Sophie

Sophie

distrib > Mageia > 6 > x86_64 > media > core-updates > by-pkgid > 2f16506cc8c1194c7e1b9856b534332a > files > 169

qtscxml5-doc-5.9.4-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" />
<!-- sudoku.qdoc -->
  <title>Qt SCXML Sudoku Example | Qt SCXML 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="qtscxml-index.html">Qt SCXML</a></td><td ><a href="examples-qtscxml.html">Qt SCXML Examples</a></td><td >Qt SCXML Sudoku 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="#running-the-example">Running the Example</a></li>
<li class="level1"><a href="#sudoku-features">Sudoku Features</a></li>
<li class="level1"><a href="#scxml-part-internal-logic-description">SCXML Part: Internal Logic Description</a></li>
<li class="level1"><a href="#c-part-constructing-the-gui">C++ Part: Constructing the GUI</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Qt SCXML Sudoku Example</h1>
<span class="subtitle"></span>
<!-- $$$sudoku-description -->
<div class="descr"> <a name="details"></a>
<p><i>Sudoku</i> demonstrates how an SCXML file may be used in a game.</p>
<a name="running-the-example"></a>
<h2 id="running-the-example">Running the Example</h2>
<p>To run the example from Qt Creator, open the <b>Welcome</b> mode and select the example from <b>Examples</b>. For more information, visit Building and Running an Example.</p>
<a name="sudoku-features"></a>
<h2 id="sudoku-features">Sudoku Features</h2>
<p class="centerAlign"><img src="images/sudoku.png" alt="Screenshot of the Sudoku example" /></p><p>Our sudoku contains the following features:</p>
<ul>
<li>Initially and when the game ends, the sudoku enters the <code>idle</code> state. In that state the players can see if their last game finished successfully or not. The state machine is then in one of two child states of the <code>idle</code> state: <code>solved</code> or <code>unsolved</code>, respectively. In the <code>idle</code> state the players can also choose the sudoku grid they would like to solve. The grid is disabled and the user interaction is ignored.</li>
<li>After players click the <b>Start</b> button, the sudoku enters the <code>playing</code> state and is ready for the user interaction on the board.</li>
<li>When the game is in the <code>playing</code> state and the players click the <b>Stop</b> button, the game ends and enters the <code>unsolved</code> child state of the <code>idle</code> state. If the players have solved the current puzzle successfully, the game automatically ends and enters the <code>solved</code> child state of the <code>idle</code> state indicating success.</li>
<li>The board consist of 81 buttons, laid out in a 9x9 grid. The buttons with initial values given remain disabled during the game. The players can only interact with buttons initially empty. Each click on the button increases its value by one.</li>
<li>During the game the <b>Undo</b> button is available for the players' convenience.</li>
</ul>
<a name="scxml-part-internal-logic-description"></a>
<h2 id="scxml-part-internal-logic-description">SCXML Part: Internal Logic Description</h2>
<p>The <i>sudoku.scxml</i> file describes the internal structure of the states the sudoku game can be in, defines the transitions between states, and triggers the appropriate script functions when the transitions take place. It also communicates with the GUI part by sending events and listening to the upcoming events and reacting to them.</p>
<p>We use the ECMAScript data model:</p>
<pre class="qml">

  &lt;scxml xmlns=&quot;http://www.w3.org/2005/07/scxml&quot; version=&quot;1.0&quot;
         name=&quot;Sudoku&quot; datamodel=&quot;ecmascript&quot;&gt;

</pre>
<p>We declare the following variables:</p>
<pre class="qml">

      &lt;datamodel&gt;
          &lt;data id=&quot;initState&quot;/&gt;
          &lt;data id=&quot;currentState&quot; expr=&quot;[[]]&quot;/&gt;
          &lt;data id=&quot;undoStack&quot;/&gt;
      &lt;/datamodel&gt;

</pre>
<div class="table"><table class="generic">
 <thead><tr class="qt-style"><th >Variable</th><th >Description</th></tr></thead>
<tr valign="top" class="odd"><td ><code>initState</code></td><td >Holds the initial state of the current game. It is a two-dimensional array of 9x9 cells that contain initial sudoku numbers. The value of zero means the cell is initially empty.</td></tr>
<tr valign="top" class="even"><td ><code>currentState</code></td><td >Holds the current state of the game being played. It is similar to the <code>initState</code> variable and initially contains the same content. However, when the players start entering the numbers into the empty cells, this variable is being updated accordingly, while the <code>initState</code> variable remains unchanged.</td></tr>
<tr valign="top" class="odd"><td ><code>undoStack</code></td><td >Holds the history of players' moves. It is a vector of the cells' coordinates that were touched last. Each new modification during a game adds a pair of x and y coordinates to that vector.</td></tr>
</table></div>
<p>The variables above are shared with the script helper functions defined in the <code>sudoku.js</code> file:</p>
<pre class="qml">

      &lt;script src=&quot;sudoku.js&quot;/&gt;

</pre>
<p>We call some of the functions defined there when taking transitions or in reaction to the events sent by the GUI.</p>
<p>All the possible states mentioned before are defined in a root state <code>game</code>.</p>
<pre class="qml">

      &lt;state id=&quot;game&quot;&gt;
          &lt;onentry&gt;
              &lt;raise event=&quot;restart&quot;/&gt;
          &lt;/onentry&gt;
          &lt;state id=&quot;idle&quot;&gt;
              ...
              &lt;state id=&quot;unsolved&quot;/&gt;
              &lt;state id=&quot;solved&quot;/&gt;
          &lt;/state&gt;
          &lt;state id=&quot;playing&quot;&gt;
              ...
          &lt;/state&gt;
          ...
      &lt;/state&gt;

</pre>
<p>When the sudoku example is started, the state machine enters the <code>game</code> state and stays in this state until the application exits. When entering this state, we raise internally the <code>restart</code> event. This event is also being raised whenever the players change the current sudoku grid or when they start the game by pressing the <b>Start</b> button. We do not want to send it when they have finished the current game because we still want to show the filled grid from the last game play. So, this event is being raised from three different contexts and is captured internally once in a targetless transition of the <code>game</code> state:</p>
<pre class="qml">

          &lt;transition event=&quot;restart&quot;&gt;
              &lt;script&gt;
                  restart();
              &lt;/script&gt;
              &lt;raise event=&quot;update&quot;/&gt;
          &lt;/transition&gt;

</pre>
<p>When we catch the <code>restart</code> event, we call a helper <code>restart()</code> script method, defined in the <code>sudoku.js</code> file and raise internally an additional <code>update</code> event.</p>
<pre class="qml">

  <span class="keyword">function</span> <span class="name">restart</span>() {
      <span class="keyword">for</span> (<span class="keyword">var</span> <span class="name">i</span> = <span class="number">0</span>; <span class="name">i</span> <span class="operator">&lt;</span> <span class="name">initState</span>.<span class="name">length</span>; i++)
          <span class="name">currentState</span>[<span class="name">i</span>] <span class="operator">=</span> <span class="name">initState</span>[<span class="name">i</span>].<span class="name">slice</span>();
      <span class="name">undoStack</span> <span class="operator">=</span> [];
  }

</pre>
<p>The <code>restart()</code> function assigns the <code>initState</code> into the <code>currentState</code> variable and clears the <code>undoStack</code> variable.</p>
<p>The <code>update</code> event is raised internally whenever we want to notify the GUI that the grid contents have been changed and that the GUI should update itself according to the passed values. This event is caught in another targetless transition of the <code>game</code> state:</p>
<pre class="qml">

          &lt;transition event=&quot;update&quot;&gt;
              &lt;send event=&quot;updateGUI&quot;&gt;
                  &lt;param name=&quot;currentState&quot; expr=&quot;currentState&quot;/&gt;
                  &lt;param name=&quot;initState&quot; expr=&quot;initState&quot;/&gt;
              &lt;/send&gt;
          &lt;/transition&gt;

</pre>
<p>We send the external event <code>updateGUI</code>, which is being intercepted in the <a href="qtscxml-sudoku-example.html#cpp">C++ code</a>. The <code>updateGUI</code> event is equipped with additional data, specified inside <code>&lt;param&gt;</code> elements. We pass two parameters, which are accessible externally through the <code>currentState</code> and <code>initState</code> names. The actual values passed for them equal the datamodel's <code>currentState</code> and <code>initState</code> variables, respectively, which are specified by the <code>expr</code> attributes.</p>
<pre class="qml">

          &lt;state id=&quot;idle&quot;&gt;
              &lt;transition event=&quot;start&quot; target=&quot;playing&quot;/&gt;
              &lt;transition event=&quot;setup&quot; target=&quot;unsolved&quot;&gt;
                  &lt;assign location=&quot;initState&quot; expr=&quot;_event.data.initState&quot;/&gt;
                  &lt;raise event=&quot;restart&quot;/&gt;
              &lt;/transition&gt;
              &lt;state id=&quot;unsolved&quot;/&gt;
              &lt;state id=&quot;solved&quot;/&gt;
          &lt;/state&gt;

</pre>
<p>When in <code>idle</code> state, we react to two events, which may be sent by the GUI part: <code>start</code> and <code>setup</code>. Whenever we receive the <code>start</code> event, we just transition to the <code>playing</code> state. When we receive the <code>setup</code> event, we expect that the GUI part has sent us the new grid to be solved. The grid's new initial state is expected to be passed through the <code>initState</code> field of <code>_event.data</code>. We assign the passed value to the <code>initState</code> variable defined in our datamodel and restart the grid's contents.</p>
<pre class="qml">

          &lt;state id=&quot;playing&quot;&gt;
              &lt;onentry&gt;
                  &lt;raise event=&quot;restart&quot;/&gt;
              &lt;/onentry&gt;
              &lt;transition event=&quot;tap&quot;&gt;
                  &lt;if cond=&quot;isValidPosition()&quot;&gt;
                      &lt;script&gt;
                          calculateCurrentState();
                      &lt;/script&gt;
                      &lt;if cond=&quot;isSolved()&quot;&gt;
                          &lt;raise event=&quot;solved&quot;/&gt;
                      &lt;/if&gt;
                      &lt;raise event=&quot;update&quot;/&gt;
                  &lt;/if&gt;
              &lt;/transition&gt;
              ...
          &lt;/state&gt;

</pre>
<p>Whenever we enter the <code>playing</code> state, we reset the grid's contents since we could have been still showing the contents from the previous game play. In the <code>playing</code> state we react to possible events sent from the GUI: <code>tap</code>, <code>undo</code>, and <code>stop</code>.</p>
<p>The <code>tap</code> event is sent when the players press one of the enabled sudoku cells. This event is expected to contain additional data specifying the cell's coordinates, which are passed through the <code>x</code> and <code>y</code> fields of <code>_event.data</code>. First, we check if the passed coordinates are valid by invoking the <code>isValidPosition()</code> script function:</p>
<pre class="qml">

  <span class="keyword">function</span> <span class="name">isValidPosition</span>() {
      var <span class="name">x</span> = <span class="name">_event</span>.<span class="name">data</span>.<span class="name">x</span>;
      var <span class="name">y</span> = <span class="name">_event</span>.<span class="name">data</span>.<span class="name">y</span>;
      <span class="keyword">if</span> (<span class="name">x</span> <span class="operator">&lt;</span> <span class="number">0</span> <span class="operator">||</span> <span class="name">x</span> <span class="operator">&gt;=</span> <span class="name">initState</span>.<span class="name">length</span>)
          <span class="keyword">return</span> <span class="number">false</span>;
      <span class="keyword">if</span> (<span class="name">y</span> <span class="operator">&lt;</span> <span class="number">0</span> <span class="operator">||</span> <span class="name">y</span> <span class="operator">&gt;=</span> <span class="name">initState</span>.<span class="name">length</span>)
          <span class="keyword">return</span> <span class="number">false</span>;
      <span class="keyword">if</span> (<span class="name">initState</span>[<span class="name">x</span>][<span class="name">y</span>] <span class="operator">!==</span> <span class="number">0</span>)
          <span class="keyword">return</span> <span class="number">false</span>;
      <span class="keyword">return</span> <span class="number">true</span>;
  }

</pre>
<p>We ensure the coordinates are neither negative nor bigger than our grid. In addition, we check if the coordinates point to an initially empty cell, since we can not modify the cells initially given by the grid description.</p>
<p>When we have ensured the passed coordinates are correct, we call <code>calculateCurrentState()</code> script function:</p>
<pre class="qml">

  <span class="keyword">function</span> <span class="name">calculateCurrentState</span>() {
      <span class="keyword">if</span> (<span class="name">isValidPosition</span>() <span class="operator">===</span> <span class="number">false</span>)
          <span class="keyword">return</span>;
      var <span class="name">x</span> = <span class="name">_event</span>.<span class="name">data</span>.<span class="name">x</span>;
      var <span class="name">y</span> = <span class="name">_event</span>.<span class="name">data</span>.<span class="name">y</span>;
      var <span class="name">currentValue</span> = <span class="name">currentState</span>[<span class="name">x</span>][<span class="name">y</span>];
      <span class="keyword">if</span> (<span class="name">currentValue</span> <span class="operator">===</span> <span class="name">initState</span>.<span class="name">length</span>)
          <span class="name">currentValue</span> <span class="operator">=</span> <span class="number">0</span>;
      <span class="keyword">else</span>
          <span class="name">currentValue</span> <span class="operator">+=</span> <span class="number">1</span>;
      <span class="name">currentState</span>[<span class="name">x</span>][<span class="name">y</span>] <span class="operator">=</span> <span class="name">currentValue</span>;
      <span class="name">undoStack</span>.<span class="name">push</span>([<span class="name">x</span>, <span class="name">y</span>]);
  }

</pre>
<p>This function increments the value of the passed grid's cell and adds the new move to the undo stack history.</p>
<p>Right after the <code>calculateCurrentState()</code> function finishes its execution, we check whether the grid is already solved by calling the <code>isSolved()</code> script function:</p>
<pre class="qml">

  <span class="keyword">function</span> <span class="name">isOK</span>(<span class="name">numbers</span>) {
      var <span class="name">temp</span> = [];
      <span class="keyword">for</span> (<span class="keyword">var</span> <span class="name">i</span> = <span class="number">0</span>; <span class="name">i</span> <span class="operator">&lt;</span> <span class="name">numbers</span>.<span class="name">length</span>; i++) {
          var <span class="name">currentValue</span> = <span class="name">numbers</span>[<span class="name">i</span>];
          <span class="keyword">if</span> (<span class="name">currentValue</span> <span class="operator">===</span> <span class="number">0</span>)
              <span class="keyword">return</span> <span class="number">false</span>;
          <span class="keyword">if</span> (<span class="name">temp</span>.<span class="name">indexOf</span>(<span class="name">currentValue</span>) <span class="operator">&gt;=</span> <span class="number">0</span>)
              <span class="keyword">return</span> <span class="number">false</span>;
          <span class="name">temp</span>.<span class="name">push</span>(<span class="name">currentValue</span>);
      }
      <span class="keyword">return</span> <span class="number">true</span>;
  }

  <span class="keyword">function</span> <span class="name">isSolved</span>() {
      <span class="keyword">for</span> (<span class="keyword">var</span> <span class="name">i</span> = <span class="number">0</span>; <span class="name">i</span> <span class="operator">&lt;</span> <span class="name">currentState</span>.<span class="name">length</span>; i++) {
          <span class="keyword">if</span> (!<span class="name">isOK</span>(<span class="name">currentState</span>[<span class="name">i</span>]))
              <span class="keyword">return</span> <span class="number">false</span>;

          var <span class="name">column</span> = [];
          var <span class="name">square</span> = [];
          <span class="keyword">for</span> (<span class="keyword">var</span> <span class="name">j</span> = <span class="number">0</span>; <span class="name">j</span> <span class="operator">&lt;</span> <span class="name">currentState</span>[<span class="name">i</span>].<span class="name">length</span>; j++) {
              <span class="name">column</span>.<span class="name">push</span>(<span class="name">currentState</span>[<span class="name">j</span>][<span class="name">i</span>]);
              <span class="name">square</span>.<span class="name">push</span>(<span class="name">currentState</span>[<span class="name">Math</span>.<span class="name">floor</span>(<span class="name">i</span> <span class="operator">/</span> <span class="number">3</span>) <span class="operator">*</span> <span class="number">3</span> <span class="operator">+</span> <span class="name">Math</span>.<span class="name">floor</span>(<span class="name">j</span> <span class="operator">/</span> <span class="number">3</span>)]
                                      [<span class="name">i</span> <span class="operator">%</span> <span class="number">3</span> <span class="operator">*</span> <span class="number">3</span> <span class="operator">+</span> <span class="name">j</span> <span class="operator">%</span> <span class="number">3</span>]);
          }

          <span class="keyword">if</span> (!<span class="name">isOK</span>(<span class="name">column</span>))
              <span class="keyword">return</span> <span class="number">false</span>;
          <span class="keyword">if</span> (!<span class="name">isOK</span>(<span class="name">square</span>))
              <span class="keyword">return</span> <span class="number">false</span>;
      }
      <span class="keyword">return</span> <span class="number">true</span>;
  }

</pre>
<p>The <code>isSolved()</code> function returns <code>true</code> if the grid is properly solved. Since we need to check each row, each column, and each 3x3 square, we define the <code>isOK()</code> helper function. This function takes the vector of numbers and returns <code>true</code> if the passed vector contains unique numbers and no number equals zero, meaning there is no empty cell. The main loop of the <code>isSolved()</code> is invoked nine times. In every iteration, we construct three vectors of numbers representing a row, a column, and a square of the grid and call <code>isOK()</code> for them. When all 27 vectors are OK, the grid is solved properly and we return <code>true</code>.</p>
<p>Coming back to our SCXML file, in case <code>isSolved()</code> returns <code>true</code>, we raise the <code>solved</code> event internally. The last instruction in case of a proper move is to raise the <code>update</code> event, since we need to notify the GUI about the grid's change.</p>
<pre class="qml">

          &lt;state id=&quot;playing&quot;&gt;
              ...
              &lt;transition event=&quot;undo&quot;&gt;
                  &lt;script&gt;
                      undo();
                  &lt;/script&gt;
                  &lt;raise event=&quot;update&quot;/&gt;
              &lt;/transition&gt;
              &lt;transition event=&quot;stop&quot; target=&quot;idle&quot;/&gt;
              &lt;transition event=&quot;solved&quot; target=&quot;solved&quot;/&gt;
          &lt;/state&gt;

</pre>
<p>When in the <code>playing</code> state, we also react to the <code>undo</code> event sent from the GUI. In this case, we call the <code>undo()</code> script function and notify the GUI about the need of an update.</p>
<pre class="qml">

  <span class="keyword">function</span> <span class="name">undo</span>() {
      <span class="keyword">if</span> (!<span class="name">undoStack</span>.<span class="name">length</span>)
          <span class="keyword">return</span>;

      var <span class="name">lastMove</span> = <span class="name">undoStack</span>.<span class="name">pop</span>();
      var <span class="name">x</span> = <span class="name">lastMove</span>[<span class="number">0</span>];
      var <span class="name">y</span> = <span class="name">lastMove</span>[<span class="number">1</span>];
      var <span class="name">currentValue</span> = <span class="name">currentState</span>[<span class="name">x</span>][<span class="name">y</span>];
      <span class="keyword">if</span> (<span class="name">currentValue</span> <span class="operator">===</span> <span class="number">0</span>)
          <span class="name">currentValue</span> <span class="operator">=</span> <span class="name">initState</span>.<span class="name">length</span>;
      <span class="keyword">else</span>
          <span class="name">currentValue</span> <span class="operator">-=</span> <span class="number">1</span>;
      <span class="name">currentState</span>[<span class="name">x</span>][<span class="name">y</span>] <span class="operator">=</span> <span class="name">currentValue</span>;
  }

</pre>
<p>The <code>undo()</code> function removes the last move from the history, if there was any, and decrements the current value for the cell described by the coordinates taken from this move.</p>
<p>The <code>playing</code> state is also ready for the <code>stop</code> event sent by the GUI when the players press the <b>Stop</b> button. In this case, we simply activate the <code>idle</code> state.</p>
<p>In addition, we intercept the <code>solved</code> event sent internally and activate the <code>solved</code> state in this case.</p>
<a name="cpp"></a><a name="c-part-constructing-the-gui"></a>
<h2 id="c-part-constructing-the-gui">C++ Part: Constructing the GUI</h2>
<p>The C++ part of the application consists of a <code>MainWindow</code> class which constructs the GUI and glues it with the SCXML part. The class is declared in <i>mainwindow.h</i>.</p>
<pre class="qml">

  <span class="keyword">class</span> MainWindow : <span class="keyword">public</span> <span class="type">QWidget</span>
  {
      Q_OBJECT

  <span class="keyword">public</span>:
      <span class="keyword">explicit</span> MainWindow(<span class="type"><a href="qscxmlstatemachine.html">QScxmlStateMachine</a></span> <span class="operator">*</span>machine<span class="operator">,</span> <span class="type">QWidget</span> <span class="operator">*</span>parent <span class="operator">=</span> nullptr);
      <span class="operator">~</span>MainWindow();

  <span class="keyword">private</span>:
      <span class="type"><a href="qscxmlstatemachine.html">QScxmlStateMachine</a></span> <span class="operator">*</span>m_machine;
      <span class="type">QVector</span><span class="operator">&lt;</span><span class="type">QVector</span><span class="operator">&lt;</span><span class="type">QToolButton</span> <span class="operator">*</span><span class="operator">&gt;</span> <span class="operator">&gt;</span> m_buttons;
      <span class="type">QToolButton</span> <span class="operator">*</span>m_startButton;
      <span class="type">QToolButton</span> <span class="operator">*</span>m_undoButton;
      <span class="type">QLabel</span> <span class="operator">*</span>m_label;
      <span class="type">QComboBox</span> <span class="operator">*</span>m_chooser;
  };

</pre>
<p>The <code>MainWindow</code> class holds the pointer to the <code>QScxmlStateMachine *m_machine</code>, which is the state machine class automatically generated by Qt out of the <code>sudoku.scxml</code> file. It also holds the pointers to some GUI elements.</p>
<pre class="qml">

  MainWindow<span class="operator">::</span>MainWindow(<span class="type"><a href="qscxmlstatemachine.html">QScxmlStateMachine</a></span> <span class="operator">*</span>machine<span class="operator">,</span> <span class="type">QWidget</span> <span class="operator">*</span>parent) :
      <span class="type">QWidget</span>(parent)<span class="operator">,</span>
      m_machine(machine)
  {

</pre>
<p>The constructor of the <code>MainWindow</code> class instantiates the GUI part of the application and stores the pointer to the passed state machine. It also initializes the GUI part and glues the GUI part to the state machine by connecting their communication interfaces together.</p>
<pre class="qml">

              connect(button<span class="operator">,</span> <span class="operator">&amp;</span><span class="type">QToolButton</span><span class="operator">::</span>clicked<span class="operator">,</span> <span class="operator">[</span><span class="keyword">this</span><span class="operator">,</span> i<span class="operator">,</span> j<span class="operator">]</span> () {
                  <span class="type">QVariantMap</span> data;
                  data<span class="operator">.</span>insert(<span class="type">QStringLiteral</span>(<span class="string">&quot;x&quot;</span>)<span class="operator">,</span> i);
                  data<span class="operator">.</span>insert(<span class="type">QStringLiteral</span>(<span class="string">&quot;y&quot;</span>)<span class="operator">,</span> j);
                  m_machine<span class="operator">-</span><span class="operator">&gt;</span>submitEvent(<span class="string">&quot;tap&quot;</span><span class="operator">,</span> data);
              });

</pre>
<p>First, we create 81 buttons and connect their <code>clicked</code> signal to a lambda expression that submits the <code>tap</code> event to the state machine passing the button's coordinates.</p>
<p>Later, we add some horizontal and vertical lines to the grid in order to group buttons in 3x3 boxes.</p>
<pre class="qml">

      connect(m_startButton<span class="operator">,</span> <span class="operator">&amp;</span><span class="type">QAbstractButton</span><span class="operator">::</span>clicked<span class="operator">,</span>
              <span class="operator">[</span><span class="keyword">this</span><span class="operator">]</span> {
          <span class="keyword">if</span> (m_machine<span class="operator">-</span><span class="operator">&gt;</span>isActive(<span class="string">&quot;playing&quot;</span>))
              m_machine<span class="operator">-</span><span class="operator">&gt;</span>submitEvent(<span class="string">&quot;stop&quot;</span>);
          <span class="keyword">else</span>
              m_machine<span class="operator">-</span><span class="operator">&gt;</span>submitEvent(<span class="string">&quot;start&quot;</span>);
      });

</pre>
<p>We create the <b>Start / Stop</b> button and connect its clicked signal to a lambda expression which submits the <code>stop</code> or <code>start</code> event depending on whether the machine is in <code>playing</code> state or not, respectively.</p>
<p>We create a label informing whether the grid is solved or not, and an <b>Undo</b> button, which submits the <code>undo</code> event whenever it is clicked.</p>
<pre class="qml">

      connect(m_undoButton<span class="operator">,</span> <span class="operator">&amp;</span><span class="type">QAbstractButton</span><span class="operator">::</span>clicked<span class="operator">,</span>
              <span class="operator">[</span><span class="keyword">this</span><span class="operator">]</span> {
          m_machine<span class="operator">-</span><span class="operator">&gt;</span>submitEvent(<span class="string">&quot;undo&quot;</span>);
      });

</pre>
<p>Then we create a combobox that is filled with grid names to be solved. These grids are read from the <code>:/data</code> directory of the application compiled-in resources.</p>
<pre class="qml">

      connect(m_chooser<span class="operator">,</span> <span class="type">QOverload</span><span class="operator">&lt;</span><span class="type">int</span><span class="operator">&gt;</span><span class="operator">::</span>of(<span class="operator">&amp;</span><span class="type">QComboBox</span><span class="operator">::</span>currentIndexChanged)<span class="operator">,</span>
              <span class="operator">[</span><span class="keyword">this</span><span class="operator">]</span> (<span class="type">int</span> index) {
          <span class="keyword">const</span> <span class="type">QString</span> sudokuFile <span class="operator">=</span> m_chooser<span class="operator">-</span><span class="operator">&gt;</span>itemData(index)<span class="operator">.</span>toString();
          <span class="keyword">const</span> <span class="type">QVariantMap</span> initValues <span class="operator">=</span> readSudoku(sudokuFile);
          m_machine<span class="operator">-</span><span class="operator">&gt;</span>submitEvent(<span class="string">&quot;setup&quot;</span><span class="operator">,</span> initValues);
      });

      <span class="keyword">const</span> <span class="type">QVariantMap</span> initValues <span class="operator">=</span> readSudoku(m_chooser<span class="operator">-</span><span class="operator">&gt;</span>itemData(<span class="number">0</span>)<span class="operator">.</span>toString());
      m_machine<span class="operator">-</span><span class="operator">&gt;</span>setInitialValues(initValues);

</pre>
<p>Whenever the players change the grid in the combobox, we read the grid contents storing it in the variant map under the <code>initValues</code> key as a list of lists of int variants and we submit the <code>setup</code> event to the state machine passing the grid's contents. Initially, we read the first available grid from the list and pass it directly to the sudoku state machine as the initial grid.</p>
<pre class="qml">

      m_machine<span class="operator">-</span><span class="operator">&gt;</span>connectToState(<span class="string">&quot;playing&quot;</span><span class="operator">,</span> <span class="operator">[</span><span class="keyword">this</span><span class="operator">]</span> (bool playing) {
          ...
      });

      m_machine<span class="operator">-</span><span class="operator">&gt;</span>connectToState(<span class="string">&quot;solved&quot;</span><span class="operator">,</span> <span class="operator">[</span><span class="keyword">this</span><span class="operator">]</span> (bool solved) {
          <span class="keyword">if</span> (solved)
              m_label<span class="operator">-</span><span class="operator">&gt;</span>setText(tr(<span class="string">&quot;SOLVED !!!&quot;</span>));
          <span class="keyword">else</span>
              m_label<span class="operator">-</span><span class="operator">&gt;</span>setText(tr(<span class="string">&quot;unsolved&quot;</span>));
      });

      m_machine<span class="operator">-</span><span class="operator">&gt;</span>connectToEvent(<span class="string">&quot;updateGUI&quot;</span><span class="operator">,</span> <span class="operator">[</span><span class="keyword">this</span><span class="operator">]</span> (<span class="keyword">const</span> <span class="type"><a href="qscxmlevent.html">QScxmlEvent</a></span> <span class="operator">&amp;</span>event) {
          ...
      });

</pre>
<p>Later, we connect to the signals that are being sent whenever the machine enters or leaves the <code>playing</code> or <code>solved</code> states, and we update some GUI parts accordingly. We also connect to the state machine's <code>updateGUI</code> event and update all the buttons' values according to the passed cells' states.</p>
<pre class="qml">

  <span class="preprocessor">#include &quot;sudoku.h&quot;</span>
  <span class="preprocessor">#include &quot;mainwindow.h&quot;</span>

  <span class="preprocessor">#include &lt;QApplication&gt;</span>

  <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span><span class="operator">*</span>argv)
  {
      <span class="type">QApplication</span> app(argc<span class="operator">,</span> argv);

      Sudoku machine;
      MainWindow mainWindow(<span class="operator">&amp;</span>machine);

      machine<span class="operator">.</span>start();
      mainWindow<span class="operator">.</span>show();
      <span class="keyword">return</span> app<span class="operator">.</span>exec();
  }

</pre>
<p>In the <code>main()</code> function in the <code>main.cpp</code> file, we instantiate the <code>app</code> application object, <code>Sudoku</code> state machine, and <code>MainWindow</code> GUI class. We start the state machine, show the main window, and execute the application.</p>
<p>Files:</p>
<ul>
<li><a href="qtscxml-sudoku-mainwindow-cpp.html">sudoku/mainwindow.cpp</a></li>
<li><a href="qtscxml-sudoku-mainwindow-h.html">sudoku/mainwindow.h</a></li>
<li><a href="qtscxml-sudoku-sudoku-cpp.html">sudoku/sudoku.cpp</a></li>
<li><a href="qtscxml-sudoku-sudoku-h.html">sudoku/sudoku.h</a></li>
<li><a href="qtscxml-sudoku-sudoku-js.html">sudoku/sudoku.js</a></li>
<li><a href="qtscxml-sudoku-sudoku-scxml.html">sudoku/sudoku.scxml</a></li>
<li><a href="qtscxml-sudoku-main-cpp.html">sudoku/main.cpp</a></li>
<li><a href="qtscxml-sudoku-sudoku-pro.html">sudoku/sudoku.pro</a></li>
<li><a href="qtscxml-sudoku-sudoku-qrc.html">sudoku/sudoku.qrc</a></li>
</ul>
</div>
<!-- @@@sudoku -->
        </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>