2017-06-25 2 views
2

Haskell Gi-GTK noob hier. Und GTK noob im Allgemeinen.Mit Haskell-Gi GTK-Signale

Ich habe ein Bild, das ich in eine Eventbox gehüllt habe. Jetzt möchte ich erkennen, wenn der Benutzer auf die Ereignisbox drückt (mousedown). Etwas Googeln weist mich auf button-press-event zu verwenden. Mein Code ist unten.

drag <- imageNewFromFile "rszh.png" 
dragevents <- eventBoxNew 
containerAdd dragevents drag 
set dragevents [widgetHalign := AlignEnd, widgetValign := AlignEnd] 
onWidgetButtonPressEvent dragevents (print "Hello world") 

Und GHC versagt dies mit der folgenden kryptischen Fehlermeldung zu kompilieren:

panedraggin.hs:30:42: error: 
    • Couldn't match type ‘IO()’ 
        with ‘GI.Gdk.Structs.EventButton.EventButton -> IO Bool’ 
     Expected type: GI.Gtk.Objects.Widget.WidgetButtonPressEventCallback 
     Actual type: IO() 
    • Possible cause: ‘print’ is applied to too many arguments 
     In the second argument of ‘onWidgetButtonPressEvent’, namely 
     ‘(print "Hello world")’ 
     In a stmt of a 'do' block: 
     onWidgetButtonPressEvent dragevents (print "Hello world") 
     In the expression: 
     do { Gtk.init Nothing; 
      window <- windowNew WindowTypeToplevel; 
      onWidgetDestroy window mainQuit; 
      windowMaximize window; 
      .... } 

Was ich falsch mache?

+1

Sie verwenden 'print ...' als Event-Handler, aber dies ist eine Funktion, die Informationen darüber akzeptiert, welche Taste gedrückt wurde, usw. und gibt ein 'IO Bool' zurück, wobei der Boolean angibt, ob der Handler erfolgreich war. – chi

+0

Ich habe das [gi-gtk Hallo Welt Beispiel] (https://github.com/haskell-gi/gi-gtk-examples/blob/master/hello/World.hs) um Hilfe gebeten. In Zeile 30 benutzten sie 'onButtonClicked (putStrLn" Hello World ")' für Signale. Dieser Code wird ohne Fehler ausgeführt. Was ist der Unterschied zwischen meinem Code und seinem Code? Ich habe ': t' auf beiden Funktionen in ghci ausgeführt, und der einzige Unterschied in ihren Typ-Signaturen besteht darin, dass man einen 'ButtonClickedCallback' als Parameter und den anderen einen' WidgetButtonPressEventCallback' nimmt. Das Ändern meiner print-Anweisung in eine putStrLn-Funktion gibt mir immer noch den gleichen Fehler. – hello

+0

Ich bin kein GTK + -Experte, aber ich würde vermuten, dass man auf Klicks reagiert, der andere auf das Drücken der Maustaste - was vielleicht Klicks sein können oder auch nicht, da wir viele Tasten an unseren Mäusen haben. Folglich nimmt der geradzahlige Handler im letzteren Fall ein Argument an, das angibt, welche Taste gedrückt wurde usw. – chi

Antwort

4

Nun die Fehlermeldung sagt es bereits: es erwartet eine Funktion des Typs EventButton -> IO Bool, und print "Hello world" hat einen Typ IO().

Sie können jedoch leicht in einen verwandeln, mit:

onWidgetButtonPressEvent dragevents (const $ print "Hello world">> return True)

So von const $ verwenden wir den EventButton Parameter für jetzt ignorieren (später können Sie entscheiden, die Ereignisparameter zu berücksichtigen) und unter Verwendung von >> return True stellen wir sicher, dass wir nach dem Drucken True zurückgeben (was bedeutet, dass der Rückruf erfolgreich war).