Skip to content

Integrating QML and Go

Radhi Fadlillah edited this page Dec 2, 2019 · 5 revisions

In QML app, usually QML only used for creating the view and its logic, while the more advanced and performance-intensive tasks is implemented in the binding base language, which in qamel case is Go. For qamel, to communicate between QML and Go code, we need a "bridge" in form of a QmlObject. In this tutorial, we will create something like this :

Screencast QML + Go

First create a project directory for your application. If you use Go modules, you can put it wherever you want. If you are not using Go modules yet, you need to put it in your GOPATH, for example in $GOPATH/src/qml-go.

Next we will create a back end as a bridge between QML and Go, so create backend.go then write following codes :

package main

import (
	"math/rand"
	"time"

	"github.com/go-qamel/qamel"
)

// BackEnd is the bridge for communicating between QML and Go
type BackEnd struct {
	qamel.QmlObject
	_ func() int `slot:"getRandomNumber"`
}

func (b *BackEnd) getRandomNumber() int {
	rand.Seed(time.Now().UTC().UnixNano())
	return rand.Intn(9999)
}

Next create main.go, then write following codes :

package main

import (
	"os"

	"github.com/go-qamel/qamel"
)

func init() {
	// Register the BackEnd as QML component
	RegisterQmlBackEnd("BackEnd", 1, 0, "BackEnd")
}

func main() {
	// Create application
	app := qamel.NewApplication(len(os.Args), os.Args)
	app.SetApplicationDisplayName("Qamel Example")

	// Create a QML viewer
	view := qamel.NewViewerWithSource("qrc:/res/main.qml")
	view.SetResizeMode(qamel.SizeRootObjectToView)
	view.SetHeight(300)
	view.SetWidth(400)
	view.Show()

	// Exec app
	app.Exec()
}

Finally, create our QML view in res/main.qml :

import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.5
import BackEnd 1.0

Rectangle {
    color: "white"

    BackEnd {
        id: backEnd
    }

    ColumnLayout {
        spacing: 20
        anchors.verticalCenter: parent.verticalCenter
        anchors.horizontalCenter: parent.horizontalCenter
        Text {
            id: txt
            text: "Hello World"
            font.pixelSize: 32
            font.weight: Font.Bold
            horizontalAlignment: Text.AlignHCenter
            Layout.fillWidth: true
            Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
        }

        Button {
            text: "Create Random Number"
            width: 300
            Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
            onClicked: {
                let val = backEnd.getRandomNumber();
                txt.text = val.toString();
            }
        }
    }
}

At this point, your directory should look like this :

path/to/qml-go/
├── backend.go
├── main.go
└── res/
    └── main.qml

Once finished, all you need to do is build the app and run it.