Haskell&问:如何在点击按钮时显示文字?

时间:2016-03-06 15:02:39

标签: qt haskell hsqml

我正在尝试创建一个显示" hello"当一个人点击按钮时,使用Qt和haskell(使用HsQML)。

请直接进入最后更新:你会看到我犯的最后一个错误:-)

我有一个有效的基地,但在我自己的程序中我已经有错误

/home/lowley/Documents/haskell/Qt/exemple-2.hs: line 13, column 5:
parse error on input `skey'
/home/lowley/Documents/haskell/Qt/exemple-2.hs: line 13, column 5:
Warning: Parse error: Last statement in a do-block must be an
expression
Found:
  main = do
    state <- newIORef $ T.pack ""
>     skey <- newSignalKey
      clazz <- newClass [
        defPropertySigRO' "my_label" skey (\_ ->)

这是我的计划:

module Main where

import Graphics.QML
import Control.Concurrent
import Control.Exception
import Data.IORef
import Data.Text (Text)
import qualified Data.Text as T

main :: IO ()
main = do
    state <- newIORef $ T.pack ""
    skey <- newSignalKey
    clazz <- newClass [
        defPropertySigRO' "my_label" skey (\_ ->
            readIORef state),
        defMethod' "sayHello" (\obj txt->
            writeIORef state $ T.pack txt
            fireSignal skey obj
            return ())]
    ctx <- newObject clazz ()
    runEngineLoop defaultEngineConfig {
        initialDocument = fileDocument "exemple2.qml",
        contextObject = Just $ anyObjRef ctx}

这是QML文件:

import QtQuick 2.0
import QtQuick.Controls 1.3

Item {
    height: 266
    Button {
        id: bouton
        x: 278
        y: 77
        text: qsTr("click me!")
        onClicked: sayHello("Hello!!")
    }

    Text {
        x: 166
        y: 147
        width: 309
        height: 87
        text: my_label
        horizontalAlignment: Text.AlignHCenter
        font.pixelSize: 76
    }

}

有关信息,这是一个有效的示例,它位于同一目录中,并且还使用sublime文本进行编译:

HS档案:

module Main where

import Graphics.QML
import Control.Concurrent
import Control.Exception
import Data.IORef
import Data.Text (Text)
import qualified Data.Text as T

main :: IO ()
main = do
    state <- newIORef $ T.pack ""
    skey <- newSignalKey
    clazz <- newClass [
        defPropertySigRO' "result" skey (\_ ->
            readIORef state),
        defMethod' "factorial" (\obj txt -> do
            let n = read $ T.unpack txt :: Integer
            writeIORef state $ T.pack "Working..."
            fireSignal skey obj
            forkIO $ do
                let out = T.take 1000 . T.pack . show $ product [1..n]
                evaluate out
                writeIORef state out
                fireSignal skey obj
            return ())]
    ctx <- newObject clazz ()
    runEngineLoop defaultEngineConfig {
        initialDocument = fileDocument "factorial2.qml",
        contextObject = Just $ anyObjRef ctx}

QML文件:

import QtQuick 2.0

Column {
    height: 300;
    TextInput {
        id: input; width: 300; font.pixelSize: 30; focus: true;
    }
    Rectangle {
        color: "red"; width: childrenRect.width; height: childrenRect.height;
        Text {
            width: 300; font.pixelSize: 30;
            text: "Calculate Factorial"; color: "white";
        }
        MouseArea {
            anchors.fill: parent;
            onClicked: factorial(input.text);
        }
    }
    Text {
        width: 300; wrapMode: Text.WrapAnywhere; font.pixelSize: 30;
        text: result;
    }
}

如果你能看出它们之间的区别,我非常感兴趣。

更新: 现在我用标签更改了所有空格,我面临另一个错误:

Couldn't match expected type `(skv0
                                 -> tt0 -> Graphics.QML.Objects.SignalValueParams skv0)
                                -> SignalKey p0 -> ObjRef () -> (a0 -> m0 a0) -> () -> Text'
              with actual type `Text'
  The function `T.pack' is applied to six arguments,
  but its type `String -> Text' has only one
  In the second argument of `($)', namely
    `T.pack "hello" fireSignal skey obj return ()'
  In the expression:
    writeIORef state $ T.pack "hello" fireSignal skey obj return ()

我不明白为什么ghc会抱怨这个适用于6个论点的包...

更新: 这段代码:

module Main where

import Graphics.QML
import Control.Concurrent
import Control.Exception
import Data.IORef
import Data.Text (Text)
import qualified Data.Text as T

main :: IO ()
main = do
    state <- newIORef $ T.pack ""
    skey <- newSignalKey
    clazz <- newClass [
        defPropertySigRO' "my_label" skey (\_ -> readIORef state),
        defMethod' "sayHello" (\obj txt -> do
            writeIORef state $ T.pack txt
            fireSignal skey obj
            return ())]
    ctx <- newObject clazz ()
    runEngineLoop defaultEngineConfig {
        initialDocument = fileDocument "exemple2.qml",
        contextObject = Just $ anyObjRef ctx}

导致此错误,仍然无法理解:

exemple-2.hs:16:17:
    Couldn't match type `MarshalMode Char ICanGetFrom ()' with `Yes'
    In the expression:
      defMethod'
        "sayHello"
        (\ obj txt
           -> do { writeIORef state $ T.pack txt;
                   fireSignal skey obj;
                   return () })
    In the first argument of `newClass', namely
      `[defPropertySigRO' "my_label" skey (\ _ -> readIORef state),
        defMethod'
          "sayHello"
          (\ obj txt
             -> do { writeIORef state $ T.pack txt;
                     .... })]'
    In a stmt of a 'do' block:
      clazz <- newClass
                 [defPropertySigRO' "my_label" skey (\ _ -> readIORef state),
                  defMethod'
                    "sayHello"
                    (\ obj txt
                       -> do { writeIORef state $ T.pack txt;
                               .... })]

