2017-06-25 37 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(表示回调成功)。