Переключение между обработчиками событий в 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"

Конечно, это не будет работать, потому что я пытаюсь использовать cid внутри блока кода, где cid еще не назначен.

Идея состоит в том, чтобы зарегистрировать прослушиватель событий, чтобы при получении события он отменял свою регистрацию и регистрировал другого прослушивателя, который будет делать то же самое, туда и обратно.

1 ответ

Решение

GHC поддерживает рекурсивныйdo,

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

Вы также можете использовать Control.Monad.Fix,

handlerOff = do
  mfix $ \cid -> canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"

Или управляйте обработчиком самостоятельно.

do ...
    h <- newIORef undefined
    let handlerOn = do
            ...
            writeIORef h handlerOff
        handlerOff = do
            ...
            writeIORef h handlerOn
    writeIORef h handlerOn
    canvas `on` buttonPressEvent $ tryEvent =<< readIORef h

Или просто сделать все в одном обработчике.

do ...
    ms <- newIORef False
    canvas `on` buttonPressEvent $ tryEvent do
        s <- readIORef ms
        if s
            then ...
            else ...
Другие вопросы по тегам