我有一个使用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)”的情况下。
答案 0 :(得分:1)
我被类似的问题所困,似乎EventM是一个读取EButton并返回Bool的ReadT。