Skip to content

MaterialApplication - Material 应用

MaterialApplicationApplication 的 Material Design 3 专用派生类,自动注册亮色和暗色主题,并把 Material 动画工厂绑定上去。如果你的应用用 Material Design 3,直接用它就行,不需要手动注册主题。

初始化

用法很简单,替换掉 QApplication 就行:

cpp
#include "ui/widget/material/application/material_application.h"

using namespace cf::ui::widget::material;

int main(int argc, char* argv[]) {
    MaterialApplication app(argc, argv);

    // 默认已经是 Material 亮色主题
    MainWindow w;
    w.show();

    return app.exec();
}
```text

构造函数里会自动调用 `init()`,`init()` 按下面的顺序执行:

1. 注册 Material 动画工厂(前缀 `theme.material`)
2. 注册 Material 亮色和暗色主题到 `ThemeManager`
3. 设置默认主题为 `theme.material.light`
4. 调用基类的 `init()` 创建动画工厂

## 主题切换

Material 主题已经预注册好了,直接切换就行:

```cpp
// 切换到暗色主题
app.setTheme("theme.material.dark");

// 或者用 token 字面量(推荐)
using namespace cf::ui::core::token::literals;
app.setTheme(MATERIAL_THEME_DARK);
```text

主题切换会触发 `themeChanged` 信号,动画工厂会同步重建。

## 动画工厂绑定

Material 动画工厂是和主题绑定的——当主题切换到任何 `theme.material.*` 时,都会用 `CFMaterialAnimationFactory` 创建动画。工厂的前缀匹配保证了这点:

```cpp
// 在 MaterialApplication::init() 里已经注册了
Application::registerAnimationFactoryType("theme.material",
    [](const core::ICFTheme& theme, QObject* parent) {
        return std::make_unique<CFMaterialAnimationFactory>(theme, nullptr, parent);
    });
```text

所以你不需要自己管工厂创建,只要确保主题 token 以 `theme.material.` 开头就行。

## 默认主题

`MaterialApplication::DEFAULT_THEME` 定义为 `MATERIAL_THEME_LIGHT`(即 `"theme.material.light"`)。如果你想在构造后立即切换主题,可以直接用:

```cpp
MaterialApplication app(argc, argv);

// 如果想要暗色主题作为默认
app.setTheme(MATERIAL_THEME_DARK);
```text

或者自己派生一个类,在 `init()` 里改默认主题:

```cpp
class DarkMaterialApplication : public MaterialApplication {
protected:
    void init() override {
        MaterialApplication::init();  // 先让基类注册完主题
        setTheme(MATERIAL_THEME_DARK);  // 然后改默认
    }
};
```text

⚠️ 不要在 `MaterialApplication::init()` 里改默认主题再调用基类 `init()`——因为基类的 `init()` 会创建动画工厂,此时默认主题还是亮色的。要么在构造后改,要么在派生类的 `init()` 里先调基类 `init()` 再改。

## 和裸 Application 的区别

直接用 `Application` 需要自己注册主题和动画工厂:

```cpp
// 用裸 Application 需要这些额外步骤
Application app(argc, argv);

Application::registerAnimationFactoryType("theme.material", ...);
themeManager()->insert_one("theme.material.light", ...);
themeManager()->setThemeTo("theme.material.light", false);

app.init();  // 别忘了手动调用 init()
```text

而 `MaterialApplication` 把这些都包圆了,构造完就能用。如果你用 Material Design 3,没理由不用它。

## 相关文档

- [Application - 应用基础类](./application.md)
- [Material 主题系统](../material/cfmaterial_theme.md)
- [Material 动画](../material/animation/index.md)

Built with VitePress