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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
|
..
---------------------------------------------------------------------------
Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
All rights reserved.
This work, unless otherwise expressly stated, is licensed under a
Creative Commons Attribution-ShareAlike 2.5.
The full license document is available from
http://creativecommons.org/licenses/by-sa/2.5/legalcode .
---------------------------------------------------------------------------
Create and Manage Note Items
============================
The user should be able to create and delete notes on the fly and this means that our code should be able to dynamically create and delete Note* items. There are several ways to create and manage QML objects. In fact, we have seen one already using the :qt5:`Repeater <qtquick/qml-qtquick2-repeater.html>` type. Creating a QML object means that the component has to be created and loaded before creating instances of that component.
QML objects can be created by calling the :qt5:`createObject(Item parent, object properties) <qtqml/qml-qtquick2-component.html#createObject-method>` JavaScript function on the component. Refer to :qt5:`Dynamic Object Management in QML <qtqml/qtqml-javascript-dynamicobjectcreation.html>` for further details.
Let's see how we can create note item objects in our components.
Note Object Creation Dynamically
--------------------------------
We know that a `Note` item belongs to the `Page` component, which is responsible for the note object creation as well as to loading notes from the database.
As mentioned before, we first load the `Note` component in the `Page` component:
.. code-block:: js
// Page.qml
...
// loading the Note Component
Component {
id: noteComponent
Note { }
}
...
Now let's define a Javascript function that will create QML `Note` objects. While creating a QML object, we must ensure that one of the arguments is the parent of the `this` object. Considering to have a `Note` item container within the `Page` component would be a good idea for managing our note objects, as we would like to save these notes in a database.
.. code-block:: js
// Page.qml
...
// creating an Item element that will be used as a note container
Item { id: container }
...
// a Javascript helper function for creating QML Note objects
function newNoteObject(args) {
// calling the createObject() function on noteComponent item
// and the container item will be the parent of the new
// object and args as the set of arguments
var note = noteComponent.createObject(container, args)
if(note == null) {
console.log("note object failed to be created!")
}
}
...
So in the code shown above, we see how a new note* item object can be created in the *newNoteObject()* function. The newly created note objects will belong to the *container* item.
Now we would like to call this function when the new note* tool is pressed on the toolbar, which is created in the `main.qml` file. As the `PagePanel` component is aware of the current visible *page* item, we can create a new property in `PagePanel` to store that page.
We will access this property in the `main.qml` file and call the function to create new note items.
.. code-block:: js
// PagePanel.qml
...
// this property holds the current visible page
property Page currentPage: personalpage
// creating the list of states
states: [
// creating a State item with its corresponding name
State {
name: "personal"
PropertyChanges {
target: personalpage
opacity:1.0
restoreEntryValues: true
}
PropertyChanges {
target: root
currentPage: personalpage
explicit: true
}
},
State {
name: "fun"
PropertyChanges {
target: funpage
opacity:1.0
restoreEntryValues: true
}
PropertyChanges {
target: root
currentPage: funpage
explicit: true
}
},
State {
name: "work"
PropertyChanges {
target: workpage
opacity:1.0
restoreEntryValues: true
}
PropertyChanges {
target: root
currentPage: workpage
explicit: true
}
}
]
...
We modify our three states for setting the appropriate value for the `currentPage` property.
In the `main.qml` file, let's see how to call the function for creating new note objects when the new note* tool is clicked:
.. code-block:: js
// main.qml
...
// using a Column element to layout the Tool items vertically
Column {
id: toolbar
spacing: 16
anchors {
top: window.top; left: window.left; bottom: window.bottom;
topMargin: 50; bottomMargin: 50; leftMargin: 8
}
// the new note tool, also known as the plus icon
Tool {
id: newNoteTool
source: "images/add.png"
// using the currentPage property of PagePanel and
// calling newNoteObject() function without any arguments.
onClicked: pagePanel.currentPage.newNoteObject()
}
}
...
Deleting Note Objects
---------------------
Deleting the `Note` objects is a more straightforward process because the QML :qt5:`Item <qtquick/qml-qtquick2-item.html>` type provides a JavaScript function called :qt5:`destroy() <qtqml/qtqml-javascript-dynamicobjectcreation.html#deleting-objects-dynamically>`. As we already have a container item whose children are `Note` items, we can simply iterate through the list of children and call :qt5:`destroy() <qtqml/qtqml-javascript-dynamicobjectcreation.html#deleting-objects-dynamically>` on each of them.
In the `Page` component, let's define a function to perform this operation for us:
.. code-block:: js
// Page.qml
...
// a JavaScript helper function for iterating through the children elements of the
// container item and calls destroy() for deleting them
function clear() {
for(var i=0; i<container.children.length; ++i) {
container.children[i].destroy()
}
}
...
In the `main.qml` file, we call the `clear()` function when the `clear` tool is pressed:
.. code-block:: js
// main.qml
...
// the `clear` tool
Tool {
id: clearAllTool
source: "images/clear.png"
onClicked: pagePanel.currentPage.clear()
}
...
In order to allow the user to delete each note individually, we add a tool in the `NoteToolbar` component to our `Note` component. We can use the `Tool` component that was implemented earlier for this:
.. code-block:: js
// Note.qml
...
// creating a NoteToolbar item that will be anchored to its parent
NoteToolbar {
id: toolbar
height: 40
anchors { top: root.top; left: root.left; right: root.right }
// using the drag property alias to set the drag.target
// to our Note item.
drag.target: root
// creating the `delete` tool for deleting the note item
Tool {
id: deleteItem
source: "images/delete.png"
onClicked: root.destroy()
}
}
...
.. rubric:: What's Next?
Next, there will be a detailed step on how store the note items in a database locally.
|