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