随着需求的更新、程序的逐渐壮大,现在需要在应用程序中调用外部编译器,执行相关指令并获得结果。
由于Qt
中使用的是C++
语言,自然可以调用system
去执行相关指令,但是在使用过程中发生了乱码,导致运行之后程序报错。
后来发现Qt自带的类,QProcess
,毫不犹豫转到这个上面来,但是一开始还是因为不熟悉浪费了很多时间,所以想要自己整理一下思路,因为英文文档比较难读懂,所以在此尽可能多的讲解怎么使用那些常用的API,以后还会更新。
Qt
提供了QProcess
类,这使得我们可以在应用程序中启动一个外部程序并与之交互通信。主要包括了三种启动外部命令的方式:
特点:非阻塞、一体式
void QProcess::start(const QString & program, const QStringList & arguments, OpenMode mode = ReadWrite)
使用这样的启动方式之启动外部程序启动后,它会随着主程序的退出而退出。
特点:分离式
void QProcess::startDetached(const QString & program, const QStringList & arguments, const QString & workingDirectory = QString(), qint64 * pid = 0)
外部程序启动后,当主程序退出时并不退出,而是继续运行。
特点:阻塞
int QProcess::execute()
int QProcess::exitCode()
// 从标准输出通道中读取数据
readAllStandardOutput()
// 从标准错误通道中读取数据
readAllStandardErrot()
// 设置输出到的文件,相当于前面的重定向
setStandardOutputFile()
// 设置错误到的文件
setStandardErrorFile()
// 读取标准输出
read()
readLine()
QProcess
提供了完成同步操作的函数:
以下方法会导致进程阻塞,直到符合其中的某一状态:
// 外部程序启动完毕
waitForStarted()
// 输出通道中的新数据是可读的
waitForReadyRead()
// 输入通道中的数据被写入完毕
waitForBytesWritten()
// 外部程序执行完毕
waitForFinished()
另外要注意的是,如果在主线程(QApplication::exec())中调用这些函数,可能会造成当前用户界面不响应1。
QProcess::kill()
QProcess::terminate()
QProcess::close()
启动外部程序必须要传递外部程序的路径和运行參数。參数用QStringList
来带入。
官方提供了分别设置路径或者参数的方法,可疑单独设置,也可以在一个方法中直接以参数的形式传入。
设置路径:
void QProcess::setProgram(const QString & program)
设置參数[可选]:
void QProcess:: setArguments(const QStringList & arguments)
示例
QObject *parent;
...
QString program = "./path/to/Qt/examples/widgets/analogclock";
QStringList arguments;
arguments << "-style" << "fusion";
QProcess *myProcess = new QProcess(parent);
myProcess->start(program, arguments);
当使用字符串传入一个整体命令之后,如果字符串中间有空格
或者路径中文件夹中有空格
,都是会失败的。
比如:
// 路径中带有空格,失败
process->start("C:/Program Files/execute.exe");
// 路径中有空格,但是使用传入字符串列表的argument,成功
process->start("C:/Program Files/execute.exe", QStringList("C:/Program Files/HaoZip/HaoZip.exe"));
// 或者传入空字符串,成功
QString wordPath = "C:\\Program Files\\Microsoft Office\\Office12\\WINWORD.EXE"
process->start(wordPath, QStringList() << "");
以上后两种方式成功是因为,如果使用单参数,并且路径中包含一个空格,则空格后的字符将被视为传递给可执行文件的参数。将两个参数重载,例如与空字符串一起使用,可以指定第一个参数是可执行文件的完整路径,即使它包含空格,并且后面的参数严格地作为第二个参数传递。
// 使用;或者&&同时执行两个语句,失败
process->start("ls -a && ifconfig"));
// 使用字符串列表传入目标程序目录,成功
QProcess *process = new QProcess(this);
QString program = "explorer.exe";
QString folder = "C:\\";
process->start(program, QStringList() << folder);
必要的时候某些程序需要有特定的环境来能执行,通过setEnvironment()
来环境变量设置,setWorkingDirectory()
来设置工作目录,默认的工作路径是当前调用程序的工作路径。
例如以下程序可以实现在输入框中输入命令,点击pushButton
按钮打开cmd
命令行控制台执行命令的功能。2
void MainWindow::on_pushButton_clicked()
{
ui->textEdit->clear();
QProcess process(this);
process.setProgram("cmd");
QStringList argument;
argument<<"/c"<<ui->lineEdit->text();
process.setArguments(argument);
process.start();
process.waitForStarted(); //等待程序启动
process.waitForFinished();//等待程序关闭
QString temp=QString::fromLocal8Bit(process.readAllStandardOutput()); //程序输出信息
ui->textEdit->setText(temp);
}
引用。 ↩︎
小示例 ↩︎