Python 调用.NET类库

PythonNet 是一个 Python 包,允许在 Python 中与 .NET 运行时环境无缝集成,兼容 Python 2.7 以及 Python 3.5-3.7 。本文以 Python 调用 .NET System.Windows.Forms 为例,演示 PythonNet 的使用方法。

安装

PythonNet 支持 pip 方式安装:

pip install pythonnet

创建 WinForm App 项目

用一个简单的示例,演示 Python 调用 .NET 的方法。首先我们使用 Visual Studio 2019 创建一个 WinForm App 项目:


项目只有一个 Form: Form1,Form1 设计时界面如下:


Form1 的主要代码为下面的两个文件:

- Form1.cs: 开发者的代码放在 Form1.cs 文件中
- Form1.Desiner.cs : WinForm  设计器自动生成的代码,不建议修改

设计器的生成的界面代码都在 Form1.Desiner.cs 文件中。打开这个文件,主要关注 InitializeComponent 这个 private 方法。界面的主要代码都在这个方法中。

private void InitializeComponent() {
    this.textBox1 = new System.Windows.Forms.TextBox();
    this.button1 = new System.Windows.Forms.Button();
    this.SuspendLayout();
    // 
    // textBox1
    // 
    this.textBox1.Location = new System.Drawing.Point(156, 48);
    this.textBox1.Name = "textBox1";
    this.textBox1.Size = new System.Drawing.Size(290, 21);
    this.textBox1.TabIndex = 0;
    this.textBox1.Text = "Helllo World";
    // 
    // button1
    // 
    this.button1.Location = new System.Drawing.Point(156, 140);
    this.button1.Name = "button1";
    this.button1.Size = new System.Drawing.Size(147, 23);
    this.button1.TabIndex = 1;
    this.button1.Text = "Click Me";
    this.button1.UseVisualStyleBackColor = true;
    this.button1.Click += new System.EventHandler(this.Button1_Click);
    // 
    // Form1
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(709, 354);
    this.Controls.Add(this.button1);
    this.Controls.Add(this.textBox1);
    this.Name = "Form1";
    this.Text = "Form1";
    this.ResumeLayout(false);
    this.PerformLayout();
}

这段代码主要是创建一个 TextBox 控件,一个 Button 控件,设置属性,然后加载到 Form 中。我们将代码移植到 Python 中。

导入模块

PythonNet 允许 CLR 像 Python 自身的 package 一样使用,其他的模块和 package 则需要导入,就像下面的语句:

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Form

然后,编写一个 HelloForm 类,从 WinForm 继承:

from System.Drawing import Size, Point
import System.Windows.Forms as WinForms


class HelloForm(WinForms.Form):

    def __init__(self):
        self.textBox1 = WinForms.TextBox()
        self.button1 = WinForms.Button()
        self.SuspendLayout()

        # textBox1
        self.textBox1.Location = Point(156, 48)
        self.textBox1.Name = "textBox1"
        self.textBox1.Size = Size(290, 21)
        self.textBox1.TabIndex = 0
        self.textBox1.Text = "Helllo World"

        # button1
        self.button1.Location = Point(156, 140)
        self.button1.Name = "button1"
        self.button1.Size = Size(147, 23)
        self.button1.TabIndex = 1
        self.button1.Text = "Click Me"
        self.button1.UseVisualStyleBackColor = True
        self.button1.Click += self.button_Click

        # Form1
        self.AutoScaleMode = WinForms.AutoScaleMode.Font
        self.ClientSize = Size(709, 354)
        self.Controls.Add(self.button1)
        self.Controls.Add(self.textBox1)
        self.Name = "Form1"
        self.Text = "Form1"
        self.ResumeLayout(False)
        self.PerformLayout()        

    def button_Click(self, sender, args):
        """Button click event handler"""
        WinForms.MessageBox.Show("Hello, there.")

__init__ 方法与 InitComponent 方法比较,可以看出,主要的区别在于不同语言的语法,而方法、方法的调用则基本类似。更精妙的是,Python 以类似的语法实现了 .NET 的事件:

this.button1.Click += new System.EventHandler(this.Button1_Click)
self.button1.Click += self.button_Click

再比较下 button click 事件的代码:

private void Button1_Click(object sender, EventArgs e) {
    MessageBox.Show("Hello, there!");
}
def button_Click(self, sender, args):
    WinForms.MessageBox.Show("Hello, there.")

WinForm 的启动代码在 program.cs 文件中:


在 Python 中,定义一个 main 函数:

def main():
    form = HelloForm()
    app = WinForms.Application

    app.Run(form)

最后给出 Python 的完整代码:

import clr

clr.AddReference("System.Windows.Forms")

from System.Drawing import Size, Point
import System.Windows.Forms as WinForms


class HelloForm(WinForms.Form):

    def __init__(self):
        self.textBox1 = WinForms.TextBox()
        self.button1 = WinForms.Button()
        self.SuspendLayout()

        # textBox1
        self.textBox1.Location = Point(156, 48)
        self.textBox1.Name = "textBox1"
        self.textBox1.Size = Size(290, 21)
        self.textBox1.TabIndex = 0
        self.textBox1.Text = "Helllo World"

        # button1
        self.button1.Location = Point(156, 140)
        self.button1.Name = "button1"
        self.button1.Size = Size(147, 23)
        self.button1.TabIndex = 1
        self.button1.Text = "Click Me"
        self.button1.UseVisualStyleBackColor = True
        self.button1.Click += self.button_Click

        # Form1
        self.AutoScaleMode = WinForms.AutoScaleMode.Font
        self.ClientSize = Size(709, 354)
        self.Controls.Add(self.button1)
        self.Controls.Add(self.textBox1)
        self.Name = "Form1"
        self.Text = "Form1"
        self.ResumeLayout(False)
        self.PerformLayout()        

def button_Click(self, sender, args):
    """Button click event handler"""
    print("Click")
    WinForms.MessageBox.Show("Hello, there.")


def main():
    form = HelloForm()
    app = WinForms.Application

    app.Run(form)


if __name__ == '__main__':
    main()

代码

github : pythonnet-winform-hello

参考

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值