一 问题产生的原因

我们的软件采用的Visual Studio 2015+Qt Creator的编译环境用C++编程语言进行开发,Python环境是采用的Python语言进行开发。在软件中的一些功能都是需要调用Python环境中的功能,在运行这些功能时软件又需要将运行时的进度,运行的结果等数据实时的显示到的界面中去方便客户查看,所以就有了软件和Python环境的实时交互问题。

二 解决问题的方法

为了解决软件与Python环境的实时交互问题设计了两种方法,第一种方法是运用线程间的通信机制,第二种方法是运用文件监视器。

1.运用线程间的通信机制

当软件需要调用Python环境时,使用Qt自带的QProcess类,QProcess这个类就相当于直接调用了Windows的控制台窗口,通过Windows窗口运行Python的指令从而调用Python环境中的功能。QProcess这个类就有QThread的功能(但它们并不是继承关系),所以QProcess就是一个线程,通过Windows的控制台运行Python的功能就是另外一个线程。

QProcess* process=new QProcess(this);

QString PythonExePath;//python应用程序的路径(根据自己的路径来初始化)

QStringList ParameterList;//python的参数列表(根据自己需要的传参来初始化)

process->start(PythonExePath,ParameterList);

Python环境通过Python中的Print()等函数,输出到Windows的控制台中,也就是输出到标准输出流。QProcess类是继承于QIODevice类,当标准输出中输入数据后会触发QIODevice类的readyReadStandardOutput()信号,然后利用Qt的信号槽机制读出标准输出流中的数据再解析到界面从而实现软件与Python环境的实时交互问题。

注意:print()函数输出时是先输出到数据缓冲区中,数据缓冲区是需要等缓冲区满了才会刷新到标准输出流中,所以为了保证实时的通信Python中的Print()函数运行后需要在后面加一句强制刷新缓存的代码

  1. 运用文件监视器

这个方法也是采用QProcess类来运行Python的功能,在Python的功能运行时,Python中会采用Log()函数来生成一个日志文件,在软件中采用QFileSystemWatcher类来对这个日志文件进行文件监控,当日志文件有数据更新时会触发fileChanged()信号,运用Qt中的信号槽机制就可以读出日志文件中更新的数据,再解析到界面从而实现软件与Python环境的实时交互问题。

注意:当我们用QProcess类来运行Python时,不能立马将被检测的日志文件添加到QFileSystemWatcher类的监视器中,因为Python刚运行时日志文件还没有生成,这个时候就把日志文件添加到监视器中,监视器找不到文件路径程序会崩溃。所以需要另外添加一个计时器来监测日志文件是否已经生成,如果日志文件已经生成则关闭计时器,并将日志文件添加到监视器中。


上面的两种方法都可以解决软件与Python环境的实时交互问题,两者的区别主要在于,进程间通信的方法需要Python环境那边调用Print()函数,文件监视器的方法则是需要Python环境那边生成日志文件,根据Python环境那边采用哪种输出方式,软件中就采用对应的接受方式接受数据,再进行数据解析和数据显示。