在本篇文章中,演示了使用IronPython,如何在一个C#WPF程序中执行python函数。
为了简单起见,这里的Python函数的功能是传入两个double,并返回它们的和。
读者仅需稍加修改,融会贯通,即可使用此方法将Python函数打包成较为精美的WPF程序。
但是这个方法仍有缺陷。
原因在于IronPython与常用的Python解释器不同,是建立在.NET上的一种Python的实现。可能不支持某些第三方库。也可能不支持较新的Python语法。其运行效率也有所不同。
如有错误,欢迎批评与指正!
1.创建WPF项目
2.添加IronPython到依赖
右键依赖项,点击关机NuGet程序包,搜索IronPython并安装
3.绘制GUI
用VS自带的编辑器绘制GUI,添加三个TextBox和一个Button
计划上面的两个TextBox用作输入,按下按钮后在下面的TextBox输出结果
将按钮和TextBox的Name如下设置,上面两个TextBox分别是TextBox1和TextBox2,下面的TextBox是TextBox3,按钮则为CalButton
4.添加Python代码
在工作目录下创建文件夹src,在其中创建文件pyCal.py
代码内容如下:
def MyAdd(a,b):
return a+b
用于实现简单的二元求和操作
在左侧的PyCal.py右键,点击属性,在右侧的属性窗口处,设置“复制到输出目录”为“始终复制”
5.编写按钮Click后执行的方法
在GUI设计界面双击按钮,Visual Studio自动生成了一个框架
先在文件头部加上
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
在接下来的程序中,将要用到ScriptEngine和ScriptScope对象来操作Python脚本,先在主类的头部先声明这两个变量。
ScriptEngine engine;
ScriptScope scope;
在入口方法MainWindow()处,初始化这两个变量
engine = Python.CreateEngine();
scope = engine.CreateScope();
这两行代码的意思是通过Python类的静态方法CreateEngine()初始化脚本引擎,再通过这个引擎来创建脚本作用域。
脚本地址是 ./src/pyCal.py
为了能够适应不同环境下路径格式的不同(Linux下分隔符用/ Windows下用\\),故调用方法System.IO.Path.Combine()
该方法可以将多个表示路径的字符串,根据当前系统的不同,选择用/或\\来分隔各个字符串,返回组合后的字符串。
string scriptPath = System.IO.Path.Combine( "src", "pyCal.py");
engine.ExecuteFile(scriptPath, scope);
运行脚本,传入两个参数,一个是刚刚生成的路径字符串scriptPath,一个是刚刚生成的作用域对象scope。
接下来开始编写点击按钮后执行的方法。
先初始化两个变量a,b,分别来接受两个TextBox传入的数字。
用double.TryParse()方法来将TextBox中的文本转换成double,如果失败,这个方法将返回false。
两个TextBox中任意一个转换失败,用消息弹框提示Wrong Input!
double.TryParse()方法用于将字符串转换为double类型,传入两个参数,一个是要转换的字符串,一个是用于接收转换结果的变量,此变量必须是out变量。如果转换成功,返回true,否则返回false(布尔类型)。类似地int也有这样的用法。
if (double.TryParse(TextBox1.Text,out a)&&double.TryParse(TextBox2.Text,out b))
{
}
else
{
MessageBox.Show("Wrong Input!");
}
用动态变量PyAddFun来管理脚本作用域中的Python函数""MyAdd
再用double变量result接收计算结果
用第三个文本框显示结果
代码部分完整代码如下:
using System.Windows;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
namespace MyApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ScriptEngine engine;
ScriptScope scope;
public MainWindow()
{
InitializeComponent();
engine = Python.CreateEngine();
scope = engine.CreateScope();
string scriptPath = System.IO.Path.Combine( "src", "pyCal.py");
engine.ExecuteFile(scriptPath, scope);
}
private void CalButton_Click(object sender, RoutedEventArgs e)
{
double a, b;
if (double.TryParse(TextBox1.Text,out a)&&double.TryParse(TextBox2.Text,out b))
{
dynamic PyAddFun = scope.GetVariable("MyAdd");
double result = PyAddFun(a, b);
TextBox3.Text = $"{result}";
}
else
{
MessageBox.Show("Wrong Input!");
}
}
}
}
6.发布程序
经过调试,程序能够正常运行
右键项目(左侧箭头处),再点击发布
选择文件夹
再选择文件夹
填入想要存放打包后程序的位置,也可以选择默认位置
弹出提示成功的窗口,关闭后,点击 显示所有设置
进行进一步的设置
目标运行时 指打包出来的程序的运行环境。
如果想要程序能够运行在一般的32位或64位windows电脑上,可以选择win-x86
设置完毕后保存
点击发布,即可生成程序
完成后,点击 导航 ,即可看到生成的程序
双击下面那个exe,即可运行程序
由于在第四步将Python代码的“复制到输出目录”为“始终复制”,在调试和发布程序时,会被自动地复制过来。
接下来,将这整个文件夹的内容(图片能看到的所有内容),整体迁移到电脑的其他位置,或者发给其他人,应该都能正常运行(前提是安装了对应版本的.Net Runtime)
如果没有安装,windows会跳出一个弹窗来提示安装。
点进去会弹出一个网页,根据这个网页的指引下载并安装即可。