2012-06-25 14 views
1

我有一個使用Gtk2Hs綁定的Haskell程序。人們可以通過點擊繪圖區繪製程序的窗口上點(小廣場):EventM如何在Gtk2Hs中工作?

[...] 
    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 => Signal self(EventM EButton Bool)」的情況下。

回答

1

我堆積了類似的問題,似乎EventM是一個ReadT,它將讀取EButton並返回Bool。

+0

所以有些狀態隱式地傳遞給使用ReaderT monad的信號處理程序,不是嗎?我想我已經開始掌握了這一點。不過,Gtk2Hs的信號處理慣例似乎並不一致。 –

+0

我這麼認爲,文件中提到「每個事件都帶有可通過EventM monad中的函數訪問的附加信息」。所以我認爲這個國家會被暗中通過。 EventM用於訪問事件中的信息。 – realli