如何使用Starflut在Flutter中导入Python包?

4

我正在使用Flutter构建一个应用程序,需要使用一些Python代码。为此,我使用了Starflut插件(https://pub.dev/packages/starflut)。我成功地运行了Python代码,没有任何问题,但我想要导入额外的包。

为了做到这一点,我创建了一个虚拟环境,在其中放置了我的应用程序,然后通过pip安装程序下载了numpy、cv2和Pillow,下载过程没有问题。

但是,当我尝试导入numpy时,我的IDE(Visual Studio Code)告诉我有一个错误:

Unable to import 'numpy' 

这是我的 main.dart 代码(唯一的 dart 文件,它是一个测试应用程序):
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:starflut/starflut.dart';

void main() => runApp(Main());

class Main extends StatefulWidget {
  @override
  _MainState createState() => _MainState();
}

class _MainState extends State<Main> {
  var _outputString = '';
  StarSrvGroupClass srvGroup;
  dynamic python;

  _MainState() {
    _initStarCore();
  }

  void showOutput(String info) async {
    if (info == null || info.length == 0) return;
    _outputString = info;
    setState(() {});
  }

  void _initStarCore() async {
    StarCoreFactory starcore = await Starflut.getFactory();
    StarServiceClass service =
        await starcore.initSimple("test", "123", 0, 0, []);
    String resPath = await Starflut.getResourcePath();
    await starcore.regMsgCallBackP(
        (int serviceGroupID, int uMsg, Object wParam, Object lParam) async {
      if (uMsg == Starflut.MSG_DISPMSG || uMsg == Starflut.MSG_DISPLUAMSG) {
        showOutput(wParam);
      }
      print("$serviceGroupID  $uMsg   $wParam   $lParam");
      return null;
    });
    srvGroup = await service["_ServiceGroup"];
    bool isAndroid = await Starflut.isAndroid();
    if (isAndroid == true) {
      String libraryDir = await Starflut.getNativeLibraryDir();
      String docPath = await Starflut.getDocumentPath();
      if (libraryDir.indexOf("arm64") > 0) {
        Starflut.unzipFromAssets("lib-dynload-arm64.zip", docPath, true);
      } else if (libraryDir.indexOf("x86_64") > 0) {
        Starflut.unzipFromAssets("lib-dynload-x86_64.zip", docPath, true);
      } else if (libraryDir.indexOf("arm") > 0) {
        Starflut.unzipFromAssets("lib-dynload-armeabi.zip", docPath, true);
      } else {
        //x86
        Starflut.unzipFromAssets("lib-dynload-x86.zip", docPath, true);
      }
      await Starflut.copyFileFromAssets("python3.6.zip",
          "flutter_assets/starfiles", null); //desRelatePath must be null
      await Starflut.copyFileFromAssets(
          "program.py", "flutter_assets/starfiles", "flutter_assets/starfiles");
    }
    if (await srvGroup.initRaw("python36", service) == true) {
      _outputString = "init starcore and python 3.6 successfully";
    } else {
      _outputString = "init starcore and python 3.6 failed";
    }

    await srvGroup.loadRawModule("python", "",
        resPath + "/flutter_assets/starfiles/" + "program.py", false);
    python = await service.importRawContext("python", "", false, "");

    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      //_counter++;
    });
  }

  void runScriptCode() async {
    var result = await python.call("multiply", [5, 2]);
    _outputString = result.toString();

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: FlatButton(
            color: Colors.red,
            child: Text(_outputString),
            onPressed: () {
              runScriptCode();
            },
          ),
        ),
      ),
    );
  }
}

以及我的Python文件:

import numpy as np # (to test)

def multiply(a, b):
    return a*b

这是我的树形结构,如果有帮助的话: 我的Flutter项目的树形结构

希望你能帮我。

提前致谢!


你能解决这个问题吗? 我也想做同样的事情。 - Sravan Kumar
你有同样的问题吗? - ic_QCOMEngineer
你找到解决方案了吗?同样的问题。 - Mudasir Habib
@MudasirHabib - 请注意,Starflut声称是开源的,但实际上并不是;请参见Where is the source code? #27 - bitinerant
没有其他选择,Chaquopy也是付费的。三年前我在原生Android Java中使用了Chaquopy,在运行时通知栏中会提示购买许可证。 - Mudasir Habib
3个回答

2

如果您想在Android应用程序中集成Python包,可以使用chaquopy插件来进行Flutter编程。


1
请注意,使用Chaquo需要许可证(https://chaquo.com/chaquopy/license/),尽管它表示该许可证对于开源应用程序是免费的。他们在GitHub上还有一个“Android的Python SDK”(https://github.com/chaquo/chaquopy),但我认为这只是一个演示项目。我不认为Chaquopy本身是开源的。 - bitinerant
是的,这不是免费的,但如果您正在创建开源应用程序,则可以联系Chaquopy的创建者,您将获得免费许可证以供使用。 - Jay Dangar

0

仅限Android Flutter:截至上个月,Chaquopy现已开源,并且有一个Flutter插件。因此,这绝对是包含Python代码的最简单方法。


这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - General Grievance

0
如果可以的话,将Python后端连接到Flutter,因为这样你的应用程序会更加流畅。

我已经用 Flask 尝试过了,效果还不错,但是如果我想部署我的应用程序,我需要支付域名或其他费用吗?即使我部署了它,我还能使用本地服务器吗?最后一个小问题,如果我使用这种方式,库的导入会更容易吗?感谢您的回答! - Vayhuit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接