gpt4 book ai didi

haskell - 如何在 gtk2hs 中的事件处理程序之间传递状态

转载 作者:行者123 更新时间:2023-12-04 08:15:54 25 4
gpt4 key购买 nike

我正在尝试制作一个玩具应用程序,只是为了了解如何在 Haskell 中编写事件驱动程序。我想要做的是在 Canvas 上画一条线,每次按下一个键时它都会向前移动(所以它有点像文本编辑器中的原始光标)。

我的问题是我无法计算出计算用户按键次数的最佳方法。显然我不能像在命令式程序中那样使用全局变量,所以大概我需要在调用堆栈上传递状态,但是在 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

最佳答案

首先,你可以有一个全局性的。忽略该解决方案是错误的形式,这看起来像是 MVar 的工作.在 main您只需制作一个新的 MVar,您可以在 onKeyboard 中更新它并 checkin myDraw :

...
import Control.Concurrent.MVar

main = do
...
mv <- newMVar 0
....
canvas `on` exposeEvent $ do liftIO $ renderWithDrawable draWin (myDraw mv 10)
...
window `on` keyPressEvent $ onKeyboard canvas mv

onKeyboard canvas mv = do
modifyMVar_ mv (\x -> return (x + 1))
....

myDraw mv pos = do
val <- readMVar mv
...

请注意,通过首先使用部分应用程序提供 MVar 将函数作为参数传递时,共享可变状态通常也很有用。 (或 TVarIORef 等)。

哦,还有一个警告:MVars 并不严格 - 如果应用程序有可能在不强制值的情况下写入很多(即读取和比较包含的 Int ),那么您应该在写入之前强制该值以避免构建一个巨大的砰。

关于haskell - 如何在 gtk2hs 中的事件处理程序之间传递状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5293898/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com