Linux Mint上でのインストールから, WindowとDialogの表示と
イベントドリブンでの状態の持たせ方, 参考リンク等.
apt-getでのインストールは,
sudo apt-get install libghc-gtk-dev
で, Graphics.UI.Gtkが使えるようになります.
最初のシンプルなWindow表示は, Gtk2hs Tutorialにあるので, ボタンを押してダイアログボックスを表示させる例を書きます.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Graphics.UI.Gtk | |
showDialog :: Window -> String -> IO () | |
showDialog parent message = do | |
dialog <- messageDialogNew (Just parent) [] MessageInfo ButtonsOk message | |
dialogRun dialog | |
widgetDestroy dialog | |
main :: IO () | |
main = do | |
initGUI | |
window <- windowNew | |
set window [windowTitle := "Window Title"] | |
windowSetDefaultSize window 200 200 | |
button <- buttonNewWithLabel "click" | |
onClicked button (showDialog window "Hello world, Gtk2hs!") | |
containerAdd window button | |
onDestroy window mainQuit | |
widgetShowAll window | |
mainGUI |
以下のように実行します.
ghc showWindow.hs
./showWindow
dialogは, インスタンスを作成して(messageDialogNew), 実行して(dialogRun), インスタンス(widgetDestroy)を消去するという流れです. windowのインスタンスの参照は, Maybeモナドで包む必要があります.
MessageInfoのところには, MessageType型の情報を指定します. MessageWarning, MessageQuestion, MessageError, MessageOtherなどが指定でき, ダイアログの右側に表示されるアイコンを変更可能.
ButtonsOkのところは, ButtonsType型の情報を表し, ButtonsNone, ButtonsOk, ButtonsClose, ButtonsCancel, ButtonsYesNo, ButtonsOkCancelなどが指定できます.
イベントドリブンでの状態
Gtk2Hsでは, イベントドリブンによるプログラミングを行うようなので, Haskellとは相性が悪そうな, いわゆる状態をもたせる必要があります. ググってみると, 次のような記事が出てきました.
How to pass state between event handlers in gtk2hs (Stack Over Flow)
Haskellにおいて, 状態を持たせそうな仕組みは, 並列プログラミングにおけるMVar, Reader/Writerモナド, Stateモナド等, いろいろありますし, 上記の記事ではMVarを薦めていますが, 一番口当たりがいいのは, IORefオブジェクトだと思われます.
IORefは, 参照によるオブジェクトの共有を行う仕組みで, Clojureのref, OCamlの破壊的代入と基本的に使い方は同じです. IOモナド中に普通に記述できます.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Data.IORef | |
import Graphics.UI.Gtk | |
showDialog :: Window -> IORef Int -> IO () | |
showDialog parent counter = do | |
n <- readIORef counter | |
dialog <- (messageDialogNew | |
(Just parent) [] MessageInfo ButtonsOk | |
((show n) ++ " times")) | |
writeIORef counter (n + 1) | |
dialogRun dialog | |
widgetDestroy dialog | |
main :: IO () | |
main = do | |
initGUI | |
window <- windowNew | |
set window [windowTitle := "Window Title"] | |
windowSetDefaultSize window 200 200 | |
button <- buttonNewWithLabel "click" | |
counter<- newIORef 0 | |
onClicked button (showDialog window counter) | |
containerAdd window button | |
onDestroy window mainQuit | |
widgetShowAll window | |
mainGUI |
readIORef, writeIORef, newIORefでイベントハンドラ上で状態を共有することができます.
参考文献
Gtkに関しては, C言語の記事が多いので, C言語関係のコードを読みながら, Haskellへ読み替えられる場合があります.こことか.
Gtk2hs関連のページは,
Gtk2hs Tutorial
HackageのGtk2hsのソース
が参考になりました.