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モナドと格闘する必要があります。私はまだHaskellに十分な能力を持っていないと言わなければなりません。単純なモナドがどのように機能するかはある程度理解していますが、この1つの「typeEventM ta = ReaderT(Ptr t)IO a」(Graphics.UI.Gtk.Gdk.EventMで定義)は私には不思議に思えます。

私の質問は:誰かがEventMモナドの内部を説明してもらえますか?たとえば、「buttonPressEvent :: WidgetClass self => Signal self(EventM EButtonBool)」の場合です。

4

1 に答える 1

1

私は同様の問題に悩まされています。EventMはEButtonを読み取り、Boolを返すReadTのようです。

于 2013-11-10T07:39:30.417 に答える