WxHaskell

2,918 views
2,784 views

Published on

How to make GUI in Haskell

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,918
On SlideShare
0
From Embeds
0
Number of Embeds
73
Actions
Shares
0
Downloads
17
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

WxHaskell

  1. 1. λ WxHaskell λλ inajob http://d.hatena.ne.jp/inajob/
  2. 2. λ wxWidgets λλ ● クロスプラットホームなGUIツールキット – 単にGUIのセットだけではなく通信や文字列操作、ファイル 管理も行うことが出来る欲張りなライブラリ – C++で記述されているが様々な言語から利用可能 ● wxPython,wxPerl,WxHaskell... ● 類似品 – Gtk – Tk – Qt – Swing
  3. 3. λ Haskell λλ ● 純関数型言語 – 正直なところ何が出来るのかとか僕は理解していない – Haskellを理解するためにGUIアプリケーションを作ってみる ● WxHaskell – HaskellからwxWidgetsを操作するためのラッパライブラリ – これでHaskellを使ってGUIアプリケーションが作れる main = putStrLn “Hello world” main = putStrLn $ show 2008 main = putStrLn (show 2008)
  4. 4. λ 日本語 λλ ● ソースコードにutf8を使うと日本語を表示できる – ソースコード中の文字を自動でUCS4に変換する ● 読み込んだデータを表示する – そのままだと文字化けする – hogehoge⇒UCS4 変換を利用する (hogehoge:読み込んだデータの文字コード)
  5. 5. λ 初めてのWindow λλ import Graphics.UI.WX main = start mainFrame mainFrame = do f <- frameFixed [text := quot;はろー Worldquot;] p <- panel f [] set f [layout := minsize (sz 300 300) $ widget p] ● いきなりdo – GUIを扱う命令はIOなので仕方がないです ● := でプロパティを設定可能
  6. 6. λ 初めてのWindow2 λλ import Graphics.UI.WX main = start mainFrame mainFrame = do s <- readFile “title.txt” f <- frameFixed [text := utf8ToUcs4 s] p <- panel f [] set f [layout := minsize (sz 300 300) $ widget p] ● 外部データをGUIに表示する時は変換関数を通す
  7. 7. λ はじめてのレイアウト λλ mainFrame = do f <- frame [text := quot;titlequot;] p <- panel f [] b <- button p [text := quot;pushquot;] i <- textEntry p[text := quot;aquot;] set p [layout := (row 2 [fill$widget i,widget b])] set f [layout := (fill $ widget p)] ● button,textEntry ● widget,row,column,fill,等でレイアウトを整える – リサイズに耐える設計 ● 親をちゃんと指定しましょう
  8. 8. λ もっとレイアウト λλ mainFrame = do f <- frame [text := quot;titlequot;] p <- panel f [] b <- button p [text := quot;pushquot;] i <- textEntry p[text := quot;aquot;] l <- singleListBox p [items := [quot;inaquot;,quot;jobquot;,quot;kpcquot;]]; set p [layout :=(column 2 [ (row 2 [fill$widget i,widget b]), fill$widget l ])] set f [layout := (fill $ widget p)] ● singleListBox
  9. 9. λ イベント λλ mainFrame = do f <- frame [text := quot;titlequot;] p <- panel f [] b <- button p [text := quot;pushquot;,on command ::= buttonEv] i <- textEntry p [text := quot;aquot;] set p [layout := (row 2 [fill$widget i,widget b])] set f [layout := (fill $ widget p)] buttonEv w = showDialog quot;helloquot; quot;worldquot; w showDialog:: String -> String -> Window a -> IO () showDialog msg title parent = do mesd <- messageDialogCreate parent msg title wxOK messageDialogShowModal mesd messageDialogDelete mesd ● クリックされると関数が呼び出される
  10. 10. λ マルチスレッドとチャンネル λλ mainFrame = do eventsChan <- newChan --MultiThread Queue f <- frame [text := quot;titlequot;] p <- panel f [] i <- textEntry p [text := quot;aquot;] b <- button p [text:=quot;pushquot;,on command::=buttonEv i eventsChan] set p [layout := (row 2 [fill$widget i,widget b])] set f [layout := (fill $ widget p)] timer <- windowTimerCreate f timerOnCommand timer (onTimer eventsChan i) timerStart timer 500 False onTimer chan i = do noEvents <- isEmptyChan chan if noEvents then return () else do str <- readChan chan; set i [text := show$str] buttonEv i chan w= do forkOS child set i [text:= quot;startquot;] where child = writeChan chan $fact 1000000 fact n=foldl' (*) 1 [1..n] ● 別スレッドからの信号をタイマーで受け取る – (重い計算をするとどっち道固まったorz)
  11. 11. λ Twitterクライアントを書いてみた λλ ● 一応かけた ● 良かったこと – JSONのパーサをいじるのが楽だった – 必要かどうか不明な通信を遅延評価で隠蔽 (unsafePerformIOの利用) ● 悪かったこと – GUI周りはとても手続き的 – 通信も手続き的 – コンパイルである程度バグが取れるが、それ以降のデバッ グがやりにくい ● http://d.hatena.ne.jp/inajob/20081005
  12. 12. λ まとめ λλ ● GUIは手続き型言語に任せて ● パーサやアルゴリズムのコアの部分をHaskellで記述 するのがよさそう

×