QField Plugins workshop

Introduction to QField Plugins Authoring

AGENDA

  1. Intro to QML
  2. Developing QField plugins
  3. Implementing a simple button plugin!
  4. Implementing the Weather Forecast plugin!
  5. Dialogs and Layouts

Intro to QML

Why QML

  • Qt Modeling Language, declarative, design-oriented
    • Elements (aka types)
    • Attributes: Properties, Signals, Handlers and Methods

../Imports

import QtQuick, import org.qfield, import org.qgis ...


import QtQuick

Item {

  [...]


}

../Elements (aka value types)

Item, Rectangle, Text, TextInput, MouseArea, Dialog, ...


Text {

  [...]


}

../Elements (aka value types)

Item, Rectangle, Text, TextInput, MouseArea, Dialog, ...


Rectangle {
  [...]
  Text {
    [...]
  }
}

../Elements (aka value types)

Item, Rectangle, Text, TextInput, MouseArea, Dialog, ...


Item {
  [...]
  Text {
    [...]
  }
}

../Attributes

Properties, Signals, Handlers and Methods


Rectangle {
  ...

  MouseArea {
    id: myArea

    ...

  }
}





../Attributes

Properties, Signals, Handlers and Methods


Rectangle {
  color: "green"

  MouseArea {

    anchors.fill: parent

  }
}






../Attributes

Properties, Signals, Handlers and Methods


Rectangle {
  color: "green"

  MouseArea {

    anchors.fill: parent

    onClicked: ...
  }
}





../Attributes

Properties, Signals, Handlers and Methods


Rectangle {
  color: "green"

  MouseArea {

    anchors.fill: parent

    onClicked: parent.color = "red"
  }
}





../Attributes

Properties, Signals, Handlers and Methods


Rectangle {
  color: "green"

  MouseArea {

    anchors.fill: parent

    onClicked: { parent.color = "red" }
  }
}





../Attributes

Properties, Signals, Handlers and Methods


Rectangle {
  color: "green"

  MouseArea {

    anchors.fill: parent

    onClicked: myCustomMethod()
    
    function myCustomMethod() {

      parent.color = "red"

    }
  }
}

../Attributes

Properties, Signals, Handlers and Methods


Rectangle {    
  color: theColor
  property var theColor: "green"

  MouseArea {
    
    anchors.fill: parent

    onClicked: {

      parent.theColor = "red"

    }
  }
}

../Attributes

Properties, Signals, Handlers and Methods


Rectangle {    
  color: theColor
  property var theColor: "green"

  MouseArea {
    
    anchors.fill: parent

    onClicked: {
      if (theColor == "green") {
          theColor = "red"
      } else {
          theColor = "green"
      }
    }
  }
}

../Attributes

Properties, Signals, Handlers and Methods


Rectangle {    
  color: isGreen ? "red" : "green"
  property bool isGreen: true

  MouseArea {
    
    anchors.fill: parent

    onClicked: {
      isGreen = !isGreen
    }
  }
}

../Attributes

Properties, Signals, Handlers and Methods


Rectangle {
  color: "green"

  MouseArea {

    anchors.fill: parent

    onClicked: { parent.color = "red" }
  }
}





../Attributes

Properties, Signals, Handlers and Methods


Rectangle {
  color: "green"
      
  signal colorChanged(var info)

  MouseArea {

    anchors.fill: parent

    onClicked: {
      parent.color = "red"
      parent.colorChanged("by in the mouse area")
    }
  }

  Text {
    id: textFeedback
    anchors.fill: parent
  }

  onColorChanged: {
    textFeedback.text = "Color changed to:" + parent.color + " info:" + info;
  }
}

Hello world (QML)

../Check it out

import QtQuick 2.0

Text {
  text: "Hello world!"
}

or here https://qmlweb.github.io

../Exercise online

  • Go to: https://qmlweb.github.io

  • Modify it to change the text color on clicking on it.

  • … and optionally to change the color back with another click

Break ☕

Developing QField plugins

../QField GUI

Dashboard | Main menu | Search bar | Plugins toolbar | Positioning | Canvas actions alt text

../QField GUI

Dashboard | Main menu | Search bar | Plugins toolbar | Positioning | Canvas actions alt text

../QField GUI

Dashboard | Main menu | Search bar | Plugins toolbar | Positioning | Canvas actions alt text

../QField GUI

Dashboard | Main menu | Search bar | Plugins toolbar | Positioning | Canvas actions alt text

../QField GUI

Dashboard | Main menu | Search bar | Plugins toolbar | Positioning | Canvas actions alt text

../QField GUI

Dashboard | Main menu | Search bar | Plugins toolbar | Positioning | Canvas actions alt text

