如何使用Cairo在drawingArea小部件上绘图?

时间:2018-05-05 18:04:29

标签: haskell gtk cairo

我有一个小项目,我尝试使用gi-gtk在窗口上绘图。

https://github.com/bigos/cairo-example/blob/b9480dc63d6fff3bc195d35c7422f193fc8ae7d4/src/Main.hs

我已经想出如何让gi-gtk与开罗合作。

https://github.com/haskell-gi/haskell-gi/wiki/Using-Cairo-with-haskell-gi-generated-bindings

但我在获取cairo上下文时遇到问题。在下面的代码中,我有两个事件。第一个事件很好。但是,当我在窗口对象上按下按键时,我无法弄清楚如何获得绘制canves所需的cairo上下文。

  win <- Gtk.windowNew WindowTypeToplevel
  canvas <- Gtk.drawingAreaNew
  Gtk.containerAdd win canvas

  _ <- Gtk.onWidgetDraw canvas $ \context ->
    renderWithContext context (updateCanvas canvas) >> pure True

  _ <- Gtk.onWidgetKeyPressEvent win $ \x -> do
    vvv <- Gdk.getEventKeyKeyval x
    -- How do I draw on canvas here?
    (putStrLn ("You have pressed key code " ++  (show vvv))) >> pure True

1 个答案:

答案 0 :(得分:2)

简单地说,你不能。您将无法访问onWidgetDraw回调之外的绘图上下文。

你可以(而且应该)做的是使用全局状态允许你的onWidgetDraw回调根据发生的事情绘制不同的东西。例如,如果要在用户按右箭头时绘制一些文本:

  • onWidgetKeyPressEvent回调中,当用户按下所选键时,在全局状态中设置一个值
  • onWidgetDraw回调中,使用该值确定是否必须绘制文本。

    理想情况下,你会尝试使你的状态符合State Monad或类似的东西 - 但是,在这个特定的情况下,Gtk不允许注入Monadic状态本身,所以这不是直接可能的。您必须使用IORefTVar或任何等效内容。

    祝好运! :)