C # Winforms GUI Management with IronPython

So, I created Winforms GUI in Visual Studio using C #, but for the project I'm working on, I want most of the code written in Python. I hope the "engine" is written in python (for portability) and then the application interface will be replaced.

I compiled a C # project into a .dll and was able to import the classes into an IronPython script and run the GUI.

The problem is that running the GUI stops the execution of the Python script unless I put it in a separate thread. However, if I put the GUI in a separate thread and try to use the original python thread to change the state information, I get an exception due to the change of the control from another thread, besides the one that created it.

Is there a good way to communicate with the GUI thread or a way to accomplish what I'm trying to do?

C # driver for graphical user interface:

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;
    }
}

And the python script:

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
source share
3 answers

Put everything after the call Program.RunGUI()to the event handler.

WITH#:

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)
+3
source

, . BackgroundWorker, .

+1

If you want to change the GUI from a thread other than a GUI thread, you must use the Invoke method.

0
source

Source: https://habr.com/ru/post/1757937/


All Articles