2010-08-04 3 views
3

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

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

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

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

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

И сценарий питона:

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

Положите все после вызова 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) 
+0

Это решение похоже именно на то, что я искал, но когда я пытаюсь сделать это, как показано, код в функции onload() не запускается. Если я просто разместил там инструкцию печати, ничего не распечатывается после запуска GUI. Любые идеи почему? Спасибо за вашу помощь! –

+0

Я не уверен, почему. Попробуйте создать экземпляр класса MainWindow из python и напрямую добавить обработчик событий, который работал для меня в прошлом. –

+0

Вы также можете разбить код C#, чтобы увидеть, действительно ли обработчик событий зарегистрирован. –

1

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

0

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

Смежные вопросы