Set QML Property from another QML - qt

I have 2 qml files.
I want to set 2nd qml fromperty from the 1st qml file.
**first.qml**
var cmponent = Qt.createComponent("second.qml");
var newObj = cmponent.createObject(swipeView);
newObj.pageIndex = i;
swipeView.insertItem(swipeView.currentIndex+i,newObj)
and insert into a SwipeView.
Where , 'pageIndex' is the integer property of 2nd qml.
In the second qml file I have a GridLayout with cells.
I need to display the cell content based on this dynamic pageIndex property
second.qml
declared the property.
property int pageIndex: 0
onPageIndexChanged:{
console.log("onPageIndexChanged :" +pageIndex)
home_grid.update()
}
The onPageIndexChanged method is triggered but, I want to set the Grid cells based on the property value.
The issue is
While initialization of the component
var cmponent = Qt.createComponent("second.qml");
the cells are loaded into the GridLayout.
How can I relead/ solve this issue.

I think what you want is this:
(I used my example for your fist question)
It should illustrate my comments.
Of course you can put the different views in different files. You just need to pass the same model to both, when creating the objects.
ListModel {
id: lm
ListElement { width: 40; height: 40 }
[...]
ListElement { width: 40; height: 40 }
}
SwipeView {
width: 200
height: 800
clip: true
currentIndex: 0
Repeater {
model: Math.ceil(lm.count / 6)
delegate: ListView {
width: 200
height: 800
property int viewIndex: index
model: DelegateModel {
model: lm
groups: DelegateModelGroup { name: 'filter' }
Component.onCompleted: {
for (var i = viewIndex * 6; i < lm.count && i < (viewIndex * 6) + 6; i++) {
items.setGroups(i, 1, ['items', 'filter'])
}
}
filterOnGroup: 'filter'
delegate: Rectangle {
width: 180
height: 30
border.width: 1
Text {
anchors.centerIn: parent
text: index
}
}
}
}
}
}
GridView {
clip: true
x: 300
width: 600
height: 600
model: lm
delegate: TestObj {
}
}
Here is the Code for the delegate TestObj
Rectangle {
width: model.width
height: model.height
property alias text: myText.text
Text {
id: myText
anchors.centerIn: parent
text: index
}
}
Of course you could also write:
delegate: TestObj {
width: model.width; height: model.height; text: index
}
which would minimize the dependencies of your second QML-File.

Related

How to display a 2 dimension qvariantlist in QML

I have a 2-dimension qvariantlist which I would like to display in QML. I have been trying with a Listview but it only display the dimensions that you indicate. Ex array[0] array1 ...
The following code displays only the first dimension...:
Rectangle {
id: rectangle
height: 300
anchors.top: userFields.bottom
width: parent.width
ListView {
id: listView
anchors.centerIn: parent
width: 180
height: 200
model: RdaDevicePropertyAcess.rdaDataAcquired[userFields.devicePropertyText + '#' + userFields.fieldText]
delegate: Row {
Rectangle {
id: first
width: listView.width / 3
height: 30
Text {
anchors.centerIn: parent
text: modelData[0]
font.pointSize: 20
}
}
}
}
}
I was taking a look of this POST but i didn't work for me. I would like to have the same but displaying it into a qml object.
I also have been trying to use the createObject()javascript function but it didn't work for me neither.
Does anyone has any suggestion?
I reply to myself. Finally I solved the problem with the following QML code. I think it will help many people to save time.
Grid {
id: rectangle
height: 1000
columns: _model.myQvariantList.length
anchors.top: userFields.bottom
anchors.left: parent.left
anchors.right: parent.right
width: 1000
Repeater {
model: _model.myQvariantList[0].length
Repeater {
model: _model.myQvariantList.length
id: repeater1
property int outerIndex: index
Rectangle {
width: 20; height: 20
Text
{
anchors.centerIn: parent
text: _model.myQvariantList[index][repeater1.outerIndex]
font.pointSize: 10
}
}
}
}
}
I fill the 2-dimensional qvariantlist:
case DataType::DT_FLOAT_ARRAY_2D:{
const float * array= entry->getArrayFloat2D(rowCount, columnCount);
QVariantList list;
for (unsigned long row=0; row < rowCount;row++) {
QVariantList rows;
for (unsigned long col=0; col < columnCount;col++) {
rows.append(array[(row*columnCount+col)]);
}
list.append(QVariant::fromValue(rows));
}
return list;
}
Then in the QML part I try to display the 2D qvariantlist:
delegate: Row {
spacing: 5;
Repeater {
model: qvariantListObject
Rectangle {
width: listView.width / 3
height: 30
Text {
anchors.centerIn: parent
text: modelData[index]
font.pointSize: 12
}
}
}
}
But it is only repeating the same row several times.

