在gtk2hs中切换事件处理程序

men*_*ics 2 gtk haskell event-handling gtk2hs

我想做这样的事情:

handlerOn = do
  cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOff
  putStrLn "handlerOn"

handlerOff = do
  cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"
Run Code Online (Sandbox Code Playgroud)

当然,这不会起作用,因为我正在尝试在尚未分配cid的代码块中使用cid.

我们的想法是注册一个事件监听器,当它收到一个事件时,它将取消注册自己并注册一个不同的事件监听器,它将来回执行相同的操作.

eph*_*ent 5

GHC支持递归do.

handlerOn = do
  rec cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOff
  putStrLn "handlerOn"
Run Code Online (Sandbox Code Playgroud)

你也可以用Control.Monad.Fix.

handlerOff = do
  mfix $ \cid -> canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"
Run Code Online (Sandbox Code Playgroud)

或者自己管理处理程序.

do ...
    h <- newIORef undefined
    let handlerOn = do
            ...
            writeIORef h handlerOff
        handlerOff = do
            ...
            writeIORef h handlerOn
    writeIORef h handlerOn
    canvas `on` buttonPressEvent $ tryEvent =<< readIORef h
Run Code Online (Sandbox Code Playgroud)

或者只是把所有东西都变成一个处理程序

do ...
    ms <- newIORef False
    canvas `on` buttonPressEvent $ tryEvent do
        s <- readIORef ms
        if s
            then ...
            else ...
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!我正在使用第一个选项,至少对我来说,我必须添加大括号:rec {cid ... handlerOff}才能使用它. (2认同)