저는 하스켈에서 이벤트 중심의 프로그램을 작성하는 방법에 대해 머리 글을 쓰려고 장난감 애플리케이션을 만들려고합니다. 내가하려고하는 것은 키를 누를 때마다 앞으로 움직이는 캔버스에 선을 그리는 것입니다. 그래서 텍스트 편집기에서 원시 커서의 일종입니다.gtk2hs의 이벤트 핸들러간에 상태를 전달하는 방법
내 문제는 사용자가 키를 누른 횟수를 계산하는 가장 좋은 방법을 찾지 못하는 것입니다. 당연히 명령형 에서처럼 전역 변수를 사용할 수 없으므로 호출 스택에서 상태를 전달해야하지만 GTK 실행에서는 각 이벤트 핸들러가 반환 된 후 주 루프로 내려갑니다. 메인 루프 제어 하나의 이벤트 핸들러에서 변경된 글로벌 상태를 어떻게 전달할 수 있는지 알지 못한다. 그렇다면 한 이벤트 핸들러가 어떻게 다른 이벤트 핸들러에 상태를 전달할 수 있습니까?
여기에는 키보드 이벤트가 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