Управление графическим интерфейсом C # Winforms с IronPython - PullRequest
3 голосов
/ 04 августа 2010

Итак, я создал графический интерфейс Winforms в Visual Studio, используя C #, но для проекта, над которым я работаю, я хочу, чтобы большая часть кода была написана на Python.Я надеюсь, что «движок» будет написан на python (для переносимости), а затем я смогу поменять интерфейс приложения.

Я сделал проект C # скомпилированным в .dll и смогимпортировать классы в сценарий IronPython и нормально запустить графический интерфейс.

Проблема в том, что запуск графического интерфейса пользователя останавливает выполнение скрипта Python, если я не поместил его в отдельный поток.Однако, если я помещаю графический интерфейс в отдельный поток и пытаюсь использовать исходный поток python для изменения информации о состоянии, я получаю исключение об изменении элемента управления из потока, отличного от того, который его создал.

Есть лихороший способ связи с потоком GUI или способ выполнить то, что я пытаюсь сделать?

Драйвер C # GUI:

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 ]

3 голосов
/ 04 августа 2010

Поместите все после вызова 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 голос
/ 04 августа 2010

Элементы управления имеют сходство потоков и могут быть доступны только тем потокам, которые их создали. Существует объект BackgroundWorker, который довольно хорошо обрабатывает передачу данных между потоками.

0 голосов
/ 05 августа 2010

Если вы хотите изменить GUI из потока, отличного от потока GUI, вы должны использовать метод Invoke.

...