所以我使用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()
答案 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方法。