如何在gtk2hs中的事件处理程序之间传递状态
我正在尝试制作玩具应用程序,以便了解如何在Haskell中编写事件驱动程序。我要做的是在画布上绘制一条线,每次按下一个键时向前移动(所以它在文本编辑器中是一种原始光标)。
我的问题是我无法确定用户按下按键的次数的最佳方法。显然,我不能像在命令式程序中那样使用全局变量,所以我可能需要在调用堆栈上传递状态,但是在每个事件处理程序返回后,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
没有找到相关结果
已邀请:
1 个回复
羔磺
你只需制作一个新的MVar,你可以在
更新并检入
:
注意,通过首先使用部分应用程序提供
(或
,
,无论如何)将函数作为参数传递时,共享可变状态通常也很有用。 哦,还有一个警告:MVars并不严格 - 如果应用程序有可能在没有强制值的情况下写入批量(即读取和比较包含的
),那么你应该在写入之前强制该值以避免构建巨大的thunk。