hsqml-datamodel-0.0.0.0: HsQML (Qt5) data model.

Safe HaskellNone
LanguageHaskell2010

Graphics.QML.DataModel.Tutorial

Contents

Synopsis

Haskell side

Any data type with a single constructor and marshallable fields can be used in a QML data model. For example:

  data Row = Row {foo :: Int, bar :: String, baz :: Double}
    deriving Generic

To use the data type in a model, first you need to declare the necessary instances. All the necessary classes have default implementations using Generic. To further automate the process, there's a Template Haskell macro that declares them all:

 dataModelInstances Row

If you don't want to use TH, you can declare them manually:

 instance QtTable      Row
 instance Mock         Row
 instance CountFields  Row
 instance SetupColumns Row

Finally, in your main function, register the data model as a QML type, set up the delegate and its callbacks, and provide a way for QML to access it.

setTVarCallbacks 
  :: QtTable a 
  => DataModel a 
  -> TVar [a]
  -> IO ()
setTVarCallbacks model tv = do
  setRowCountCallback model $      length $ readTVarIO mtv
  setDataCallback     model $ i -> (!!i) $ readTVarIO mtv

main = do
    registerHaskellModel   

    storage <- newTVarIO [Row 1 "a" 3.0, Row 2 "b" 4.2]
    model <- setupDataModel
    setTVarCallbacks model storage

    toplevel'class <- newClass [ defPropertyConst' "haskellModelDelegate" . return $ delegate model ]
    toplevel'obj <- newObject toplevel'class ()

    runEngineLoop defaultEngineConfig 
      { initialDocument = "path/toyour/main.qml"
      , contextObject = Just $ anyObjRef toplevel'obj
      }

QML side

Using the model in QML is simple as that:

  HaskellModel {
    id: haskellModel;
    delegate: haskellModelDelegate;
  }

  TableView {
    id: hsView;
    model: haskellModel;

    TableViewColumn {
      title: "A";
      role: "baz";
    }

    TableViewColumn {
      title: "B";
      role: "foo";
    }
  }

Record fields become roles, and you can use them in any order any with any names you like. Views other than TableView can be used too, of course.