进程是操做系统的基础之一。一个进程能够认为是一个正在执行的程序。咱们能够把进程当作计算机运行时的一个基础单位。关于进程的讨论已经超出了本章的范畴,如今咱们假定你是了解这个概念的。数组
在 Qt 中,咱们使用QProcess
来表示一个进程。这个类能够容许咱们的应用程序开启一个新的外部程序,而且与这个程序进行通信。下面咱们用一个很是简单的例子开始咱们本章有关进程的阐述。网络
//!!! Qt5 QString program = "C:/Windows/System32/cmd.exe"; QStringList arguments; arguments << "/c" << "dir" << "C:\\"; QProcess *cmdProcess = new QProcess; QObject::connect(cmdProcess, &QProcess::readyRead, [=] () { QTextCodec *codec = QTextCodec::codecForName("GBK"); QString dir = codec->toUnicode(cmdProcess->readAll()); qDebug() << dir; }); cmdProcess->start(program, arguments);
这是一段 Qt5 的程序,而且仅能运行于 Windows 平台。简单来讲,这段程序经过 Qt 开启了一个新的进程,这个进程至关于执行了下面的命令:异步
C:\Windows\System32\cmd.exe /c dir C:\
注意,咱们能够在上面的程序中找到这个命令的每个字符。事实上,咱们能够把一个进程看作执行了一段命令(在 Windows 平台就是控制台命令;在 Linux 平台(包括 Unix)则是执行一个普通的命令,好比 ls)。咱们的程序至关于执行了 dir 命令,其参数是 C:\,这是由arguments
数组决定的(至于为何咱们须要将 dir 命令做为参数传递给 cmd.exe,这是因为 Windows 平台的规定。在 Windows 中,dir 命令并非一个独立的可执行程序,而是经过 cmd.exe 进行解释;这与 ls 在 Linux 中的地位不一样,在 Linux 中,ls 就是一个可执行程序。所以若是你须要在 Linux 中执行 ls,那么program
的值应该就是 ls )。函数
上面程序的运行结果相似于:测试
驱动器 C 中的卷是 SYSTEM 卷的序列号是 EA62-24AB C:\ 的目录 2013/05/05 20:41 1,024 .rnd 2013/08/22 23:22 <DIR> PerfLogs 2013/10/18 07:32 <DIR> Program Files 2013/10/30 12:36 <DIR> Program Files (x86) 2013/10/31 20:30 12,906 shared.log 2013/10/18 07:33 <DIR> Users 2013/11/06 21:41 <DIR> Windows 2 个文件 13,930 字节 5 个目录 22,723,440,640 可用字节
上面的输出会根据不一样机器有所不一样。豆子是在 Windows 8.1 64位机器上测试的。编码
为了开启进程,咱们将外部程序名字(program
)和程序启动参数(arguments
)做为参数传给QProcess::start()
函数。固然,你也可使用setProgram()
和setArguments()
进行设置。此时,QProcess
进入Starting
状态;当程序开始执行以后,QProcess
进入Running
状态,而且发出started()
信号。当进程退出时,QProcess
进入NotRunning
状态(也是初始状态),而且发出finished()
信号。finished()
信号以参数的形式提供进程的退出代码和退出状态。若是发送错误,QProcess
会发出error()
信号操作系统
QProcess
容许你将一个进程当作一个顺序访问的 I/O 设备。咱们可使用write()
函数将数据提供给进程的标准输入;使用read()
、readLine()
或者getChar()
函数获取其标准输出。因为QProcess
继承自QIODevice
,所以QProcess
也能够做为QXmlReader
的输入或者直接使用QNetworkAccessManager
将其生成的数据上传到网络。线程
进程一般有两个预约义的通道:标准输出通道(stdout)和标准错误通道(stderr)。前者就是常规控制台的输出,后者则是由进程输出的错误信息。这两个通道都是独立的数据流,咱们能够经过使用setReadChannel()
函数来切换这两个通道。当进程的当前通道可用时,QProcess
会发出readReady()
信号。当有了新的标准输出数据时,QProcess
会发出readyReadStandardOutput()
信号;当有了新的标准错误数据时,则会发出readyReadStandardError()
信号。咱们前面的示例程序就是使用了readReady()
信号。注意,因为咱们是运行在 Windows 平台,Windows 控制台的默认编码是 GBK,为了不出现乱码,咱们必须设置文本的编码方式。code
通道的术语可能会引发误会。注意,进程的输出通道对应着QProcess
的 读 通道,进程的输入通道对应着QProcess
的 写 通道。这是由于咱们使用QProcess
“读取”进程的输出,而咱们针对QProcess
的“写入”则成为进程的输入。QProcess
还能够合并标准输出和标准错误通道,使用setProcessChannelMode()
函数设置MergedChannels
便可实现。继承
另外,QProcess
还容许咱们使用setEnvironment()
为进程设置环境变量,或者使用setWorkingDirectory()
为进程设置工做目录。
前面咱们所说的信号槽机制,相似于前面咱们介绍的QNetworkAccessManager
,都是异步的。与QNetworkAccessManager
不一样在于,QProcess
提供了同步函数:
waitForStarted()
:阻塞到进程开始;waitForReadyRead()
:阻塞到能够从进程的当前读通道读取新的数据;waitForBytesWritten()
:阻塞到数据写入进程;waitForFinished()
:阻塞到进程结束;注意,在主线程(调用了QApplication::exec()
的线程)调用上面几个函数会让界面失去响应。