Pregunta

Necesito hacer alguna acción mientras se presiona el botón.¿Cómo puedo hacerlo?

Tengo la versión 0.12.4.

p.S.: Por alguna razón, onButtonActivate en

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

No hagas nada.


Además, es bueno ir, si la acción se hará repetidamente mientras presiona alguna tecla en el teclado.

¿Fue útil?

Solución

De acuerdo con la docs onbuttonactivate se deprecia, por lo que probablemente no deberías usarlo.Sin embargo, tengo problemas para encontrar la forma correcta, probablemente hay algunas señales genéricas en algún lugar que debe usar.Puede probar mi solución que use opresionada y onRelease (estos también se observan como depreciados).Podría hacer lo que se sugiere en el comentario y la horquilla un hilo:

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

luego reescribe a su principal que hacer:

whilePressed but (putStr "A")

No estoy seguro de si esto es seguro, ya que parece posible que pueda ser despedido para que el evento de Botón se le haya registrado antes de que KillThread se registre.Puede ser más seguro usar un iERef:

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

Lamentablemente, no he compilado ni probado el código sine, no puedo instalar GTK en esta computadora, pero avíseme si tiene algún problema.

Otros consejos

Esto utiliza un objeto ToggleButton, un "Tiempo de espera" (consulte el tiempo de tiempo en el sistema Module.glib.mainloop en los documentos) y un iERef.Se inicia un temporizador cuando se presiona el ToggleButton, pero solo si no se está ejecutando ningún otro temporizador (ese es el propósito de la IOREF).Si se libera el botón, el temporizador se detiene.La función de devolución de llamada del temporizador devuelve IO False para detener y destruir el objeto TEMPORTER.

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

La forma preferida de registrar las devoluciones de llamada de señal está usando "ON".También tenga en cuenta que "On Window ObjectDestroy Mainquit" destruye correctamente la ventana y detiene el bucle principal de GTK (la versión no destruyó los temporizadores en GHCI, siguieron funcionando después de llamar "Main" nuevamente).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top