根据文档onButtonActivate 已贬值,因此您可能不应该使用它。虽然我很难找到正确的方法,但您应该在某处使用一些泛型信号。您可以尝试我使用 onPressed 和 onRelease 的解决方案(这些也被标记为折旧)。您可以按照评论中的建议进行操作并分叉一个线程:
import Control.Concurrent (forkIO, killThread, threadDelay)
import Control.Monad (void, when)
whilePressed button action = do
onPressed button $ do
threadId <- forkIO go
onReleased button (killThread threadId)
where
go = do
action
threadDelay 1000000
go
然后重写你的主要做:
whilePressed but (putStr "A")
我不确定这是否安全,因为在注册 killThread 之前似乎可能会触发 buttonReleased 事件。使用 IORef 可能更安全:
import Data.IORef
whilePressed button action = do
isPressed <- newIORef False
onPressed button $ do
writeIORef isPressed True
void $ forkIO $ go isPressed
onReleased button (writeIORef isPressed False)
where
go isPressed = do
c <- readIORef isPressed
when c $ do
action
threadDelay 1000000
void $ forkIO $ go isPressed
不幸的是,我还没有编译或测试代码,因为我无法在这台计算机上安装 GTK,但如果您有任何问题,请告诉我。