2017-06-25 51 views
2

Haskell Gi-GTK noob here。一般GTK noob。使用haskell-gi GTK信號

我有一個圖像,我已經包裝在一個事件箱中。現在,我想要檢測用戶何時按下事件框(mousedown)。一些谷歌搜索指向我使用button-press-event。我的代碼如下。

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

而且GHC失敗,出現以下神祕的錯誤消息,編譯如下:

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; 
      .... } 

我在做什麼錯誤?

+1

您正在使用'print ...'作爲事件處理程序,但這應該是一個接受有關按下哪個按鈕等信息的函數。 ,並返回一個'IO Bool',布爾表示處理程序是否成功。 – chi

+0

我看了一下[gi-gtk hello world示例](https://github.com/haskell-gi/gi-gtk-examples/blob/master/hello/World.hs)尋求幫助。在第30行,他們使用'onButtonClicked按鈕(putStrLn「Hello World」)來獲取信號。該代碼無誤地運行。我的代碼和他們的代碼有什麼區別?我在ghci的兩個函數上都運行了':t',它們類型簽名的唯一區別就是'ButtonClickedCallback'作爲參數,另一個需要'WidgetButtonPressEventCallback'。將我的打印語句更改爲putStrLn函數仍然會導致同樣的錯誤。 – hello

+0

我不是一個gtk +專家,但我猜想其中一個會對點擊產生反應,另一個會對鼠標按下按鈕 - 這可能是點擊,也可能不是點擊,因爲我們的鼠標上有許多按鈕。因此,在後一種情況下,偶處理程序會接受指定按下哪個按鈕的參數等。 – chi

回答

4

那麼錯誤消息已經說明了它:它需要EventButton -> IO Bool類型的函數,而print "Hello world"的類型是IO()

但是,您可以輕鬆地將其轉化爲一個,與:

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

因此,通過使用const $我們忽略對於現在的EventButton參數(以後你可以決定採取事件參數考慮在內),並通過使用>> return True,我們確保打印完成後,我們返回True(表示回調成功)。