我正在嘗試製作一個玩具應用程序,只是爲了讓我的頭瞭解如何在Haskell中編寫事件驅動的程序。我想要做的是在每次按下按鍵時向前移動一個畫布(因此它是文本編輯器中的原始光標)。如何在gtk2hs中的事件處理程序之間傳遞狀態
我的問題是我無法計算出用戶按下某個鍵的次數的最佳方法。顯然,我不能像我在一個命令式程序中那樣使用全局變量,所以大概我需要在調用堆棧上傳遞狀態,但是在GTK中,每個事件處理程序返回後執行都會下降到主循環中,並且由於我不控制主循環我看不出我如何從一個事件處理程序傳遞更改後的全局狀態。那麼,一個事件處理程序如何將狀態傳遞給另一個事件處理程序
我在這裏有一種部分解決方案,其中鍵盤事件re-curries myDraw並將其設置爲新的事件處理程序。我不確定這個解決方案是否可以擴展,或者哪怕這是個好主意。
這個問題最好的解決方案是什麼?
import Graphics.UI.Gtk
import Graphics.Rendering.Cairo
main :: IO()
main= do
initGUI
window <- windowNew
set window [windowTitle := "Hello World",
windowDefaultWidth := 300, windowDefaultHeight := 200]
canvas <- drawingAreaNew
containerAdd window canvas
widgetShowAll window
draWin <- widgetGetDrawWindow canvas
canvas `on` exposeEvent $ do liftIO $ renderWithDrawable draWin (myDraw 10)
return False
window `on` keyPressEvent $ onKeyboard canvas
window `on` destroyEvent $ do liftIO mainQuit
return False
mainGUI
onKeyboard :: DrawingArea -> EventM EKey Bool
onKeyboard canvas = do
liftIO $ do drawWin <- widgetGetDrawWindow canvas
canvas `on` exposeEvent $ do liftIO $renderWithDrawable drawWin (myDraw 20)
return False
widgetQueueDraw canvas
return False
myDraw :: Double -> Render()
myDraw pos = do
setSourceRGB 1 1 1
paint
setSourceRGB 0 0 0
moveTo pos 0
lineTo pos 20
stroke