前面看过我文章的都知道本人喜欢用pythonnet, 温故而知新,先说python嵌入.net.
首先: 需要安装 安装.偷个懒. 贴上上次的下载脚本. 后面需要什么直接往后面添..
import os
def cmd(S="pause"):
os.system(S)
def P_install(S="mvtec-halcon==20111"):
cmd(rf"pip install {S} -i https://pypi.doubanio.com/simple")
IN_list=[
"mvtec-halcon==20111","pythonnet",
"pywin32","pyautogui","keyboard","Pyinstaller",
"pillow","numpy","opencv-python"
]
for i in IN_list:
P_install(f"{i}")
while True:
cmd(rf"pip list"); CMD=input("请输入:");
cmd(rf"pip install {CMD} -i https://pypi.doubanio.com/simple");
如果计算机只有一个python环境 并且3.5以上3.10以下理论上都可以用. 顺便提一下,3.7以下版本不支持f字符串,所以老版本需要占位符+.format(). #大概就有这么回事..
接下来:导入clr ,下来C#那一套命名空间就可以当作python自己的包导入进来了.
#--------------------------------------------------------------------------
import clr
import System
from System import String, Char, Int32,UInt16, Int64, Environment, IntPtr
print(f"{clr.AddReference('System')}")
print(f"{clr.AddReference('System.Drawing')}")
#---------------------------------------------------------------------------
导入以后,就可以开心的写程序了. 我先来,在python里用>NET,写一个图片格式转换.
from tkinter import ttk
from tkinter import messagebox
from tkinter import *
import tkinter as tk
import tkinter.messagebox
import os,sys,time
import tkinter.filedialog
from ctypes import *
from tkinter import Tk,Frame
def cmd(s="pause"):
os.system(s)
#--------------------------------------------------------------------------
import clr
import System
from System import String, Char, Int32,UInt16, Int64, Environment, IntPtr
print(f"{clr.AddReference('System')}")
print(f"{clr.AddReference('System.Drawing')}")
#---------------------------------------------------------------------------
文件名="11"
R=f"{文件名}.bmp"
W=f"{文件名}.jpg"
System.Drawing.Bitmap(f"{R}").Save(f"{W}",System.Drawing.Imaging.ImageFormat.Jpeg);
print("done!")
time.sleep(2)
#cmd()
可以看到主要就是这一句;
System.Drawing.Bitmap(f"{R}").Save(f"{W}",System.Drawing.Imaging.ImageFormat.Jpeg);
脚本同级目录放一张 "11.bmp"的图片. 运行之后 会生成 "11.jpg"的图,
尺寸从1282变成了98,尺寸缩小了十几倍.而图像精度几乎没有损失.
接下来:贴一个官方例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import clr
import System
clr.AddReference("System.Windows.Forms")
import System.Windows.Forms as WinForms
from System.IO import File
from System.Text import Encoding
from System.Drawing import Color, Point, Size
from System.Threading import ApartmentState, Thread, ThreadStart
class Wordpad(WinForms.Form):
"""A simple example winforms application similar to wordpad."""
def __init__(self):
super().__init__()
self.filename = ''
self.word_wrap = True
self.doctype = 1
self.InitializeComponent()
self.NewDocument()
def InitializeComponent(self):
"""Initialize form components."""
self.components = System.ComponentModel.Container()
self.openFileDialog = WinForms.OpenFileDialog()
self.saveFileDialog = WinForms.SaveFileDialog()
self.mainMenu = WinForms.MainMenu()
self.fileMenu = WinForms.MenuItem()
self.menuFileNew = WinForms.MenuItem()
self.menuFileOpen = WinForms.MenuItem()
self.menuFileSave = WinForms.MenuItem()
self.menuFileSaveAs = WinForms.MenuItem()
self.menuFileSep_1 = WinForms.MenuItem()
self.menuFileExit = WinForms.MenuItem()
self.editMenu = WinForms.MenuItem()
self.menuEditUndo = WinForms.MenuItem()
self.menuEditRedo = WinForms.MenuItem()
self.menuEditSep_1 = WinForms.MenuItem()
self.menuEditCut = WinForms.MenuItem()
self.menuEditCopy = WinForms.MenuItem()
self.menuEditPaste = WinForms.MenuItem()
self.menuEditSep_2 = WinForms.MenuItem()
self.menuEditSelectAll = WinForms.MenuItem()
self.formatMenu = WinForms.MenuItem()
self.menuFormatFont = WinForms.MenuItem()
self.menuFormatWordWrap = WinForms.MenuItem()
self.aboutMenu = WinForms.MenuItem()
self.menuHelpAbout = WinForms.MenuItem()
self.richTextBox = WinForms.RichTextBox()
self.statusBarPanel1 = WinForms.StatusBarPanel()
self.statusBar = WinForms.StatusBar()
self.fontDialog = WinForms.FontDialog()
self.statusBarPanel1.BeginInit()
# ===================================================================
# File Menu
# ===================================================================
self.menuFileNew.Text = "&New"
self.menuFileNew.Shortcut = WinForms.Shortcut.CtrlN
self.menuFileNew.ShowShortcut = False
self.menuFileNew.Index = 0
self.menuFileNew.Click += self.OnClickFileNew
self.menuFileOpen.Text = "&Open"
self.menuFileOpen.Shortcut = WinForms.Shortcut.CtrlO
self.menuFileOpen.ShowShortcut = False
self.menuFileOpen.Index = 1
self.menuFileOpen.Click += self.OnClickFileOpen
self.menuFileSave.Text = "&Save"
self.menuFileSave.Shortcut = WinForms.Shortcut.CtrlS
self.menuFileSave.ShowShortcut = False
self.menuFileSave.Index = 2
self.menuFileSave.Click += self.OnClickFileSave
self.menuFileSaveAs.Text = "Save &As"
self.menuFileSaveAs.Index = 3
self.menuFileSaveAs.Click += self.OnClickFileSaveAs
self.menuFileSep_1.Text = "-"
self.menuFileSep_1.Index = 4
self.menuFileExit.Text = "E&xit"
self.menuFileExit.Shortcut = WinForms.Shortcut.AltF4
self.menuFileExit.ShowShortcut = False
self.menuFileExit.Index = 5
self.menuFileExit.Click += self.OnClickFileExit
self.fileMenu.Text = "&File"
self.fileMenu.Index = 0
items = (self.menuFileNew, self.menuFileOpen,
self.menuFileSave, self.menuFileSaveAs,
self.menuFileSep_1, self.menuFileExit)
self.fileMenu.MenuItems.AddRange(items)
# ===================================================================
# Edit menu
# ===================================================================
self.menuEditUndo.Text = "&Undo"
self.menuEditUndo.Shortcut = WinForms.Shortcut.CtrlZ
self.menuEditUndo.Index = 0
self.menuEditUndo.Click += self.OnClickEditUndo
self.menuEditRedo.Text = "&Redo"
self.menuEditRedo.Shortcut = WinForms.Shortcut.CtrlY
self.menuEditRedo.Index = 1
self.menuEditRedo.Click += self.OnClickEditRedo
self.menuEditSep_1.Text = "-"
self.menuEditSep_1.Index = 2
self.menuEditCut.Text = "Cut"
self.menuEditCut.Shortcut = WinForms.Shortcut.CtrlX
self.menuEditCut.Index = 3
self.menuEditCut.Click += self.OnClickEditCut
self.menuEditCopy.Text = "Copy"
self.menuEditCopy.Shortcut = WinForms.Shortcut.CtrlC
self.menuEditCopy.Index = 4
self.menuEditCopy.Click += self.OnClickEditCopy
self.menuEditPaste.Text = "Paste"
self.menuEditPaste.Shortcut = WinForms.Shortcut.CtrlV
self.menuEditPaste.Index = 5
self.menuEditPaste.Click += self.OnClickEditPaste
self.menuEditSelectAll.Text = "Select All"
self.menuEditSelectAll.Shortcut = WinForms.Shortcut.CtrlA
self.menuEditSelectAll.Index = 7
self.menuEditSelectAll.Click += self.OnClickEditSelectAll
self.menuEditSep_2.Text = "-"
self.menuEditSep_2.Index = 6
self.editMenu.Text = "&Edit"
self.editMenu.Index = 1
items = (self.menuEditUndo, self.menuEditRedo,
self.menuEditSep_1, self.menuEditCut,
self.menuEditCopy, self.menuEditPaste,
self.menuEditSep_2, self.menuEditSelectAll)
self.editMenu.MenuItems.AddRange(items)
# ===================================================================
# Format Menu
# ===================================================================
self.menuFormatWordWrap.Text = "Word Wrap"
self.menuFormatWordWrap.Checked = self.word_wrap
self.menuFormatWordWrap.Index = 1
self.menuFormatWordWrap.Click += self.OnClickFormatWordWrap
self.menuFormatFont.Text = "Fo&nt"
self.menuFormatFont.Index = 0
self.menuFormatFont.Click += self.OnClickFormatFont
self.formatMenu.Text = "F&ormat"
self.formatMenu.Index = 2
items = (self.menuFormatWordWrap, self.menuFormatFont)
self.formatMenu.MenuItems.AddRange(items)
# ===================================================================
# About menu
# ===================================================================
self.menuHelpAbout.Text = "&About"
self.menuHelpAbout.Index = 0
self.menuHelpAbout.Click += self.OnClickHelpAbout
self.aboutMenu.Text = "&Help"
self.aboutMenu.Index = 3
self.aboutMenu.MenuItems.Add(self.menuHelpAbout)
self.statusBarPanel1.Dock = WinForms.DockStyle.Fill
self.statusBarPanel1.Text = "Ready"
self.statusBarPanel1.Width = 755
self.richTextBox.Dock = WinForms.DockStyle.Fill
self.richTextBox.Size = System.Drawing.Size(795, 485)
self.richTextBox.TabIndex = 0
self.richTextBox.AutoSize = True
self.richTextBox.ScrollBars = WinForms.RichTextBoxScrollBars.ForcedBoth
self.richTextBox.Font = System.Drawing.Font("Tahoma", 10.0)
self.richTextBox.AcceptsTab = True
self.richTextBox.Location = System.Drawing.Point(0, 0)
self.statusBar.BackColor = System.Drawing.SystemColors.Control
self.statusBar.Location = System.Drawing.Point(0, 518)
self.statusBar.Size = System.Drawing.Size(775, 19)
self.statusBar.TabIndex = 1
self.statusBar.ShowPanels = True
self.statusBar.Panels.Add(self.statusBarPanel1)
items = (self.fileMenu, self.editMenu, self.formatMenu, self.aboutMenu)
self.mainMenu.MenuItems.AddRange(items)
self.openFileDialog.Filter = "Text documents|*.txt|RTF document|*.rtf"
self.openFileDialog.Title = "Open document"
self.saveFileDialog.Filter = "Text Documents|*.txt|" \
"Rich Text Format|*.rtf"
self.saveFileDialog.Title = "Save document"
self.saveFileDialog.FileName = "Untitled"
self.AutoScaleBaseSize = System.Drawing.Size(5, 13)
self.ClientSize = System.Drawing.Size(775, 537)
self.Menu = self.mainMenu
self.Text = "Python Wordpad"
self.Controls.Add(self.statusBar)
self.Controls.Add(self.richTextBox)
self.statusBarPanel1.EndInit()
def Dispose(self):
self.components.Dispose()
WinForms.Form.Dispose(self)
def OnClickFileNew(self, sender, args):
self.SaveChangesDialog()
self.NewDocument()
def OnClickFileOpen(self, sender, args):
self.SaveChangesDialog()
self.OpenDocument()
def OnClickFileSave(self, sender, args):
self.SaveDocument()
def OnClickFileSaveAs(self, sender, args):
self.filename = ''
self.SaveDocument()
def OnClickFileExit(self, sender, args):
self.SaveChangesDialog()
self.Close()
def OnClickEditUndo(self, sender, args):
self.richTextBox.Undo()
def OnClickEditRedo(self, sender, args):
self.richTextBox.Redo()
def OnClickEditCut(self, sender, args):
self.richTextBox.Cut()
def OnClickEditCopy(self, sender, args):
self.richTextBox.Copy()
def OnClickEditPaste(self, sender, args):
self.richTextBox.Paste()
def OnClickEditSelectAll(self, sender, args):
self.richTextBox.SelectAll()
def OnClickFormatWordWrap(self, sender, args):
value = not self.word_wrap
self.richTextBox.WordWrap = value
self.menuFormatWordWrap.Checked = value
self.word_wrap = value
def OnClickFormatFont(self, sender, args):
if self.fontDialog.ShowDialog() == WinForms.DialogResult.OK:
self.richTextBox.SelectionFont = self.fontDialog.Font
def OnClickHelpAbout(self, sender, args):
AboutForm().ShowDialog(self)
def NewDocument(self):
self.doctype = 1
self.richTextBox.Rtf = ''
self.richTextBox.Text = ''
self.Text = 'Python Wordpad - (New Document)'
self.filename = ''
def OpenDocument(self):
if self.openFileDialog.ShowDialog() != WinForms.DialogResult.OK:
return
filename = self.openFileDialog.FileName
stream = File.OpenRead(filename)
buff = System.Array.CreateInstance(System.Byte, 1024)
buff.Initialize()
data = []
read = 1
while read > 0:
read, _ = stream.Read(buff, 0, 1024)
temp = Encoding.ASCII.GetString(buff, 0, read)
data.append(temp)
data = ''.join(data)
stream.Close()
filename = self.filename = filename.lower()
if filename.endswith('.rtf'):
self.richTextBox.Rtf = data
self.doctype = 2
else:
self.richTextBox.Text = data
self.doctype = 1
self.Text = 'Python Wordpad - %s' % filename
self.richTextBox.Select(0, 0)
def SaveDocument(self):
filename = self.filename
if not filename:
if self.saveFileDialog.ShowDialog() != WinForms.DialogResult.OK:
return
filename = self.saveFileDialog.FileName
filename = self.filename = filename.lower()
self.Text = 'Python Wordpad - %s' % filename
self.richTextBox.Select(0, 0)
stream = File.OpenWrite(filename)
if filename.endswith('.rtf'):
data = self.richTextBox.Rtf
else:
data = self.richTextBox.Text
data = System.Text.Encoding.ASCII.GetBytes(System.String(data))
stream.Write(data, 0, data.Length)
stream.Close()
def SaveChangesDialog(self):
if self.richTextBox.Modified:
if WinForms.MessageBox.Show(
"Save changes?", "Word Pad",
WinForms.MessageBoxButtons.OK |
WinForms.MessageBoxButtons.YesNo
) == WinForms.DialogResult.Yes:
self.SaveDocument()
return 1
return 0
class AboutForm(WinForms.Form):
def __init__(self):
super().__init__()
self.InitializeComponent()
def InitializeComponent(self):
"""Initialize form components."""
self.Text = "Python Wordpad"
self.components = System.ComponentModel.Container()
self.btnClose = WinForms.Button()
self.label1 = WinForms.Label()
self.SuspendLayout()
self.btnClose.Location = System.Drawing.Point(360, 181)
self.btnClose.Name = "bnClose"
self.btnClose.TabIndex = 1
self.btnClose.Text = "&Close"
self.btnClose.Click += self.OnClickClose
self.label1.Location = System.Drawing.Point(20, 20)
self.label1.Name = "label1"
self.label1.Size = System.Drawing.Size(296, 140)
self.label1.TabIndex = 2
self.label1.Text = "Python Wordpad - an example winforms " \
"application using Python.NET"
self.AutoScaleBaseSize = System.Drawing.Size(5, 13)
self.ClientSize = System.Drawing.Size(300, 150)
self.Controls.AddRange((self.label1, self.btnClose))
self.FormBorderStyle = WinForms.FormBorderStyle.FixedDialog
self.MaximizeBox = False
self.MinimizeBox = False
self.Name = "AboutForm"
self.ShowInTaskbar = False
self.StartPosition = WinForms.FormStartPosition.CenterScreen
self.Text = "About"
self.ResumeLayout(False)
def OnClickClose(self, sender, args):
self.Close()
def app_thread():
app = Wordpad()
WinForms.Application.Run(app)
app.Dispose()
def main():
thread = Thread(ThreadStart(app_thread))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()
if __name__ == '__main__':
main()
这是完全把winform拿过来了啊??!!,以后写python 带UI的可以直接 py-winform.
还没完:继续.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import clr
import System
clr.AddReference("System.Windows.Forms")
import System.Windows.Forms as WinForms
from System.Drawing import Color, Size, Point
class Splitter(WinForms.Form):
"""A WinForms example transcribed to Python from the MSDN article:
'Creating a Multipane User Interface with Windows Forms'."""
def __init__(self):
super().__init__()
# Create an instance of each control being used.
self.components = System.ComponentModel.Container()
self.treeView1 = WinForms.TreeView()
self.listView1 = WinForms.ListView()
self.richTextBox1 = WinForms.RichTextBox()
self.splitter1 = WinForms.Splitter()
self.splitter2 = WinForms.Splitter()
self.panel1 = WinForms.Panel()
# Set properties of TreeView control.
self.treeView1.Dock = WinForms.DockStyle.Left
self.treeView1.Width = self.ClientSize.Width // 3
self.treeView1.TabIndex = 0
self.treeView1.Nodes.Add("TreeView")
# Set properties of ListView control.
self.listView1.Dock = WinForms.DockStyle.Top
self.listView1.Height = self.ClientSize.Height * 2 // 3
self.listView1.TabIndex = 0
self.listView1.Items.Add("ListView")
# Set properties of RichTextBox control.
self.richTextBox1.Dock = WinForms.DockStyle.Fill
self.richTextBox1.TabIndex = 2
self.richTextBox1.Text = "richTextBox1"
# Set properties of Panel's Splitter control.
self.splitter2.Dock = WinForms.DockStyle.Top
# Width is irrelevant if splitter is docked to Top.
self.splitter2.Height = 3
# Use a different color to distinguish the two splitters.
self.splitter2.BackColor = Color.Blue
self.splitter2.TabIndex = 1
# Set TabStop to false for ease of use when negotiating UI.
self.splitter2.TabStop = False
# Set properties of Form's Splitter control.
self.splitter1.Location = System.Drawing.Point(121, 0)
self.splitter1.Size = System.Drawing.Size(3, 273)
self.splitter1.BackColor = Color.Red
self.splitter1.TabIndex = 1
# Set TabStop to false for ease of use when negotiating UI.
self.splitter1.TabStop = False
# Add the appropriate controls to the Panel.
for item in (self.richTextBox1, self.splitter2, self.listView1):
self.panel1.Controls.Add(item)
# Set properties of Panel control.
self.panel1.Dock = WinForms.DockStyle.Fill
self.panel1.TabIndex = 2
# Add the rest of the controls to the form.
for item in (self.panel1, self.splitter1, self.treeView1):
self.Controls.Add(item)
self.Text = "Intricate UI Example"
def Dispose(self):
self.components.Dispose()
WinForms.Form.Dispose(self)
def main():
app = Splitter()
WinForms.Application.Run(app)
app.Dispose()
if __name__ == '__main__':
main()
展示了 相对布局.
再来一个:hello form.
import clr
clr.AddReference("System.Windows.Forms")
import System.Windows.Forms as WinForms
from System.Drawing import Size, Point
class HelloApp(WinForms.Form):
"""A simple hello world app that demonstrates the essentials of
winforms programming and event-based programming in Python."""
def __init__(self):
super().__init__()
self.Text = "Hello World From Python"
self.AutoScaleBaseSize = Size(5, 13)
self.ClientSize = Size(392, 117)
h = WinForms.SystemInformation.CaptionHeight
self.MinimumSize = Size(392, (117 + h))
# Create the button
self.button = WinForms.Button()
self.button.Location = Point(160, 64)
self.button.Size = Size(820, 20)
self.button.TabIndex = 2
self.button.Text = "Click Me!"
# Register the event handler
self.button.Click += self.button_Click
# Create the text box
self.textbox = WinForms.TextBox()
self.textbox.Text = "Hello World"
self.textbox.TabIndex = 1
self.textbox.Size = Size(1260, 40)
self.textbox.Location = Point(160, 24)
# Add the controls to the form
self.AcceptButton = self.button
self.Controls.Add(self.button)
self.Controls.Add(self.textbox)
def button_Click(self, sender, args):
"""Button click event handler"""
print ("Click")
WinForms.MessageBox.Show("Please do not press this button again.")
def run(self):
WinForms.Application.Run(self)
def main():
form = HelloApp()
print ("form created")
app = WinForms.Application
print ("app referenced")
app.Run(form)
if __name__ == '__main__':
main()
这个运行结果就不展示了. 运行起来就可以看到.
还没完, 这个脚本展示了 WPF, 可以和 xaml 单独写
import clr
import sys
if sys.platform.lower() not in ['cli','win32']:
print("only windows is supported for wpf")
clr.AddReference(r"wpf\PresentationFramework")
from System.IO import StreamReader
from System.Windows.Markup import XamlReader
from System.Threading import Thread, ThreadStart, ApartmentState
from System.Windows import Application, Window
class MyWindow(Window):
def __init__(self):
stream = StreamReader("DynamicGrid.xaml")
window = XamlReader.Load(stream.BaseStream)
Application().Run(window)
if __name__ == '__main__':
thread = Thread(ThreadStart(MyWindow))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()
当然还有xaml.
python 里使用.NET 说完了.
接下来说一下 C# 中如何嵌入python .主要说环境怎么配. 毕竟对C# 中如何嵌入python 不熟, 况且就算真的有需求 命令行 或者网络 应该更容易上手些... 环境配置过程在注释中体现.直接上例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Python.Runtime; // 这个是 nuget下载的,并不是python安装目录里那个dll
using System.Net;
using SC= System.Console;
namespace CsPyNET
{
class Program
{
static void Main(string[] args)
{
/*
操作系统: Win10 64位:
python解释器: Python3.8.8_64位 VS2015.
配置管理器:解决方案也得是64位;
项目->属性->[目标框架].NET Fraemwork 4 {快捷键::alt+PP}
工具->NuGet包管理器->管理解决方案的NuGet程序包(N) {快捷键:alt+TNN}. [浏览->底下搜索框搜 pythonnet 出现很多选项]
pythonnet_py38_win.2.5.2
安装这个:到当前项目.
安装后:在.sln同级目录packages文件夹下会下载对应文件.
引用该文件
//using Python.Runtime;
C:\Users\Administrator\AppData\Local\Programs\Python\Python38\Lib\site-packages\pythonnet\runtime
*/
// 这是我的pythonn安装路径.
/*
"https://pythonnet.github.io/"
"将 Python 嵌入到 .NET 中 - Python.NET 文档 https://pythonnet.github.io/pythonnet/dotnet.html"
*/
string dllPath = @"C:\Users\Administrator\AppData\Local\Programs\Python\Python38\python38.dll";
string pythonHomePath = @"C:\Users\Administrator\AppData\Local\Programs\Python\Python38";
string[] py_paths =
{
"DLLs",
"Lib",// "原文是lib 我的3.8只有Lib路径,所以改成 Lib"
"Lib/site-packages",
"Lib/site-packages/win32" ,
"Lib/site-packages/win32/lib",
"Lib/site-packages/Pythonwin"
};
string pySearchPath = $"{pythonHomePath};";
foreach (string p in py_paths)
{
pySearchPath += $"{pythonHomePath}/{p};";
}
// 此处解决BadPythonDllException报错
// Runtime.PythonDLL = dllPath; //
Environment.SetEnvironmentVariable("PYTHONNET_PYDLL", dllPath);
// 配置python环境搜索路径解决PythonEngine.Initialize() 崩溃
PythonEngine.PythonHome = pythonHomePath;
PythonEngine.PythonPath = pySearchPath;
PythonEngine.Initialize();
using (Py.GIL())
{
dynamic np = Py.Import("numpy");
dynamic cv2= Py.Import("cv2");
PyObject ar = np.array(new int[] { 1, 2, 3, 4 });
SC.WriteLine(ar);
SC.WriteLine(cv2.__version__);
}
SC.WriteLine("");
SC.ReadKey();// ############### wait ############# //##################################################################################################
}//Main
//##################################################################################################
}//Program
}//CsPyNET
结束.