How to Remove a dynamically created item from Column QML Element

[EDIT]: I want to remove some controls which are created in Column QML type dynamically and also how to access the children of a layout? .Following is the code which is not dynamic and is just for reference:
import QtQuick 2.6
import QtQuick.controls 2.2
Item
{
Column {
id:col
spacing: 2
//Initially Adding controls.
Rectangle { color: "red"; width: 50; height: 50 }
Rectangle { color: "green"; width: 20; height: 50 }
Rectangle { color: "blue"; width: 50; height: 20 }
}
Button
{
id:button
onClicked:
{
//How to remove a perticular element from above column which is created dynamically?
}
}
// [EDIT] - Code to add controls dynamically to column.
}
//How to remove perticular element from above column ?
Use the below mentioned code [Reference: https://stackoverflow.com/a/8852535/3459185]:
col.children[index_to_destroy].destroy()
[EDIT] Sample code to add and delete elements dynamically in a column:
Item
{
ListModel {
id: elementModel
ListElement { elementColor: "red"; elementWidth: 50; elementHeight: 50}
ListElement { elementColor: "green"; elementWidth: 20; elementHeight: 50}
ListElement { elementColor: "blue"; elementWidth: 50; elementHeight: 20}
}
Column {
id:col
spacing: 2
Repeater {
model: elementModel
Rectangle { color: elementColor; width: elementWidth; height: elementHeight }
}
}
Button
{
id: deleteButton; x: 200; y: 200; height: 50; width: 50; text: "Delete"
onClicked:
{
//How to remove perticular element from above column ?
elementModel.remove(index)
}
}
Button
{
id: addButton; x: 400; y: 200; height: 50; width: 50; text: "Add"
onClicked:
{
// Code to add controls dynamically to column.
elementModel.insert(index, { "elementColor": "red", "elementWidth": 50, "elementHeight": 50})
}
}
}

QML 'Custom Menu' option moving upwards

I am trying to create a "menu" in QML with custom data in each option
For requirements of my application, I need to show it loading the QML file dynamically (Qt.createComponent). What I need is to show some fixed options in the bottom part, and when clicked the top one, another options appear below this top option, which keeps in the top
A simple example. I have this menu:
Option 4
Option 2
Option 1
And when clicked in Option 4, the menu changes to
Option 4
Option 3
Option 2
Option 1
So Option 4 is moved upwards and Option 3 appears.
I would like to have a 'shadow' around all my menu (I added a DropShadow component for that purpose).
I have this simple test code, where I have a main Rectangle (to be surrounded by the shadow), and 2 Rectangles inside.
Rect1 for the fixed part (Option 1, Option 2), and Rect2 for the 'movable' part (Option 3, Option 4).
Rect2 is behind Rect1 (z: -1), and located to have only Option 4 visible, above Option 2. When clicked Option 4, Rect2 is moved upwards and all options are visible.
To achieve that, I have to update Rect2 visible height, and main window position (y value), since main window height depends on this Rect2 visible height.
I have it working, but it flicks a lot since 2 variables changes ('fixed panel' is moved upwards and back).
I have also tried with a ParallelAnimation for 2 values, but no success.
Any idea to have this menu with a smooth movement?
Main.qml:
import QtQuick 2.0
Rectangle
{
id: window
property variant win: undefined;
Component.onCompleted:
{
var component = Qt.createComponent("TestMenu.qml");
win = component.createObject(window, {"x": 500, "y": 500});
win.show();
}
}
TestMenu.qml:
import QtQuick 2.0
import QtQuick.Window 2.1
import QtGraphicalEffects 1.0
Window {
id: window
flags: Qt.Tool | Qt.FramelessWindowHint
height: panel.height
color: "transparent"
property int radiusShadow: 20
property int iOptionHeight: 30
Rectangle {
id: panel
anchors { centerIn: parent}
height: menu1.height + menu2.heightVisible + 2*radiusShadow
width: window.width - 2*radiusShadow
color: "transparent"
Rectangle {
id: menu1
anchors { bottom: parent.bottom; bottomMargin: radiusShadow }
width: parent.width
height: column1.children.length * iOptionHeight
Column {
id: column1
anchors.fill: parent
Rectangle {
color: "red";
Text { text: qsTr("option 2") }
height: iOptionHeight; width: parent.width
}
Rectangle {
color: "green";
Text { text: qsTr("option 1") }
height: iOptionHeight; width: parent.width
}
}
}
Rectangle {
id: menu2
property int heightVisible: iOptionHeight
anchors { top: parent.top; topMargin: radiusShadow; left: menu1.left }
width: parent.width
height: column2.children.length * iOptionHeight
z: -1
Column {
id: column2
anchors.fill: parent
Rectangle {
id: blue
property bool bOpen: false
color: "blue";
height: iOptionHeight; width: parent.width
Text { text: qsTr("option 4") }
MouseArea {
anchors.fill: parent
onClicked: {
blue.bOpen = !blue.bOpen;
panel.showHideMenu2(blue.bOpen);
}
}
}
Rectangle {
color: "pink";
Text { text: qsTr("option 3") }
height: iOptionHeight; width: parent.width
}
}
}
function showHideMenu2(bShow)
{
if (bShow)
{
window.y -= iOptionHeight
menu2.heightVisible += iOptionHeight;
}
else
{
window.y += iOptionHeight
menu2.heightVisible -= iOptionHeight;
}
}
}
DropShadow {
id: dropShadow
visible: true
anchors.fill: panel
radius: radiusShadow
samples: 24
color: "#40000000"
source: panel
}
}
As a quick answer for your question, you can get what you want using Behavior animation for a property change.
Here, Behavior animation will be used on y (position) change of your window, and for height change of respective rectangles.
Here is the patch for your code I recommend you to apply to see smooth movement:
## -10,6 +10,9 ##
property int radiusShadow: 20
property int iOptionHeight: 30
+ property int animationDuration: 500 // ms
+
+ Behavior on y { NumberAnimation { duration: window.animationDuration } }
Rectangle {
id: panel
## -18,6 +21,7 ##
height: menu1.height + menu2.heightVisible + 2*radiusShadow
width: window.width - 2*radiusShadow
color: "transparent"
+ Behavior on height { NumberAnimation { duration: window.animationDuration } }
Rectangle {
id: menu1
## -25,6 +29,7 ##
anchors { bottom: parent.bottom; bottomMargin: radiusShadow }
width: parent.width
height: column1.children.length * iOptionHeight
+ Behavior on height { NumberAnimation { duration: window.animationDuration } }
Column {
id: column1
## -52,6 +57,8 ##
width: parent.width
height: column2.children.length * iOptionHeight
+ Behavior on height { NumberAnimation { duration: window.animationDuration } }
+
z: -1
Column {
## -64,6 +71,7 ##
color: "blue";
height: iOptionHeight; width: parent.width
Text { text: qsTr("option 4") }
+ Behavior on height { NumberAnimation { duration: window.animationDuration } }
MouseArea {
anchors.fill: parent
## -77,6 +85,7 ##
color: "pink";
Text { text: qsTr("option 3") }
height: iOptionHeight; width: parent.width
+ Behavior on height { NumberAnimation { duration: window.animationDuration } }
}
}
}
## -105,4 +114,4 ##
color: "#40000000"
source: panel
}
-}+}
I have tried with a model and a ListView (code is simpler now), but I don't know where and how insert an 'Animation' or a 'Behaviour' to achieve my target, if it is possible to do it (I have tried several options with no success...)
The expected effect is that the 1st rectangle moves up when the 2nd appears, so the bottom one keeps in its position (at bottom). But the default behaviour when I add an element to the model is that the list increased the height downwards
Maybe anyone could help...
My code:
import QtQuick 2.0
import QtQuick.Controls 1.4
Rectangle {
id: rootItem
width: 400
height: list.height
ListModel {
id: modelRects
ListElement { rectColor: "green" }
ListElement { rectColor: "orange" }
}
ListView {
id: list
height: modelRects.count * 30
model: modelRects
delegate: Rectangle {
id: delegate
height: 30
width: rootItem.width
color: rectColor
MouseArea {
anchors.fill: parent
onClicked: onRectClicked(index);
}
}
}
function onRectClicked(index)
{
if (index == 0)
{
if (modelRects.count == 2)
modelRects.insert(1, {"idRect": 2, "rectColor": "red"});
else
modelRects.remove(1, 1);
}
}
}

