haskell-giでHelloWorldができたので、基本的なラベル、テキストボックス、ボタンを使った簡単なプログラムを作ってみます。
テキストボックスに数値を入れて、ボタンを押すと+1した結果をラベルに出力します。
stackでプロジェクトを作成します。
stack new my-project
cd my-project
「stack.yaml」ファイルに「extra-deps」を設定します。
extra-deps:
- gtk2hs-buildtools-0.13.8.0
- glib-0.13.8.1
- cairo-0.13.8.1
- pango-0.13.8.1
- gi-gtk-3.0.37
- gi-gdk-3.0.24
- gi-gdkpixbuf-2.0.26
- gi-gmodule-2.0.1
- gi-atk-2.0.23
- gi-cairo-1.0.25
- gi-gio-2.0.28
- gi-gobject-2.0.26
- gi-harfbuzz-0.0.4
- gi-pango-1.0.24
- haskell-gi-0.25.0
- haskell-gi-base-0.25.0
- gi-glib-2.0.25
- reactive-banana-1.2.1.0
「package.yaml」ファイルに「dependencies」を設定します。
dependencies:
- base >= 4.7 && < 5
- gi-gtk
- haskell-gi-base
- text
- gi-gio
- bytestring
「app/Main.hs」ファイルに下記コードを上書きします。
{-# LANGUAGE OverloadedStrings, OverloadedLabels #-}
{- cabal:
build-depends: base, haskell-gi-base, gi-gtk == 3.0.*
-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
{- Hello World example of GTK+ documentation. For information please refer to README -}
module Main where
-- import qualified Data.Text as T
import Data.Text
import qualified GI.Gio as Gio
import qualified GI.Gtk as Gtk
import Data.GI.Base
import Data.Text.Encoding
--import qualified Data.ByteString
activateApp :: Gtk.Application -> IO ()
activateApp app = do
win1 <- new Gtk.ApplicationWindow [ #application := app
, #title := "BasicSample"
, #defaultHeight := 200
, #defaultWidth := 200
]
box1 <- new Gtk.Box [ #orientation := Gtk.OrientationVertical ]
#add win1 box1
entry1 <- new Gtk.Entry[ #text := "0" ]
#add box1 entry1
label1 <- new Gtk.Label [#label := "1" ]
#add box1 label1
button1 <- new Gtk.Button [ #label := "Increment"]
on button1 #clicked ( do
buffer <- Gtk.entryGetBuffer entry1
bufferText <- Gtk.entryBufferGetText buffer
let bufferString = Data.Text.unpack bufferText
let bufferInt = (read bufferString :: Int) + 1
let label1String = show (bufferInt)
let label1Text = Data.Text.pack label1String
set label1 [ #sensitive := False, #label := label1Text ]
)
--on btn #clicked $ Gtk.widgetDestroy w
#add box1 button1
#showAll win1
return ()
main :: IO ()
main = do
app <- new Gtk.Application [ #applicationId := "haskell-gi.examples.hello-world"
, #flags := [ Gio.ApplicationFlagsFlagsNone ]
]
on app #activate $ activateApp app
Gio.applicationRun app Nothing
return ()
少し解説します。
box1 <- new Gtk.Box [ #orientation := Gtk.OrientationVertical ]
#add win1 box1
上記より上のコードで設定したウィンドゥ(win1)にbox1というBoxを追加しています。
box1に追加される部品が縦(垂直)に並ぶよう「Gtk.OrientationVertical」を設定しています。
ここの部分を「Gtk.OrientationHorizontal」とすると横(水平)に部品が並びます。
entry1 <- new Gtk.Entry[ #text := "0" ]
#add box1 entry1
単行のテキストボックスです。
初期値で"0"が表示されるようにしています。
label1 <- new Gtk.Label [#label := "1" ]
#add box1 label1
ラベルを設置しています。
初期値で"1"が表示されるようにしています。
button1 <- new Gtk.Button [ #label := "Increment"]
on button1 #clicked ( do
buffer <- Gtk.entryGetBuffer entry1
bufferText <- Gtk.entryBufferGetText buffer
let bufferString = Data.Text.unpack bufferText
let bufferInt = (read bufferString :: Int) + 1
let label1String = show (bufferInt)
let label1Text = Data.Text.pack label1String
set label1 [ #sensitive := False, #label := label1Text ]
)
--on btn #clicked $ Gtk.widgetDestroy w
#add box1 button1
ボタンを設置しています。
ボタンがクリックされたとき、テキストボックスのデータを取り出し、Text型に変換し、更にString型に変換し、更に数値化したデータをインクリメントして、再びString型に変換し、再びText型に変換し、ラベルに設定しています。
コンパイルして実行します。
stack build
stack exec my-project-exe
下記のように実行されます。(テキストボックスに「5」を入力してボタン押下後)
以上