aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quick/tableview/gameoflife/doc/src/gameoflife.qdoc
blob: 069513636a7c400bdad72e1db5412bc8f6a1a0c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
    \title Qt Quick TableView examples - Conway’s Game of Life
    \example tableview/gameoflife
    \brief The \e{Conway’s Game of Life} example shows how the QML TableView
    type can be used to display a C++ model that the user can pan around.

    \image gameoflife.png
    \ingroup qtquickexamples

    \include examples-run.qdocinc

    \section1 The QML User Interface

    \snippet tableview/gameoflife/main.qml tableview
    The example uses the TableView component to display a grid of cells. Each
    of these cells is drawn on the screen by the TableView’s delegate, which is
    a Rectangle QML component. We read the cell’s value and we change it
    using \c{model.value} when the user clicks it.

    \snippet tableview/gameoflife/main.qml scroll
    When the application starts, the TableView is scrolled to its center
    by using its \c{contentX} and \c{contentY} properties to update the scroll
    position, and the \c{contentWidth} and \c{contentHeight} to compute where
    the view should be scrolled to.

    \snippet tableview/gameoflife/main.qml model
    The model that we use is a custom C++ class that we register
    in the QML system:
    \snippet tableview/gameoflife/main.cpp registertype

    \section1 The C++ Model

    \snippet tableview/gameoflife/gameoflifemodel.h modelclass
    The \c{GameOfLifeModel} class extends QAbstractTableModel so it can be
    used as the model of our TableView component. Therefore, it needs to
    implement some functions so the TableView component can interact with
    the model. As you can see in the \c private part of the class, the model
    uses a fixed-size array to store the current state of all the cells.

    \snippet tableview/gameoflife/gameoflifemodel.cpp modelsize
    Here, the \c rowCount and \c columnCount methods are implemented so
    the TableView component can know the size of the table. It simply returns
    the values of the \c width and \c height constants.

    \snippet tableview/gameoflife/gameoflifemodel.cpp read
    This method is called when the TableView component requests some data from
    the model. In our example, we only have one piece of data by cell: whether
    it is alive or not. This information is represented by the \c CellRole value
    of the \c Roles enum in our C++ code; this corresponds to the \c value
    property in the QML code (the link between these two is made by the
    \c{roleNames()} function of our C++ class).

    The \c GameOfLifeModel class can identify which cell was the data requested
    from with the \c index parameter, which is a QModelIndex that contains
    a row and a column.

    \section1 Updating the Data

    \snippet tableview/gameoflife/gameoflifemodel.cpp write
    The \c setData method is called when a property’s value is set from the
    QML interface: in our example, it toggles a cell’s state when it is clicked.
    In the same way as the \c{data()} function does, this method receives an
    \c index and a \c role parameter. Additionally, the new value is passed
    as a QVariant, that we convert to a boolean using the \c toBool function.

    When we update the internal state of our model object, we need to emit a
    \c dataChanged signal to tell the TableView component that it needs to update the
    displayed data. In this case, only the cell that was clicked is affected, thus
    the range of the table that has to be updated begins and ends at the cell’s index.

    \snippet tableview/gameoflife/gameoflifemodel.cpp update
    This function can be called directly from the QML code, because it contains the
    Q_INVOKABLE macro in its definition. It plays an iteration of the game, either when
    the user clicks the \e{Next} button or when the Timer emits a \c{triggered()} signal.

    Following the \e{Conway’s Game of Life} rules, a new state is computed for each
    cell depending on the current state of its neighbors. When the new state has
    been computed for the whole grid, it replaces the current state and a
    \e dataChanged signal is emitted for the whole table.

    \snippet tableview/gameoflife/gameoflifemodel.cpp loader
    When the application opens, a pattern is loaded to demonstrate how
    \e{Conway’s Game of Life} works. These two functions load the file where
    the pattern is stored and parse it. As in the \c nextStep function, a
    \c dataChanged signal is emitted for the whole table once the pattern
    has been fully loaded.
*/