GoForum › 🌐 V2EX

Flut, 用 Python 写 Flutter

yangyuan · 2026-04-09 13:20 · 0 次点赞 · 0 条回复

GitHub: https://github.com/yangyuan/flut/ PYPI: https://pypi.org/project/flut/

用法

安装:pip install flut

// 正常用 Dart 写 Flutter 是这样
Container(
  padding: EdgeInsets.all(16),
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(8),
  ),
  child: Text('Hello'),
)

# 在 Python 用 Flut 就是这样
Container(
  padding=EdgeInsets.all(16),
  decoration=BoxDecoration(
    color=Colors.blue,
    borderRadius=BorderRadius.circular(8),
  ),
  child=Text('Hello'),
)

原始的 Flutter contract ,执行时被映射到 flutter 真实的代码。所以是真实的 Flutter 在运行。

这是针对桌面的 SDK ,目标不是一个发布产品的 SDK 而是一个快速做点小桌面应用的包。

比如:学生的大作业,科研做点小 demo ;需要 Python 又想要有个不需要配置的 UI ,这样的场景。再比如我自己用这个做了个本地桌面 Agent ,我自己觉得比命令行好用就行。

  • 设计上,原则是原生 1:1 对应,Python 这边写的啥样,就在 Flutter 这里 1:1 照搬执行。
  • 异步集成设计上基本遵照了 Libuv ,Electron ,Chromium 的做法,不敢说没 bug, 但设计绝对是产品级的。
  • 性能上,FFI 期间的确需要序列化,会带来理论上的损失。实际执行上,只要设备不太差,性能损失和事件延时是无感的。我 4 年老本上维持 120hz 动画和无延时拖拽,Catalog 里有一些样例。
  • 内存生命周期上,以及 flutter 覆盖度上,还有很大改进空间。

自己画的图标:

flut

catalog app https://github.com/yangyuan/flut/tree/master/examples/catalog 做的比较粗糙,但主要能看常见支持的功能。

一个简单但完整能跑的例子:

from flut import run_app
from flut.flutter.widgets import StatelessWidget, StatefulWidget, State, Text, Center, Column, Icon
from flut.flutter.material import MaterialApp, Scaffold, AppBar, FloatingActionButton, Icons, ThemeData, ColorScheme, Colors, Theme
from flut.flutter.rendering import MainAxisAlignment


class MyApp(StatelessWidget):
    def build(self, context):
        return MaterialApp(
            title="Flut Demo",
            theme=ThemeData(
                colorScheme=ColorScheme.fromSeed(seedColor=Colors.deepPurple),
            ),
            home=MyHomePage(title="Flut Demo Home Page"),
        )


class MyHomePage(StatefulWidget):
    def __init__(self, title):
        super().__init__()
        self.title = title

    def createState(self):
        return _MyHomePageState()


class _MyHomePageState(State[MyHomePage]):
    def initState(self):
        self._counter = 0

    def _incrementCounter(self):
        def _update():
            self._counter += 1

        self.setState(_update)

    def build(self, context):
        return Scaffold(
            appBar=AppBar(
                title=Text(self.widget.title),
                backgroundColor=Theme.of(context).colorScheme.inversePrimary,
            ),
            body=Center(
                child=Column(
                    mainAxisAlignment=MainAxisAlignment.center,
                    children=[
                        Text("You have pushed the button this many times:"),
                        Text(
                            f"{self._counter}",
                            style=Theme.of(context).textTheme.headlineMedium,
                        ),
                    ],
                ),
            ),
            floatingActionButton=FloatingActionButton(
                onPressed=self._incrementCounter,
                tooltip="Increment",
                child=Icon(Icons.add),
            ),
        )


if __name__ == "__main__":
    run_app(MyApp())

0 条回复
添加回复
你还需要 登录 后发表回复

登录后可发帖和回复

登录 注册
主题信息
作者: yangyuan
发布: 2026-04-09
点赞: 0
回复: 0