QML: scroll multiple ListViews synchronously

I want to have a single (vertical) ListView with (horizontal) ListView delegates.
The horizontal delegates should scroll synchronously. To do so, I put a Flickable on top of the ListViews and bind the contentX of the horizontal ListView to the contentX of the Flickable (and the same for the contentY of the vertical ListView) (Note: Here a different approach was described for the synchronous ListView scrolling but this seems to have performance issues on mobile devices)
The code below kind of works but still has the following issues
I don't get the onClicked in the Rectangle (I do get it when I remove the top Flickable)
I want either horizontal flicking or vertical flicking but not both at the same time. I can restrict the flicking of the top Flickable by setting flickableDirection: Flickable.HorizontalFlick but then I can't flick vertically anymore (I was hoping that the Flickable would pass on unused mouse events to the vertical ListView but this doesn't seem to happen)
Suggestions on how to fix these issues?
Any help appreciated!
import QtQuick 2.0
Item {
id: main
visible: true
width: 600
height: 600
ListView {
id: verticalList
width: parent.width;
height: parent.height;
contentY : flickable.contentY
anchors.fill: parent
spacing: 10
orientation: ListView.Vertical
model: 100
delegate:
ListView {
id: horizontalList
width: parent.width;
height: 100;
contentX : flickable.contentX
spacing: 10
orientation: ListView.Horizontal
model: 20
property var verticalIndex : index
delegate:
Rectangle
{
property var colors : ['red', 'green', 'blue']
property var widths : [100, 200, 300]
height: 100
width: widths[(verticalIndex + model.index) % widths.length]
color: colors[model.index % colors.length]
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Rectangle.onClicked")
}
}
}
}
}
//on top a Flickable
Flickable {
id: flickable
height: parent.height
width: parent.width
contentHeight: 100*100 //nrOfRows * rowHeight
contentWidth: 20*300 //nrOfEvent * max/averageEventWidth
}
}
I'm not giving you a perfect solution, but it's working. When you are using Flickable on the top of the ListView, you are not able to interact with it. So, I've used Flickable bellow the ListView and bounded the contentX of Flickable and ListView, but this is causing a loop and I'm getting the following output, but we're getting the desired behavior.
QML Binding: Binding loop detected for property "value"
EDIT
So, instead of using ListView for vertical list, I just used a Repeater and Column and used property binding. It's working well now.
Following is the updated version.
import QtQuick 2.0
Item {
id: main
visible: true
width: 600
height: 600
property bool virticalFlick: false //To get either vertical or horizontal flicking
Flickable {
anchors.fill: parent
contentWidth: contentItem.childrenRect.width
contentHeight: contentItem.childrenRect.height
flickableDirection: Flickable.VerticalFlick
interactive: (virticalFlick === true)?true:false
Column {
id: column
spacing: 10
Repeater {
id: repeater
model: 20
ListView {
id: horizontalList
width: 600;
height: 100;
clip: true
interactive: (virticalFlick === true)?false:true
spacing: 10
orientation: ListView.Horizontal
model: 20
property var verticalIndex : index
onMovingChanged: {
if(moving == true) {
for(var i=0; i<repeater.count ; i++) {
/* If the property is later assigned a static value from a JavaScript statement,
this will remove the binding.
However if the intention is to create a new binding then the property
must be assigned a Qt.binding() value instead. This is done by passing a function to
Qt.binding() that returns the desired result */
if (i !== index)
repeater.itemAt(i).contentX = Qt.binding(function() { return contentX });
}
}
else {
for(var i=0; i<repeater.count ; i++) {
if (i !== index)
repeater.itemAt(i).contentX = contentX; // This will remove binding
}
}
}
delegate: Rectangle {
property var colors : ['red', 'green', 'blue']
property var widths : [100, 200, 300]
height: 100
width: widths[(ListView.view.verticalIndex + model.index) % widths.length]
color: colors[model.index % colors.length]
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Rectangle.onClicked")
}
}
}
}
}
}
}
}
The following does work, however the initial attempt seemed more elegant.
I still need to compare the performance (fps) when flicking, especially on a mobile device. I also get "Binding loop" warnings but I think they are false positives.
import QtQuick 2.0
Item {
id: main
visible: true
width: 600
height: 600
ListView {
id: verticalList
width: parent.width;
height: parent.height;
anchors.fill: parent
spacing: 10
cacheBuffer: 500 // in pixels
orientation: ListView.Vertical
model: 100
property var activeIndex : 0
property var lastContentX : 0
delegate:
ListView {
id: horizontalList
width: parent.width;
height: 100;
spacing: 10
cacheBuffer: 500 // in pixels
orientation: ListView.Horizontal
model: 20
property var verticalIndex : index
delegate:
Rectangle
{
property var colors : ['red', 'green', 'blue']
color: colors[model.index % colors.length]
height: 100
property var widths : [100, 200, 300]
width: widths[(verticalIndex + model.index ) % widths.length]
MouseArea {
z:10
anchors.fill: parent
onClicked: {
console.log("Rectangle.onClicked")
}
onPressed: {
console.log("Rectangle.onPressed")
}
onReleased: {
console.log("Rectangle.onReleased")
}
}
}
onContentXChanged: {
if(model.index === verticalList.activeIndex)
{
verticalList.lastContentX = contentX
}
}
onMovementStarted: {
verticalList.activeIndex = model.index
unbind();
}
onMovementEnded: {
bind();
}
Component.onCompleted: {
bind();
}
function bind()
{
contentX = Qt.binding(function() { return verticalList.lastContentX })
}
function unbind()
{
contentX = contentX ;
}
}
}
}
The following modifications were needed to my initial attempt
limit the Flickable to flickableDirection : Flickable.HorizontalFlick and remove the contentY : flickable.contentY on the verticalList
by doing so, there is no vertical scrolling anymore. This can be fixed by moving the Flickable inside the ListView
onClicked events are received by adding the following MouseArea to the Flickable
eg.
MouseArea {
anchors.fill: parent
//see http://stackoverflow.com/questions/29236762/mousearea-inside-flickable-is-preventing-it-from-flicking
onReleased: {
if (!propagateComposedEvents) {
propagateComposedEvents = true
}
}
}

