系列文章目录
前言
- Qt QProcess类是用于启动外部程序和与之交互的类。 它提供了一种在Qt应用程序中执行外部命令的方便方法,并且可以读取命令的输出和错误信息。
一、概述
1.1 启动进程的方式
- 分离式: 外部程序启动程序后,主程序退出时,被调用的进程继续执行,不退出。
- 一体式: 当主程序退出时,被主程序调用起来的进程也退出。
1.2 QProcess功能
-
QProcess类可以启动一个外部程序,并且可以向其发送输入,获取其输出和错误信息,以及监控其运行状态。 它可以用于执行各种类型的外部命令,包括执行脚本、运行可执行文件、打开文件等。
-
QProcess类提供了多个方法来执行外部命令,包括start()、execute()和system()等。start()方法是异步执行外部命令的方式,可以在启动命令后继续执行其他操作。execute()方法是同步执行外部命令的方式,执行命令后会等待命令执行完成再继续执行其他操作。system()方法是调用系统的命令执行外部命令的方式,它返回命令的执行结果。
-
QProcess类还提供了信号和槽机制来处理外部程序的输出和错误信息。 可以通过读取stdout和stderr的信号来获取命令的输出和错误信息 ,并且可以通过write()方法向外部程序发送输入。
二、常用方法
函数 | 描述 |
---|---|
start() | 启动一个进程 |
close() | 关闭启动的外部进程 |
write() | 向外部进程写入数据 |
readAllStandardOutput() | 读取外部进程的标准输出 |
readAllStandardError() | 读取外部进程的错误信息 |
waitForStarted() | 启动阻塞,等待程序启动完毕,期间整个程序所有进程阻塞 |
waitForFinished() | 结束阻塞,等待程序结束完毕,期间整个程序所有进程阻塞 |
waitForReadyRead() | 阻塞,直到输出通道中的新数据是可读的 |
waitForBytesWritten() | 阻塞,直到 输入通道中的数据被写入完毕 |
QProcess::execute() | 以堵塞方式的执行shell命令,当命令执行完成后,调用进程才会继续执行。命令输出的任何数据都将转发给调用进程输出(因此无法捕获) (主进程一直处于阻塞状态,等待被调用的程序完成(关闭软件)) |
QProcess::start() | 以异步方式的执行shell命令,命令输出的数据存储于缓冲区,可以通过readAllStandardOutput()捕获(当主进程关闭时,被调用的程序是随着主进程一起退出) |
QProcess::startDetached() | 以分离的方式执行shell命令,调用进程退出,则分离的进程将继续运行,而不受影响(当主进程关闭时,被调用的程序是不会退出的) |
注意:
- QProcess中start()和write()中写的命令,末尾要加上\n(linux直接加\n,windows加\r\n),否则命令无法执行!
- write()方法不可与waitForFinished()一起使用,否则会阻塞30秒。waitForFinished()只能用start()一起使用!
- Qt中还无法直接识别管道 “|” 和重定向">>”命令 (而是在启动程序或终端时作为参数传入管道 “|” 和重定向">>”命令 ,而不是启动后再输入)
- QProcess 指令执行结果
输出不能及时打印
,请按照标准的连接信号槽的方法使用。请尽量避开用lambda去写connect连接信号和槽。想真正非阻塞地使用QProcess,老老实实按照连接信号与槽的方法去使用。
三、示例
自定义延时封装
void MainWindow::delayMSec(unsigned int msec)
{
QTime Time_set = QTime::currentTime().addMSecs(msec);
while( QTime::currentTime() < Time_set )
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
示例1:
QProcess *process = new QProcess;
process->start("bash");
connect(process,SIGNAL(readyReadStandardOutput),this,SLOT(slot_processOutput()));
void slot_processOutput()
{
qDebug() << process->readAllStandarOutput();
}
QString cmd = QString("awk \'NR==15,NR==16{printf \"%-7s:%-15s\\n\",$1,$2}\' /etc/network/interfaces\n");
process->write(cmd.toLocal8Bit().data());
只要命令有输出,就会不断激活readyReadStandardOutput信号(通常不止一次),然后执行槽函数输出信息,输出信息完结了就不会激活readyReadStandardOutput信号了。整个过程非阻塞。
注意:
字符里边的""、\n等特殊字符需要转义处理
总结
总之,QProcess类是Qt中执行外部命令和与之交互的重要类,可以方便地在Qt应用程序中执行各种外部命令,并且可以获取其输出和错误信息。