Domanda

Devo fare qualche azione mentre viene premuto il pulsante.Come posso farlo?

Ho la versione 0.12.4.

p.S.: Per qualche motivo, onButtonActivate in

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
.

Non fare nulla.


.

Inoltre, è bello andare, se l'azione verrà eseguita ripetutamente mentre premeva un po 'di tastiera sulla tastiera.

È stato utile?

Soluzione

Secondo il Documenti onbuTonactivate è ammortizzato in modo da probabilmente non dovresti usarlo.Sto avendo problemi a trovare il modo corretto, ci sono probabilmente alcuni segnali generici da qualche parte che dovresti usare.Puoi provare la mia soluzione che utilizza igiene e onrelease (queste sono anche note come ammortizzate).Potresti fare come suggerito nel commento e alla forcella un filo:

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
.

Quindi riscrivi il tuo principale da fare:

whilePressed but (putStr "A")
.

Non sono sicuro che questo sia al sicuro, come sembra che potrebbe essere possibile per l'evento abbottonato da sparare prima che il killthread sia registrato.Potrebbe essere più sicuro usare un 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
.

Purtroppo non ho compilato o testato il codice Sine non posso installare GTK su questo computer, ma fammi sapere se hai problemi.

Altri suggerimenti

Questo utilizza un tagglebutton, un oggetto "timeout" (vedere TimeoutaDD nel sistema del modulo.glib.mainloop nei documenti) e un IOREF.Un timer viene avviato quando viene premuto il tagglebutton, ma solo se nessun altro timer è attualmente in esecuzione (è lo scopo dello IOREF).Se il pulsante viene rilasciato, il timer viene interrotto.La funzione di callback del timer ritorna IO FALSE per interrompere e distruggere l'oggetto Timer.

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
.

Il modo preferito di registrazione dei callback del segnale utilizza "On".Si noti inoltre che "On Window ObjectDestroy Mainquit" distrugga correttamente la finestra e interrompe il ciclo principale GTK (la versione non distrugge i timer in GHCI, continuavano a correre dopo aver chiamato nuovamente "Main").

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top