编辑:新代码,新错误消息......

代码:

module Main where

import Graphics.QML
import Control.Concurrent
import Control.Exception
import Data.IORef
import Data.Text (Text)
import qualified Data.Text as T

main :: IO ()
main = do
    state <- newIORef $ T.pack ""
    skey <- newSignalKey
    clazz <- newClass [
        defPropertySigRO' "my_label" skey (\_ -> readIORef state),
        defMethod' "sayHello" (\obj txt -> do
            writeIORef state txt
            fireSignal skey obj
            return ())]
    ctx <- newObject clazz ()
    runEngineLoop defaultEngineConfig {
        initialDocument = fileDocument "exemple2.qml",
        contextObject = Just $ anyObjRef ctx}

错误消息:

Build FAILED

/home/lowley/Documents/haskell/Qt/exemple-2.hs: line 13, column 10:
  No instance for (SignalSuffix (IO a0))
    arising from a use of `newSignalKey'
  The type variable `a0' is ambiguous
  Possible fix: add a type signature that fixes these type variable(s)
  Note: there is a potential instance available:
    instance SignalSuffix (IO ()) -- Defined in `Graphics.QML.Objects'
  Possible fix:
    add an instance declaration for (SignalSuffix (IO a0))
  In a stmt of a 'do' block: skey <- newSignalKey
  In the expression:
    do { state <- newIORef $ T.pack "";
         skey <- newSignalKey;
         clazz <- newClass
                    [defPropertySigRO' "my_label" skey (\ _ -> readIORef state),
                     defMethod' "sayHello" (\ obj txt -> ...)];
         ctx <- newObject clazz ();
         .... }
  In an equation for `main':
      main
        = do { state <- newIORef $ T.pack "";
               skey <- newSignalKey;
               clazz <- newClass
                          [defPropertySigRO' "my_label" skey (\ _ -> ...), ....];
               .... }

0 个答案:

没有答案