Go + QML で簡単なカウンタ作成

「[Go + QML で簡単なカウンタ作成 - Goとキュートな日々](http://miyabishi.hatenablog.com/entry/2015/12/27/160341)」から転載。

Go + QML で、ボタンを押すと数字をカウントアップする簡単なアプリケーションを作ります。

# まずはソースコード



```go:main.qml
package main
import (
    "gopkg.in/qml.v1"
    "fmt"
)

// --------------------------------------------------
// main
// --------------------------------------------------
func main() {
    err := qml.Run(run)
    if nil != err {
        fmt.Println(err)
    }
}

// --------------------------------------------------
// run関数
// --------------------------------------------------
func run() error {
    engine := qml.NewEngine()
    component, err := engine.LoadFile("counter.qml")
    if err != nil {
        return err
    }

    // コンテキストに変数をセットする
    context := engine.Context() 
    context.SetVar("counter", &Counter{Count: 0})

    win := component.CreateWindow(nil)
    win.Show()
    win.Wait()
    return nil
}

// --------------------------------------------------
// Counter 構造体
// --------------------------------------------------
type Counter struct {
    Count int
}

// --------------------------------------------------
// Increment メソッド
// --------------------------------------------------
func (counter *Counter) Increment() {
    counter.Count += 1 // カウンタを1増やす
    qml.Changed(counter, &counter.Count) 
}


```

```qml:counter.qml
import QtQuick 2.0
import QtQuick.Controls 1.4

ApplicationWindow{
    title:  "Counter"
    width:  200
    height: 200

    Rectangle {
        id: page
        anchors.fill: parent
        color: "lightgray"

        Label{
            text: counter.count
            y: 40
            anchors.horizontalCenter: page.horizontalCenter
            font.pointSize: 36; font.bold: true
        }

        Button{
            text: "click!"
            y: 100
            anchors.horizontalCenter: page.horizontalCenter
            onClicked: {
                counter.increment()
            }
        }
    }
}
```

# 簡単な解説

run関数の以下の箇所でコンテキストに変数を設定しています。これを行うことでQMLからGoで定義したcounter構造体を使用することができるようになります。

```go
    // コンテキストに変数をセットする
    context := engine.Context() 
    context.SetVar("counter", &Counter{Count: 0})
```

GoとQMLではフィールドにアクセスする際の大文字/小文字が異なるので注意しなければなりません。
以下、例。

```go
value.Name      => value.name
value.UPPERName => value.upperName
value.UPPER     => value.upper
```

counter.qml 内では 以下の箇所でLabelのテキストに counter.countを設定しています。

```
        Label{
            text: counter.count
            y: 40
            anchors.horizontalCenter: page.horizontalCenter
            font.pointSize: 36; font.bold: true
        }
```

また、counter.qmlにはボタンが押された際にcounter.incrementメソッドを呼び出す処理が以下に書かれています。

```
        Button{
            text: "click!"
            y: 100
            anchors.horizontalCenter: page.horizontalCenter
            onClicked: {
                counter.increment()
            }
        }
```

main.qml内のincrementメソッド内ではCounter構造体のcount値を1増やしています。
値を変更した後にqml.Changedメソッドを呼ぶことで全てのQMLオブジェクトに値の変更が反映されます。

```go
func (counter *Counter) Increment() {
    counter.Count += 1 // カウンタを1増やす
    qml.Changed(counter, &counter.Count) 
}
```

# 実行結果
以下のウインドウが表示されボタンを押すと数字がカウントアップされます。
![スクリーンショット 2015-12-27 16.02.27.png](https://qiita-image-store.s3.amazonaws.com/0/107186/9b5f52eb-7b14-bab3-fb98-2987c847571d.png)


以上です。

# 参考

*  [QtとC++でGUIプログラミング](http://www.slideshare.net/seanchas_t/qt-cpp-26692727)
*  [qml - GoDoc](https://godoc.org/gopkg.in/qml.v1)