EventM如何在Gtk2Hs中运作?

时间:2012-06-25 14:24:04

标签: gtk2hs

我有一个使用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是如何工作的,但是这个“类型EventM t a = ReaderT(Ptr t)IO a”(在Graphics.UI.Gtk.Gdk.EventM中定义)对我来说似乎是一个谜。

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

1 个答案:

答案 0 :(得分:1)

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