Julia
gtk

Juliaで簡単なGUIアプリを作ってみる

概要

  • 人生初のGUIアプリ作成をJuliaでやってみました
  • GUIツールキットとしてGtkを使用しています
  • GUIプログラミング初心者なので、手始めに下図のようなボタンをクリックしたらクリックした回数が表示されるという簡単なアプリ作成から始めてみました

juliagui2.png

作成までの流れは
1. 画面レイアウトの作成
2. ボタンを押したときに呼ばれる関数の定義
3. ボタンと関数を連携させる
と言った感じです。

環境

OS: ArchLinux
Julia v0.6.2
Gtk.jl v0.13.1

インストール

GUIを作るためにGtk.jlを使っているのでインストールしていない場合インストールしてください。

Pkg.add("Gtk.jl")

画面レイアウトの作成

初めに大枠のウィンドウを作り、そこにボタンやらスライダーやら何やらのWidgetを追加していきます。

using Gtk.ShortNames

win = Window("Count Click") # 大枠のWindowをつくる
v = Box(:v) # widgetを並べて配置するためのボックス。 
            # :v でwidgetを縦に、:h で横並びになる
l = Label("You clicked 0 times.") # クリックした回数を表示する部分
b = Button("Click!") # ボタン
push!(win, v) # Window に Box を配置する
push!(v, l) # Box内に表示部分を配置
push!(v, b) # Box内にボタンを配置
setproperty!(v, :expand, l, true) # Box内の余白をなくして表示部分を広くする

showall(win) # レイアウトに反映させる

juliagui3.png

とりあえず、GUIアプリっぽくなってきました。しかし、このままではボタンを押したときの動作を定義していないのでボタンを押しても何も起こりません。

関数定義とボタンとの連携

次にボタンがクリックされたときに呼ばれる関数(callback function)を定義します。

nclick = 0
function click()
    global nclick += 1
    setproperty!(l, :label, "You clicked $nclick times.") # Label Widgetのラベルを変更する

    return nothing
end

signal_connect(x -> click(), b, "clicked") # ボタンと関数をつなぐ

setproperty!を使うと各 Widget の property を変更することができます。

最後に signal_connect でボタンと関数をつなげます。上記の場合だとボタンbから"clicked"シグナルが出たら callback function を呼ぶという意味になるらしいです。このとき、callback function にはボタン b が引数として与えられます。今回の場合、引数もらっても使わないので無名関数使って素通りさせてます。

これで目標のGUIアプリを作ることができるはずです。
窓の外の野鳥や車でも見ながらポチポチしてください。
juliagui2.png

まとめ

Juliaを使って簡単なGUIアプリを作ることができました。

私は他の言語でGUIアプリを作ったことがないので比較は出来ませんが、思っていたよりもGUIアプリって簡単に作れるものなんだなぁといった印象です。
まともな情報が公式ドキュメントくらいしかないのは辛いところですが。

他にも役に立たないものを練習がてら色々作ってみましたが、複雑なものでも 関数定義, setproperty!, signal_connect をひたすら繰り返せばそれっぽいものは作れるとわかりました。

ウィジェットが増えてくるとコマンドで画面レイアウトを作るのは大変なので Glade を使いましょう!

ソースコード

click
#!/usr/bin/env julia
using Gtk.ShortNames

# 画面レイアウトの作成
win = Window("Count Click")
v = Box(:v)
l = Label("You clicked 0 times.")
b = Button("Click!")
push!(win, v)
push!(v, l)
push!(v, b)
setproperty!(v, :expand, l, true)

showall(win)

# ボタンを押したときに呼ばれる関数
nclick = 0
function click()
    global nclick += 1
    setproperty!(l, :label, "You clicked $nclick times.")

    return nothing
end

# ボタンと関数をつなぐ
signal_connect(x -> click(), b, "clicked")


if !isinteractive()
    c = Condition()
    signal_connect(win, :destroy) do widget
        notify(c)
    end
    wait(c)
end

最後の部分はREPL使わずにコマンドラインからスクリプトとして実行したときのために入れています。

click とでもスクリプト名つけて、実行権限もつけて、PATHの通っているところおけば普通のGUIのアプリの様に使えます。

$ chmod +x click
$ ./click

参考

  • Gtk.jl documentation: Gtk.jlの公式ドキュメントを読めば簡単なアプリの作り方はおおよそ理解できます。
  • GTK+ 3 Reference Manual: 各Widgetのシグナルで悩んだらGTK+ 3 Reference Manualを見ましょう。
  • yomichi/JuliaBook-Samples: もっと凝ったアプリを作りたい場合 yomichiさんのサンプルコードが参考になります。

追記

もう少し実用的のものを作ってみました。GoogleにもWolfram Alphaにもグラフをプロットさせることが出来ない状況になったら有用かもしれません。
https://github.com/goropikari/GtkFunctionPlot.jl
screenshot.png