使用IronPython控制C#Winforms GUI

时间:2010-08-04 03:23:26

标签: c# python winforms ironpython

所以我使用C#在Visual Studio中创建了一个Winforms GUI,但对于我正在开发的项目,我希望大部分代码都是用Python编写的。我希望用python编写“引擎”(为了便携性),然后将应用程序接口作为我可以换出的东西。

我将C#项目编译为.dll,并且能够将类导入IronPython脚本并启动GUI。

问题是运行GUI会停止执行Python脚本,除非我把它放到一个单独的线程中。但是,如果我将GUI放入一个单独的线程并尝试使用原始的python线程来更改状态信息,我会从一个不同于创建它的线程修改一个控件的例外。

有没有什么好方法可以与GUI线程进行通信,或者有什么方法可以完成我想要做的事情?

GUI的C#驱动程序:

public class Program
{
    private static MainWindow window;

    [STAThread]
    static void Main()
    {
        Program.RunGUI();
    }

    public static void RunGUI()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        window = new MainWindow();
        Application.Run(window);
    }

    public static void SetState(GameState state)
    {
        window.State = state;
    }
}

和python脚本:

import clr
clr.AddReferenceToFile("TG.Model.dll")
clr.AddReferenceToFile("TG.UI.dll")
from TG.Model import GameState
from TG.UI import Program
import thread
import time


def main():
    print "Hello!"
    state = GameState()
    print state.CharacterName
    print dir(Program)
    thread.start_new_thread(Program.RunGUI, ())
    #Program.RunGUI()
    time.sleep(2)
    Program.SetState(state)
    raw_input()


if __name__ == "__main__":
    main()

3 个答案:

答案 0 :(得分:3)

在事件处理程序中调用Program.RunGUI()之后输入所有内容。

C#:

public static void RunGUI(EventHandler onLoad)
{   
    ...

    window = new MainWindow();
    window.Load += onLoad;
    Application.Run(window);
    window.Load -= onLoad; //removes handler in case RunGUI() is called again
}

的Python:

def onload(sender, args):
    time.sleep(2)
    Program.SetState(state)
    raw_input()  

def main():
    ...
    Program.RunGUI(onload)

答案 1 :(得分:1)

控件具有线程关联性,并且只能由创建它们的线程访问。 有一个BackgroundWorker对象可以很好地处理线程之间的数据传递。

答案 2 :(得分:0)

如果要从GUI的线程以外的线程中修改GUI,则必须使用Invoke方法。