Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9749

【WPF】Pythonの標準出力をリアルタイムに表示する

$
0
0
Pythonで機械学習を回すGUIアプリを作っているときに、進捗状況を確認できればいいなーと思い色々調べたのでメモ コード 結果から言うとこれで上手いこといきました。恐らくこれが一番シンプルだと思います。 sumple.pyの出力結果を非同期で取得して、textbox(名前はtb1)に表示しています。 sumple.pyは1秒ずつ文字列を出力するだけのプログラムです。 GUIにはボタンとtextboxだけ置いてます。 MainWindow.xaml.cs using System; using System.Windows; using System.Diagnostics; namespace ConsoleRead { public partial class MainWindow : Window { Process pr = null; public MainWindow() { InitializeComponent(); } private void Button_Start(object sender, RoutedEventArgs e) { HeavyMethod(); } /// <summary> /// pythonコードを非同期で実行 /// <summary> public void HeavyMethod() { pr = new Process(); // pythonファイル(sumple.py)の指定 pr.StartInfo.FileName = "python.exe"; pr.StartInfo.Arguments = "-u sumple.py"; // コンソール画面を表示させない pr.StartInfo.CreateNoWindow = true; // 非同期実行に必要 pr.StartInfo.UseShellExecute = false; pr.StartInfo.RedirectStandardOutput = true; // イベントハンドラ登録(標準出力時) pr.OutputDataReceived += process_DataReceived; // イベントハンドラ登録(プロセス終了時) pr.EnableRaisingEvents = true; pr.Exited += onExited; pr.Start(); pr.BeginOutputReadLine(); //非同期で標準出力読み取り } /// <summary> /// 標準出力があった時に実行 /// </summary> public void process_DataReceived(object sender, DataReceivedEventArgs e) { string output = e.Data + "\r\n"; Dispatcher.BeginInvoke(new Action(() => { tb1.Text += output; })); } /// <summary> /// プロセス終了時に実行 /// </summary> public void onExited(object sender, EventArgs e) { if (pr != null) { pr.Close(); pr.Dispose(); MessageBox.Show("end"); } } } } sumple.py import time for i in range(10): time.sleep(1) print("process" ,i*1) } ポイント 1. 非同期実行 pr.BeginOutputReadLine() を記述することで非同期で標準出力を読み取ることができます。 2. 標準出力の検知 process.OutputDataReceived にメソッドを追加することで、標準出力が行われたときに処理をすることができます。 3. UIスレッドからのtextboxの操作 BeginInvoke でUIスレッドに戻してからtb1に結果を追加しています。 4. python実行時に-uオプションを付ける これを付けないと標準出力が最後にまとめて表示されます。 これで半日悩んで結局teratailに質問投げたんですが、小一時間で回答が返ってきて解決してしまいインターネットしゅごい…となりました。 余談 最初async/awaitを使っていたのですが、awaitを使うとpythonの実行が終わるまで待たなければならず上手くいきませんでした。 標準出力が一つだけのコードを繰り返し使うような場合には良いかもしれません。 注意 全体的にふんわりとした理解なので(特にイベントハンドラ周り)、間違ったことを言っている可能性は十二分にあります。 何かありましたらご指摘いただけると有難いです。 参考 C# GUIアプリケーションからPythonスクリプトを実行する https://qiita.com/kimisyo/items/0879fc9f1315e2abfd1f 非同期で標準出力(コンソールアプリケーション)の内容をプログラムで受け取る - C#プログラミング https://www.ipentec.com/document/csharp-get-standard-output-async Taskを極めろ!async/await完全攻略 https://qiita.com/acple@github/items/8f63aacb13de9954c5da

Viewing all articles
Browse latest Browse all 9749

Trending Articles