我需要在按下按钮时执行某些操作。我该怎么办?
我的版本是0.12.4。
P上。小号: 出于某种原因,
中的onButtonActivate
import Graphics.UI.Gtk
import Control.Concurrent
main = do
initGUI
window <- windowNew
but <-buttonNewWithLabel "Write A"
onButtonActivate but $ do
putStr "A"
threadDelay 1000000
return()
containerAdd window but
widgetShowAll window
onDestroy window mainQuit
mainGUI
什么都不做。
此外,如果在按下键盘上的某个键时反复进行操作,那么最好去。
答案 0 :(得分:1)
根据docs 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,但如果您有任何问题请告诉我。
答案 1 :(得分:1)
这使用了一个ToggleButton,一个“超时”对象(参见文档中System.Glib.MainLoop模块中的timeoutAdd)和一个IORef。按下ToggleButton时启动计时器,但前提是当前没有其他计时器正在运行(这就是IORef的目的)。如果释放按钮,则计时器停止。计时器的回调函数返回IO False以停止并销毁计时器对象。
import Graphics.UI.Gtk
import Data.IORef
import Control.Monad(void, when)
action but idle = do
butDown <- get but toggleButtonActive
if butDown
then do
putStrLn "A"
writeIORef idle False
return True
else do
writeIORef idle True
return False
main = do
initGUI
window <- windowNew
but <-toggleButtonNewWithLabel "Write A"
idle <- newIORef True
on but toggled $ do
butDown <- get but toggleButtonActive
isIdle <- readIORef idle
when (butDown && isIdle) $ void $ timeoutAdd (action but idle) 1000
containerAdd window but
widgetShowAll window
on window objectDestroy mainQuit
mainGUI
注册信号回调的首选方法是使用“on”。还要注意“on window objectDestroy mainQuit”正确地破坏窗口并停止Gtk主循环(你的版本没有销毁GHCi中的定时器,它们在再次调用“main”后继续运行)。