LoginSignup
5
3

More than 1 year has passed since last update.

haskell-giでHelloWorld以後

Last updated at Posted at 2021-05-27

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」を入力してボタン押下後)

20210527.png

すべてのソースコード

以上

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3