0

我有一个使用 Gtk2Hs 绑定的小 Haskell 程序。可以通过单击 DrawingArea 在程序窗口上绘制点(小方块):

[...]
    image <- builderGetObject gui castToDrawingArea "drawingarea"
    p <- widgetGetDrawWindow image
    gc <- gcNewWithValues p (newGCValues { foreground = Color 0 0 0,
        function = Copy })
    on image buttonPressEvent (point p gc)
    set image [ widgetCanFocus := True ]
[...]

point :: DrawWindow -> GC -> EventM EButton Bool
point p gc = tryEvent $ do
    (x', y') <- eventCoordinates
    liftIO $ do
        let x = round x'
        let y = round y'
        let relx = x `div` 4
        let rely = y `div` 4
        gcval <- gcGetValues gc
        gcSetValues gc (newGCValues { function = Invert })
        drawRectangle p gc True (relx * 4) (rely * 4) 4 4
        gcSetValues gc gcval

通过试错法并在阅读 Hackage 的文档后,我设法将按钮按下事件添加到绘图区域,因为小部件默认情况下不提供此事件的信号。但是,我不了解 EventM 的定义和用法,所以如果我必须再次向小部件添加新事件,恐怕我将不得不与 EventM monad 斗争。我必须说我仍然不够精通 Haskell。我有点理解简单的 monad 是如何工作的,但是这个“type EventM ta = ReaderT (Ptr t) IO a”(在 Graphics.UI.Gtk.Gdk.EventM 中定义)对我来说似乎是个谜。

我的问题是:有人可以解释一下 EventM monad 的内部结构吗?例如在“buttonPressEvent :: WidgetClass self => Signal self (EventM EButton Bool)”的情况下。

4

1 回答 1

1

我被类似的问题所困扰,似乎 EventM 是一个 ReadT,它将读取 EButton 并返回 Bool。

于 2013-11-10T07:39:30.417 回答