我有一个小项目,我尝试使用 gi-gtk 在窗口上绘图。
https://github.com/bigos/cairo-example/blob/b9480dc63d6fff3bc195d35c7422f193fc8ae7d4/src/Main.hs
我已经弄清楚如何让 gi-gtk 与 Cairo 一起工作。
https://github.com/haskell-gi/haskell-gi/wiki/Using-Cairo-with-haskell-gi-generated-bindings
但是我在获取开罗上下文时遇到问题。在下面的代码中我有两个事件。第一个事件效果很好。但是当我监听窗口对象上的按键时,我无法弄清楚如何获取在 Canvas 上绘图所需的开罗上下文。
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
最佳答案
简单地说,你不能。您将无法访问 onWidgetDraw
回调之外的绘图上下文。
您可以(并且应该)做的是使用全局状态来允许您的 onWidgetDraw 回调根据发生的情况绘制不同的东西。例如,如果您想在用户按下向右箭头时绘制一些文本:
- 在
onWidgetKeyPressEvent
回调中,在用户按下所选键时在全局状态中设置一个值 - 在
onWidgetDraw
回调中,使用该值来确定是否必须绘制文本。
理想情况下,您会尝试将您的状态放入 State Monad 或类似的东西中 - 但是,在这种特定情况下,Gtk 不允许注入(inject) Monadic 状态本身,因此这不是直接可能的。您必须求助于IORef
、TVar
或任何等效项。
祝你好运! :)
关于haskell - 如何使用 Cairo 在 DrawingArea 小部件上绘图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50192550/