前言:
此刻兄弟们对“python怎么调用c”大体比较看重,你们都想要知道一些“python怎么调用c”的相关内容。那么小编也在网上搜集了一些有关“python怎么调用c””的相关资讯,希望大家能喜欢,朋友们一起来学习一下吧!整体思路就是将C#的windows窗体打包成动态链接库进行调用,只是要处理一些线程细节。这里用c#写一个无边框窗体来显示python程序的消息为例,演示如何实现调用功能。
首先,用Visual studio2022 创建一个 .Net Framemork 4.7.2 的类库 WinFormDll 项目,添加一个窗体FlatForm,在窗体设计器中进行设计,然后添加一个类WinForm来调用这个FlatForm.
Visual studio2022如图一
Python 调用示例如图二
运行效果如图三
相关源代码分别如下:
FlatForm.cs,注意需要额外手工添加对System.Windows.Forms的引用
using Python.Runtime;using System;using System.Drawing;using System.Windows.Forms;namespace WinFormDll{ public partial class FlatForm : Form { bool mousedown = false; Point mPoint; public FlatForm() { InitializeComponent(); this.ControlBox = false; this.FormBorderStyle = FormBorderStyle.None; } delegate void SetLabelTextCallBack(string message, Label txt, bool NewLine, Color textColor, bool IsAppend, int MaxLine = 0); delegate void SetContextMenuCallBack(ToolStripItemClickedEventArgs e); public void SetLabelText(string message, Label LableText, bool NewLine,Color color, bool IsAppend = true, int MaxLine = 0) { if (LableText.InvokeRequired) { SetLabelTextCallBack d = new SetLabelTextCallBack(SetLabelText); this?.Invoke(d, new object[] { message, LableText, NewLine,color, IsAppend, MaxLine }); } else { if (this == null || LableText.IsDisposed) return; if (MaxLine < 0) MaxLine = 0; LableText.ForeColor = color; if (IsAppend == true) { if (MaxLine == 0) { if (NewLine) { LableText.Text = LableText.Text + "\n" + message; } else { string[] var=LableText.Text.Split('\n'); var[var.Length-1] = message; string svar = ""; for(int i=0;i<var.Length; i++) { svar +=var[i]; } LableText.Text =svar; } } else { string[] Lines = LableText.Text.Split('\n'); int li = Lines.Length; int ic = Math.Min(li, MaxLine); string s = ""; for (int i = li - ic; i < li; i++) { s = s + Lines[i]; } if (NewLine) { LableText.Text = s + message + "\n"; } else { string[] var = LableText.Text.Split('\n'); var[var.Length-1] = message; string svar = ""; for (int i = 0; i<var.Length; i++) { svar +=var[i]; } LableText.Text =svar; } } } else { LableText.Text = message; } } } public void SendMessage(string msg,bool NewLine=true, Color color = new Color()) { if (color.IsEmpty) color = Color.FromArgb(0xFF, 127, 127, 127); string s = label1.Text; if (s.Contains(msg)) { int index = s.IndexOf('\n'); string ss = s.Substring(index + 1, s.Length - index - 1); SetLabelText($"", label1, NewLine, color, false, 2); string tmp = $"{ss}{msg}({DateTime.Now.ToLongTimeString()})"; if (msg.Length > 50) { tmp = $"{ss}{msg}"; } SetLabelText(tmp, label1, NewLine, color, true, 2); } else { string tmp = $"\n{msg}({DateTime.Now.ToLongTimeString()})"; if (msg.Length > 50) { tmp = $"\n{msg}"; } SetLabelText(tmp, label1, NewLine, color, true, 2); } } public void SetContextMenu(ToolStripItemClickedEventArgs e) { if (contextMenuStrip1.InvokeRequired) { SetContextMenuCallBack d = new SetContextMenuCallBack(SetContextMenu); this?.Invoke(d, new object[] {e}); } else { MenuClicked(e); } } private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { MenuClicked(e); } public virtual void MenuClicked(ToolStripItemClickedEventArgs e) { switch (e.ClickedItem.Text) { case "退出": Close(); break; case "开始": using (Py.GIL()) { dynamic deskbot = Py.Import("deskbot"); deskbot.robot.bstop=false; } break; case "停止": using (Py.GIL()) { dynamic deskbot = Py.Import("deskbot"); deskbot.robot.bstop=true; } break; } } public virtual void frmMain_Load(object sender, EventArgs e) { this.Height = 35; Rectangle rec = Screen.GetWorkingArea(this.ClientRectangle); this.Left = rec.Width - this.Width; this.Top = rec.Height - this.Height - 5; } private void frmMain_FormClosing(object sender, FormClosingEventArgs e) { notifyIcon1.Visible = false; notifyIcon1.Dispose(); } private void frmMain_FormClosed(object sender, FormClosedEventArgs e) { System.Environment.Exit(0); } private void frmMain_SizeChanged(object sender, EventArgs e) { if (this.WindowState == FormWindowState.Minimized) //判断是否最小化 { this.ShowInTaskbar = false; //不显示在系统任务栏 notifyIcon1.Visible = true; //托盘图标可见 } else { this.ShowInTaskbar = true; //不显示在系统任务栏 notifyIcon1.Visible = false; //托盘图标不可见 } } private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) { if (this.WindowState == System.Windows.Forms.FormWindowState.Minimized) this.WindowState = System.Windows.Forms.FormWindowState.Normal; } private void button1_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.Close(); } } private void label1_MouseMove(object sender, MouseEventArgs e) { if (mousedown) { this.Location = new Point(this.Location.X + e.X - mPoint.X, this.Location.Y + e.Y - mPoint.Y); } } private void label1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) mousedown = false; } private void label1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { mousedown = true; mPoint = new Point(e.X, e.Y); } else { this.contextMenuStrip1.Show(e.X + this.Location.X, e.Y + this.Location.Y); } } private void label1_MouseDoubleClick(object sender, MouseEventArgs e) { if (this.WindowState != FormWindowState.Minimized) //判断是否最小化 { this.WindowState = System.Windows.Forms.FormWindowState.Minimized; this.ShowInTaskbar = false; //不显示在系统任务栏 notifyIcon1.Visible = true; //托盘图标可见 } } }}
FlatForm.Designer.cs
namespace WinFormDll{ partial class FlatForm { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FlatForm)); this.label1 = new System.Windows.Forms.Label(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.toolStripExit = new System.Windows.Forms.ToolStripMenuItem(); this.button1 = new System.Windows.Forms.Button(); this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); this.contextMenuStrip1.SuspendLayout(); this.SuspendLayout(); // // label1 // this.label1.ContextMenuStrip = this.contextMenuStrip1; this.label1.Dock = System.Windows.Forms.DockStyle.Fill; this.label1.Location = new System.Drawing.Point(0, 0); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(317, 31); this.label1.TabIndex = 0; this.label1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.label1_MouseDoubleClick); this.label1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.label1_MouseDown); this.label1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.label1_MouseMove); this.label1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.label1_MouseUp); // // contextMenuStrip1 // this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripMenuItem2, this.toolStripMenuItem1, this.toolStripSeparator1, this.toolStripExit}); this.contextMenuStrip1.Name = "contextMenuStrip1"; this.contextMenuStrip1.Size = new System.Drawing.Size(181, 98); this.contextMenuStrip1.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.contextMenuStrip1_ItemClicked); // // toolStripExit // this.toolStripExit.Name = "toolStripExit"; this.toolStripExit.Size = new System.Drawing.Size(180, 22); this.toolStripExit.Text = "退出"; // // button1 // this.button1.BackColor = System.Drawing.SystemColors.ActiveCaption; this.button1.Dock = System.Windows.Forms.DockStyle.Right; this.button1.FlatAppearance.BorderSize = 0; this.button1.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(192))))); this.button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(192)))), ((int)(((byte)(255))))); this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.button1.ForeColor = System.Drawing.SystemColors.Highlight; this.button1.Location = new System.Drawing.Point(301, 0); this.button1.Margin = new System.Windows.Forms.Padding(0); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(16, 31); this.button1.TabIndex = 1; this.button1.Text = "X"; this.button1.UseVisualStyleBackColor = false; this.button1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.button1_MouseClick); // // notifyIcon1 // this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1; this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon"))); this.notifyIcon1.Text = "notifyIcon1"; this.notifyIcon1.Visible = true; this.notifyIcon1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon1_MouseClick); // // toolStripSeparator1 // this.toolStripSeparator1.Name = "toolStripSeparator1"; this.toolStripSeparator1.Size = new System.Drawing.Size(177, 6); // // toolStripMenuItem1 // this.toolStripMenuItem1.Name = "toolStripMenuItem1"; this.toolStripMenuItem1.Size = new System.Drawing.Size(180, 22); this.toolStripMenuItem1.Text = "停止"; // // toolStripMenuItem2 // this.toolStripMenuItem2.Name = "toolStripMenuItem2"; this.toolStripMenuItem2.Size = new System.Drawing.Size(180, 22); this.toolStripMenuItem2.Text = "开始"; // // FlatForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(317, 31); this.ContextMenuStrip = this.contextMenuStrip1; this.Controls.Add(this.button1); this.Controls.Add(this.label1); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.Name = "FlatForm"; this.Opacity = 0.9D; this.Text = "FlatForm"; this.TopMost = true; this.Load += new System.EventHandler(this.frmMain_Load); this.SizeChanged += new System.EventHandler(this.frmMain_SizeChanged); this.contextMenuStrip1.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button1; private System.Windows.Forms.NotifyIcon notifyIcon1; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; private System.Windows.Forms.ToolStripMenuItem toolStripExit; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; }}
WinForm.cs,using Python.Runtime;是为了调用了python模块的功能,可以自行进行扩展,需要额外引用 Python.Runtime;
using Python.Runtime;using System;using System.Windows.Forms;namespace WinFormDll{ public class WinForm { public static FlatForm flatform = new FlatForm(); public static Python.Runtime.PyObject myFunc; public static int add(int a, int b) { return a + b; } [STAThread]//这一行必须要加 public static void Show() { Application.Run(flatform); } public static void SendMessage(string args,bool newline=true) { flatform.SendMessage(args, newline); } public void SetFunc(Python.Runtime.PyObject func) { using (Py.GIL()) { dynamic main = Py.Import("main"); main.testclallback("test in c#"); myFunc=main.testclallback; } } }}
python调用C#窗体的代码:main.py 先将C#程序编译成WinFormDll.dll 拷贝到python程序目录下的lib目录下。main.py 代码如下:
assembly_path=r"lib\\"import sysimport timefrom threading import Threadsys.path.append(assembly_path)import clr #安装命令是 pip install pythonnet 不是 pip install clr .clr 是另一个功能的包。clr.FindAssembly('WinFormDll.dll')clr.AddReference('WinFormDll')from WinFormDll import WinFormdef testclallback(args:str): print("this is callback from c# to sendmessage:%s"%args) bp=WinForm()bp.SetFunc(testclallback)def showform(args,sec): print(args) bp.Show() print('结束')def main(): # 创建 Thread 实例 t1 = Thread(target=showform, args=('第一个线程', 5)) # 启动线程运行 t1.start() i=0 while i<100: #可以将消息发送放在你自己的业务逻辑中 bp.SendMessage("meassage is %s"%i) time.sleep(2) i+=1 # 等待所有线程执行完毕 t1.join() # join() 等待线程终止,要不然一直挂起if __name__=="__main__": main()
标签: #python怎么调用c