../QField API

Root objects | iface | Theme | QField GUI types | QGIS | Utils


iface

qgisProject

settings

clipboardManager

...




See QField API for class documentation for details on which classes are exposed.

../QField API

Root objects | iface | Theme | QField GUI types | QGIS | Utils


iface.mainWindow()

iface.mapCanvas()

iface.positioning()

iface.findItemByObjectName("...")

iface.logMessage("...")

iface.addItemToPluginsToolbar()
iface.addItemToMainMenuActionsToolbar()
iface.addItemToCanvasActionsToolbar()


See QfAppInterface API documentation for details.

../QField API

Root objects | iface | Theme | QField GUI types | QGIS | Utils


QfTheme.mainColor  // #80cc28

QfTheme.mainTextColor

QfTheme.mainBackgroundColor

QfTheme.darkGray

QfTheme.defaultFont

QfTheme.getThemeVectorIcon("...")


See QfTheme API documentation for details.

../QField API

Root objects | iface | Theme | QField GUI types | QGIS | Utils


import org.qfield.gui
...
QfButton

QfToolButton

QfTextField

QfSwitch

QfComboBox

...


See QML GUI Items for details.

../QField API

Root objects | iface | Theme | QField GUI types | QGIS | Utils


QgsFeature

QgsGeometry

QgsAttributes

QgsPointXY

QgsField

...


See QGIS API documentation for class documentation.

../QField API

Root objects | iface | Theme | QField GUI types | QGIS | Utils


import org.qfield.core
...
QfLayerUtils

QfGeometryUtils

QfFeatureUtils

QfCoordinateReferenceSystemUtils

QfSnappingUtils

...


See C++ core classes for details.

../Plugin Location

Application Plugins

  • Install Plugins via QField Settings > Manage Plugins alt text

../Plugin Location

Application Plugins

  • Find location in “About QField” alt text
  • Folder structure alt text

../Plugin Location

Project Plugins

  • Copy to project folder
  • Name the main-file like the project qgz alt text

../Debugging

  • Popup on application display

    iface.mainWindow.displayToast("")

  • Log message in the log panel

    iface.logMessage("")

  • Console output (not visible in QField)

    console.log("")

../Let’s play

All the world is green

  Rectangle{
    id: myRectangle
    parent: iface.mapCanvas()
    anchors.fill: parent
    color: '#5000ff00'
  }

../Let’s play

Template Plugin

https://github.com/opengisch/qfield-template-plugin

Break ☕

Weather Forecast plugin

Let’s create a forecast plugin!

../What we need

  • Button to fetch a weather forecast (reuse the edited template plugin)
  • Show an info dialog (reuse the edited template plugin)
  • Our location (reuse the edited template plugin)
  • API call
    • XmlHttpRequest to do an API call and fetch the forecast from open-meteo.com
  • Whatever we want

../What we do

  • Check out open-meteo.com
  • Get code snippet on the slide below
  • We test the Java Script at https://runjs.app/play
  • We map the weather code to description and image
  • We integrate it into our template plugin

../API Request snippet

The Java Script for using XmlHttpRequest

//Laax
const lat = 46.8053;
const lon = 9.2572;

let request = new XMLHttpRequest();

request.onreadystatechange = function() {
  if (request.readyState === XMLHttpRequest.DONE) {
    iface.logMessage(request.responseText)
  }
}

request.open("GET", "https://api.open-meteo.com/v1/forecast?latitude=" + lat + "&longitude=" + lon + "&daily=weather_code,temperature_2m_max&timezone=auto");

request.send();

../Code Mapping

{
  "0": {
    "description": "Sunny", 
    "image": "http: //openweathermap.org/img/wn/01d@2x.png"
  }, 
  "1": {
    "description": "Mainly Sunny", 
    "image": "http://openweathermap.org/img/wn/01d@2x.png"
  }, 
  [...]
};

Plugin showcase

Plugin showcase

Snap!

Plugin showcase

Nominatim locator plugin

Plugin showcase

LiveField plugin

Resources

QML Documentation https://doc.qt.io/qt-6/qtquick-index.html

QML Reference: https://doc.qt.io/qt-6/qmlreference.html

QML Tutorial: https://doc.qt.io/qt-6/qml-tutorial.html

Introduction to Qt/QML, by KDAB (YouTube Playlist)

QML online editor: https://qmlweb.github.io

QML advanced online editor: https://patrickelectric.work/qmlonline/

QField plugins: https://github.com/topics/qfield-plugin

QField documentation: https://api.qfield.org/

Plugin icons: https://fonts.google.com/icons

JavaScript online editor: https://runjs.app/play

os_love

Thanks, and happy coding!