我已经为我的python程序构建了一个winform接口,我的python程序是一个实时语音助手,我需要的是接口应该在python提供输出时立即响应。我需要立即向界面显示标准输出。以下程序就是我所做的。
在此代码中,界面没有正确响应。 python程序在后台持续执行而不响应语音。我需要一个程序来执行我的python程序并将标准输出显示到winform接口。
namespace @interface
{
public partial class Form1 : Form
{
public static string text;
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private async void start_button_Click(object sender, EventArgs e)
{
string line;
int counter=0;
msg.Text = "Hey, Tell me something!";
Task task = new Task(Execute);
task.Start();
}
public void Execute()
{
// full path of python interpreter
string python = @"C:/Users/Jayasooryan/AppData/Local/Programs/Python/Python36-32/python.exe";
// python app to call
string myPythonApp = @"C:/Users/Jayasooryan/AppData/Local/Programs/Python/Python36-32/Avira.py";
// Create new process start info
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(python);
// make sure we can read the output from stdout
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcessStartInfo.CreateNoWindow = true;
// start python app with 3 arguments
// 1st arguments is pointer to itself,
// 2nd and 3rd are actual arguments we want to send
myProcessStartInfo.Arguments = myPythonApp;
Process myProcess = new Process();
// assign start information to the process
myProcess.StartInfo = myProcessStartInfo;
// start the process
myProcess.Start();
// Read the standard output of the app we called.
// in order to avoid deadlock we will read output first
// and then wait for process terminate:
StreamReader myStreamReader = myProcess.StandardOutput;
string myString = myStreamReader.ReadLine();
text = myString;
//Console.WriteLine(myString);
/*if you need to read multiple lines, you might use:
string myString = myStreamReader.ReadToEnd() */
// wait exit signal from the app we called and then close it.
myProcess.WaitForExit();
myProcess.Close();
// write the output we got from python app
//Console.ReadLine();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
答案 0 :(得分:0)
首先:你不应该尝试从python进程中读取一行,而是在进程写入新数据时使用OutputDataReceived
事件。
第二:由于输出是缓冲的,你可能想在python进程中写入后刷新它。
所以这是一个简单的python脚本,一直写入标准输出(注意如何调用stdout.flush
):
import random
import time
import sys
while True:
rand = random.randint(1, 10)
time.sleep(1)
print rand
sys.stdout.flush()
if rand in (9, 10):
break
这是一个简单的表单,它读取该脚本的输出:
var f = new Form();
var t = new TextBox();
t.Dock = DockStyle.Fill;
t.Multiline = true;
f.Controls.Add(t);
f.Load += (s, e) => {
Process process = new Process();
process.StartInfo.FileName = "python";
process.StartInfo.Arguments = @"d:\script.py";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (s2, e2) => {
t.Text += e2.Data + Environment.NewLine;
};
process.Start();
process.BeginOutputReadLine();
};
f.ShowDialog();