龙空技术网

Python程序调用C#窗体的方法

务猿 127

前言:

此刻兄弟们对“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