# Getting started with Rive in Qt

> Add rive-qt-plugin to a CMake project, show a .riv in QML, drive it through data binding, and generate typed names for your files' artboards, state machines and properties.

rive-qt-plugin builds from source alongside your app: add it to your CMake
project, link one target, and `RiveView` is available in QML.

## Requirements

- Qt 6.5 or later (6.12 tested)
- CMake 3.21 or later
- A C++20 compiler: Xcode's clang, MSVC 2022, or a recent GCC
- `make` (macOS and Linux) or `msbuild` (Windows), for Rive's own build
- `git`: the first configure bootstraps `premake5` from source

On macOS, Xcode needs its Metal compiler. If the build reports a missing
Metal toolchain, install it and rebuild:

```sh
xcodebuild -downloadComponent MetalToolchain
```

The Vulkan backend (on by default) compiles its shaders with `glslang` and
`spirv-tools`. Windows builds use copies that ship with the plugin. On macOS,
install them with `brew install glslang spirv-tools`; on Linux, from your
distribution's packages. Or turn Vulkan off (see [Build options](#build-options)).

## Add it to your project

Add the repository as a submodule:

```sh
git submodule add https://github.com/hypernuclear/rive-qt-plugin.git third_party/rive-qt-plugin
git submodule update --init --recursive
```

Then link it in your `CMakeLists.txt`:

```cmake
add_subdirectory(third_party/rive-qt-plugin)
target_link_libraries(my_app PRIVATE rive_qt::rive_qt)
```

The first configure takes a minute or two while it bootstraps `premake5` and
builds the Rive runtime. Builds after that are fast.

## Show a .riv

Import the module and give a `RiveView` a source. It loads `qrc:/`, `file://`
and `http(s)://` URLs:

```qml

Window {
    width: 640
    height: 480
    visible: true

    RiveView {
        anchors.fill: parent
        source: "qrc:/animations/hero.riv"
        fit: RiveView.Fit.Contain
        onLoadFailed: reason => console.warn("Rive:", reason)
    }
}
```

`RiveView` plays the artboard's default state machine, or its first animation
when there's no state machine. Mouse, touch and keyboard input go to the state
machine's listeners. To pick a different artboard or machine, set `artboard`
and `stateMachineName`.

## Drive it with data binding

Rive has replaced state machine inputs and events with data binding, so
that's how your app talks to the artboard. `RiveView` binds the artboard's
default view model and exposes it as `viewModel`:

```qml
RiveView {
    id: rive
    source: "qrc:/animations/scoreboard.riv"

    onViewModelChanged: {
        if (!viewModel)
            return
        viewModel.number("score").value = 42
        viewModel.trigger("celebrate").triggered.connect(() => console.log("celebrated"))
    }
}

Button {
    text: "Celebrate"
    onClicked: rive.viewModel.trigger("celebrate").fire()
}
```

For plain values you can also bind declaratively through `props`, e.g.
`text: rive.viewModel ? rive.viewModel.props.title : ""`. See
[RiveViewModelInstance](/docs/rive-qt/qml-api/#riveviewmodelinstance) for
every property type.

## Build options

Set these when you configure (`-DOPTION=VALUE`):

| Option | Default | What it does |
|--------|---------|--------------|
| `RIVE_QT_WITH_VULKAN` | `ON` | Builds the Vulkan backend. Off skips the `glslang` dependency. |
| `RIVE_QT_WITH_D3D12` | `ON` | Builds the Direct3D 12 backend (Windows). |
| `RIVE_QT_WITH_AUDIO` | `system` | `system` plays `.riv` audio through the OS; `external` decodes and mixes but leaves output to your app; `none` drops audio. |
| `RIVE_QT_WITH_SCRIPTING` | `ON` | Builds Rive's Luau scripting. Off, scripted listeners and transitions do nothing. |
| `RIVE_QT_WITH_RIVE_TOOLS` | `ON` | Allows unsigned scripts and builds the Luau compiler. Turn it off for production builds that only load signed `.riv` files. |
| `RIVE_QT_BUILD_EXAMPLES` | top level only | Builds the standalone viewer. |
| `RIVE_QT_BUILD_TESTS` | top level only | Builds the test suite. |

## Typed names for your files

Artboards, state machines and view model properties are looked up by name, so
a typo fails quietly at runtime. `qt_add_rive_assets()` reads your `.riv`
files at build time and generates their names as constants:

```cmake
qt_add_rive_assets(my_app
    NAMESPACE MyApp::Rive
    QML_URI MyApp.Rive
    ASSETS
        animations/scoreboard.riv
)
```

C++ gets a header per file, `scoreboard_assets.h`, already on the target's
include path. Its constants look like this, and a misspelled one is a compile
error:

```cpp
namespace MyApp::Rive::Scoreboard::ViewModels::Scoreboard {
    namespace Properties {
        inline constexpr std::string_view score = "score";
    }
    namespace Triggers {
        inline constexpr std::string_view celebrate = "celebrate";
    }
}
```

With `QML_URI`, each file also gets a QML singleton named after it:

```qml

Button {
    text: "Celebrate"
    onClicked: rive.viewModel
        .trigger(Scoreboard.viewModels.scoreboard.triggers.celebrate)
        .fire()
}
```

The generated names cover artboards and their state machines and text runs,
and each view model's instances, properties, triggers and nested view models.
Names are turned into valid identifiers (`State Machine 1` becomes
`State_Machine_1` in C++ and `state_Machine_1` in QML); open the generated
files to see exactly what you got.

## Try your files in the viewer

The repository includes a viewer that opens any `.riv`, lets you pick the
artboard, state machine or animation, scrub timelines and edit view model
properties live. See [the viewer](/docs/rive-qt/viewer/) for how to build and
use it.

## Good to know

- **Hosted assets load synchronously.** The `.riv` itself loads off the render
  thread, but images, fonts and audio the file references (rather than
  embeds) are fetched while it imports. Embed assets, or keep them small.
- **Source only.** You consume the plugin with `add_subdirectory`; there is no
  installed `find_package` package yet.
- **Sharing a view model across windows.** Several `RiveView`s, even in
  different windows, can share one `.riv`. Sharing a single view model
  instance between windows isn't safe yet.

---

From https://hypernuclear.com/docs/rive-qt/getting-started/
