Comment faire quelque chose à plusieurs reprises alors que le bouton est enfoncé dans gtk2hs?

StackOverflow https://stackoverflow.com//questions/22059147

  •  23-12-2019
  •  | 
  •  

Question

J'ai besoin de faire un peu d'action, tandis que le bouton est pressé.Comment puis-je le faire?

J'ai la version 0.12.4.

P.S.:Pour une raison quelconque, onButtonActivate dans

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

ne pas faire n'importe quoi.


Aussi, il est bon d'aller, si une action va être fait à plusieurs reprises tout pressé quelques clés sur le clavier.

Était-ce utile?

La solution

Selon l' docs onButtonActivate est amorti de sorte que vous ne devriez probablement pas l'utiliser.Je vais avoir du mal à trouver le bon chemin, bien que, il y a sans doute certains génériques signaux quelque part que vous devez utiliser.Vous pouvez essayer ma solution qui utilise onPressed et au relâchement (ceux-ci sont également considérés comme amortis).Vous pourriez le faire, comme le suggère le commentaire de la fourche et un fil:

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

Alors réécrire votre principal pour le faire:

whilePressed but (putStr "A")

Je ne sais pas si c'est sûr, même si, comme il semble qu'il pourrait être possible pour le buttonReleased événement pour être tiré avant killThread est enregistré.Il peut être prudent d'utiliser 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

Malheureusement, je n'ai pas compilé ou mis à l'essai le code des sinus je ne peux pas installer GTK sur cet ordinateur, mais laissez-moi savoir si vous avez des questions.

Autres conseils

Il utilise un ToggleButton, un "délai d'attente" de l'objet (voir timeoutAdd dans le module Système.La Glib.MainLoop dans les docs) et un IORef.Un timer est démarré lorsque le ToggleButton est pressé vers le bas, mais seulement si aucun autre minuterie est actuellement en cours d'exécution (c'est le but de la IORef).Si le bouton est relâché, la minuterie est arrêtée.La minuterie la fonction de callback retourne IO Faux de s'arrêter et de détruire l'objet 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

Le moyen privilégié de l'enregistrement du signal à l'aide de rappels est "sur".Notez également que "sur la fenêtre de objectDestroy mainQuit" correctement détruit la fenêtre et s'arrête le Gtk boucle principale (vous version n'a pas de détruire les compteurs à zéro dans GHCi, ils restent en cours d'exécution après l'appel de la "main" de nouveau).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top