QML: How to move items within a grid

I have a 4x4 grid and I want to associate arrow key presses with the movement of items within the grid. How does one do that?
Here is a sample QML:
import QtQuick 1.1
Rectangle {
id: main;
width: 500; height: 500;
color: "darkgreen";
property int emptyBlock: 16;
Grid {
id: grid16;
x: 5; y: 5;
width: 490; height: 490;
rows: 4; columns: 4; spacing: 5;
Repeater {
model: 1;
Rectangle {
width: 118; height: 118; color: "darkblue";
}
}
}
Keys.onRightPressed: pressRight();
function pressRight() {
console.log("Left key pressed");
}
focus: true;
}
Update 1: Thanks to sebasgo and alexisdm for the answers. If moving within a grid is not that easy why we have the move transition property [http://qt-project.org/doc/qt-4.8/qml-grid.html#move-prop]
You'd better use a GridView Item instead of your Grid approach.
This way you can use it's currentIndex property to choose which item to move like this:
import QtQuick 1.1
Rectangle {
id: main;
width: 500; height: 500;
color: "darkgreen";
property int emptyBlock: 16;
GridView {
id: grid16;
x: 5; y: 5;
width: 490; height: 490;
model: gridModel
delegate: Component{
Rectangle {
width: 118; height: 118; color: "darkblue";
Text {
anchors.centerIn: parent
font.pixelSize: 20
text: value
}
}
}
}
ListModel {
id: gridModel
ListElement {value: 1}
ListElement {value: 2}
ListElement {value: 3}
ListElement {value: 4}
}
Keys.onRightPressed: {
gridModel.move(grid16.currentIndex, grid16.currentIndex+1, 1)
}
Keys.onLeftPressed: {
gridModel.move(grid16.currentIndex, grid16.currentIndex-1, 1)
}
focus: true;
}
Grids give you no way to manipulate the position of the contained items directly. Instead their position is directly derived from the physically order of the child items of the grid. There is no easy way to to manipulate child items in QML dynamically, so I think you should abandon the Grid item and specify the position of the child items explicitly with the x and y properties. Applied to your code this could look like:
Rectangle {
id: main;
width: 500; height: 500;
color: "darkgreen";
Item {
x: 5; y: 5;
width: 490; height: 490;
Repeater {
id: pieces
model: 1;
Rectangle {
property int column: 0
property int row: 0
x: column * 123
y: row * 123
width: 118; height: 118; color: "darkblue";
}
}
}
Keys.onRightPressed: pressRight();
function pressRight() {
console.log("Left key pressed");
pieces.itemAt(0).column++
}
focus: true;
}
Update 1:
Grids (in combination with a Repeater) can be used to visualize models, e.g., a XmlListModel item or an QAbstractItemModel descendent.
With move property it's easy to react to layout changes in the model (if an entry is removed/added) in an animated way. Still, the items in the Grid are laid out strictly in the order of the entries of the model.
So if you want have manual control over the position of your items, even in cellular layout, use of a Grid is not advisable.
You can change the number of items before the item you want to move to change its position:
import QtQuick 1.1
Rectangle {
id: main;
width: 500; height: 500;
color: "darkgreen";
property int emptyBlock: 16;
property int posX: 0;
property int posY: 0;
Grid {
id: grid;
x: 5; y: 5;
width: 490; height: 490;
rows: 4; columns: 4; spacing: 5;
Repeater {
id: beforeTheItem
model: main.posX + parent.columns * main.posY
Rectangle {
width: 118; height: 118; color: "transparent";
}
}
Rectangle {
id:theItem
width: 118; height: 118; color: "darkblue";
}
}
Keys.onPressed: {
// To avoid flickering, the item is hidden before the change
// and made visible again after
theItem.visible = false;
switch(event.key) {
case Qt.Key_Left: if(posX > 0) posX--;
break;
case Qt.Key_Right: if(posX < grid.columns - 1) posX++;
break;
case Qt.Key_Up: if(posY > 0) posY--;
break;
case Qt.Key_Down: if(posY < grid.rows - 1) posY++;
break;
}
theItem.visible = true;
}
focus: true;
}
Now, by using Qt 5.1 or above and GridLayout you can move your items without hassle:
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
Window
{
visible: true
MainForm
{
GridLayout {
id: gridLayout
columns: 3
property int oneRow: 0
property int oneCol: 0
Text { id: one; Layout.row :grid.oneRow; Layout.column: grid.oneCol; text: "My"; font.bold: true; }
Text { text: "name"; color: "red" }
Text { text: "is"; font.underline: true }
Text { text: "not"; font.pixelSize: 20 }
Text { text: "Ravan"; font.strikeout: true }
}
Component.onCompleted:
{
gridLayout.oneRow = 1
gridLayout.oneCol = 2
}
}
}
The GridView is a very confusing monster. It just populates one row from a given model, which leads to confusion since it is called GRID. But it can still be used as a fixed size grid, as I show in the example below. A single square can be moved with arrow keys on a 4x4 sized grid.
GridView {
id: grid16;
anchors.fill: parent
cellWidth: parent.width / 2
cellHeight: parent.height / 2
model: gridModel
delegate:
Rectangle {
Component.onCompleted: if( index >= 1 ) visible = false
width: grid16.cellWidth ; height: grid16.cellHeight ; color: "yellow";
Text {
anchors.centerIn: parent
font.pixelSize: 20
text: value
}
}
move: Transition {
NumberAnimation { properties: "x,y"; duration: 1000 }
}
}
ListModel {
id: gridModel
ListElement {value: 1}
//Necessary, otherwise the grid will have the dimension 1x1
ListElement {value: 2}
ListElement {value: 3}
ListElement {value: 4}
}
Keys.onRightPressed: { gridModel.move(grid16.currentIndex, grid16.currentIndex+1, 1) }
Keys.onLeftPressed: { gridModel.move(grid16.currentIndex, grid16.currentIndex-1, 1) }
Keys.onUpPressed: { gridModel.move(grid16.currentIndex, grid16.currentIndex-2, 1) }
Keys.onDownPressed: { gridModel.move(grid16.currentIndex, grid16.currentIndex+2, 1) }
focus: true;
}

Resources