QProcess 类
順序設備 - QProcess 類(啟動進程,與之交互) - 知乎本文結構如下: 概述函數詳解準備階段啟動階段運行階段退出階段其他附:所有函數概述QProcess 類的作用就是啟動一個程序,然后與之交互。因為和 socket 都是順序設備類型,所以讀寫的方式基本大差不差。本文將按照…https://zhuanlan.zhihu.com/p/52116398
QProcess 類的作用就是啟動一個程序,然后與之交互。因為和 socket 都是順序設備類型,所以讀寫的方式基本大差不差。本文將按照:“準備階段->啟動階段->運行階段->退出階段”的思路來理清如何使用 QProcess 類。
函數詳解
準備階段
指定程序獲取:QString program() const設置:void setProgram(const QString &program) 指定參數獲取:QStringList arguments() const設置:void setArguments(const QStringList &arguments) Windows專屬獲取:QString nativeArguments() const設置:void setNativeArguments(const QString &arguments) 設置 stdout、stderr獲取:QProcess::ProcessChannelMode processChannelMode() const設置:void setProcessChannelMode(QProcess::ProcessChannelMode mode)既然我們要啟動一個程序,當然我們要選擇啟動哪個程序了,用 setProgram() 函數指定,啟動參數用 setArguments() 來設置。
關于 nativeArguments(),這是專門用在 Windows 操作系統上。雖然 Qt 跨平臺已經做的很好了,但是在 Windows 系統上,啟動外部程序的命令參數會調用 Windows 系統的 API 接口來完成啟動,這時候就只能用 setNativeArguments() 來設置啟動參數,而不能用 setArguments()。比如說最常見的畫圖程序,我在“我的文檔”中有一個 temp.png 圖片,我想通過畫圖程序來啟動,那么代碼應該是這樣的:
QProcess *process = new QProcess(); process->setWorkingDirectory("C:/Users/ren/Documents"); process->setNativeArguments("temp.png"); process->start("mspaint.exe"); process->waitForFinished(); delete process;關于 stdout、stderr,任何程序都有一條向外傳輸信息的標準輸出通道,即 stdout,和一條標準錯誤通道,即 stderr。其中 stdout 傳輸正常信息,就是我們用 qDebug() 或者 print() 打印的信息,而 stderr 傳輸錯誤信息。說“通道”可能不是很好理解,其實就是兩個文件,尤其是在萬物皆為文件的 Linux 中。程序輸出的信息寫到這兩個文件,然后屏幕去讀取。在啟動程序前,我們可以用 setProcessChannelMode() 來控制輸出通道的行為。通道行為模式如下:
- (1)SeparateChannels(默認),QProcess 管理這兩條通道,為它們分別保存在兩個單獨的緩沖區中,此時如果想讀取通道信息的話需要調用 setReadChannel() 來選擇當前讀取通道;
 - (2)MergedChannels?模式是將標準錯誤通道 stderr 合并到 stdout 通道中,原來的 stderr 通道將不會接收任何數據。在這種模式下兩種信息會都經過 stdout 通道傳輸信息;
 - (3)ForwardedChannels?模式就是將啟動的程序的 stdout、stderr 信息都從主進程的 stdout、stderr 通道往外輸出了;
 - (4)ForwardedErrorChannel?模式就是只將 stderr 信息轉發到主進程。最常見的場景就是命令行工具,你看我們用命令行啟動一個程序后只看到錯誤信息,其他的信息都保存到一個文件了;
 - (5)ForwardedErrorChannel?模式就是只將 stdout 信息轉發到主進程。
 
特殊程序的設置
進程環境獲取:QProcessEnvironment processEnvironment() const設置:void setProcessEnvironment(const QProcessEnvironment &environment) 工作目錄獲取:QString workingDirectory() const設置:void setWorkingDirectory(const QString &dir)關于 processEnvironment(),有些程序啟動的時候需要必要的環境變量,比如“TMPDIR”為“C:\MyAPP\temp”,或者“PATH”需要某某路徑之類的。
關于 workingDirectory(),如果設置了工作目錄,那么 QProcess 將在此目錄中啟動程序。如果沒有設置,默認是本程序的目錄中啟動。
啟動階段
啟動
合并式void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)void start(const QString &command, QIODevice::OpenMode mode = ReadWrite)void start(QIODevice::OpenMode mode = ReadWrite)[static]int execute(const QString &program, const QStringList &arguments)[static]int execute(const QString &command) 分離式bool startDetached(qint64 *pid = nullptr)bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr)bool startDetached(const QString &command) 信號[signal]void started()狀態
獲取:QProcess::ProcessState state() const 信號:[signal]void stateChanged(QProcess::ProcessState newState)當一切準備就緒以后,接下來就是啟動程序了。啟動程序分兩種:start()?和?startDetached()。
(1)start() 函數
如果在啟動前已經用 setProgram() 和 setArguments() 指定了程序和參數,那么直接調用第三種 start() 函數即可啟動;如果沒有指定,那么調用第一種 start() 時需要將程序和參數傳入參數列表中。
關于第二種 start(),這個要區別于第一種和第三種。它的作用是執行一個命令而不是啟動一個程序,比如刪除某某文件命令“del /s *.txt”,其中 /s 表示從子目錄刪除指定的文件。如果命令中包含了空格,需要用 \"\" 來包裹住,否則執行不通過。如下所示。為了避免踩各種坑,建議用 setProgram() 和 setArguments() 指定了程序和參數,然后調用第三種 start() 方式。
QProcess process; process.start("dir \"My Documents\"");關于 execute() 靜態函數,它和 start() 唯一的區別就是:start() 是非阻塞式的,而 execute() 是阻塞式的,即啟動后就一直等待程序結束,獲得程序的退出代碼為止。此時啟動的程序的所有輸出都轉發到調用進程。
(2)startDetached()
用 startDetached() 啟動程序后,程序就和調用進程分離了。啥意思?就是說如果用 start() 啟動程序,此時如果關閉了調用進程,那么啟動的程序也會隨之被關閉;如果用 startDetached() 啟動的話,即使調用進程關閉,那么啟動的程序依然不受影響的繼續運行著。
運行階段
進程ID:qint64 processId() const 重定向到文件錯誤:void setStandardErrorFile(const QString &fileName, QIODevice::OpenMode mode = Truncate)輸入:void setStandardInputFile(const QString &fileName)輸出:void setStandardOutputFile(const QString &fileName, QIODevice::OpenMode mode = Truncate)[static]QString nullDevice()關于 processId(),如果有程序再運行,那么該函數返回進程標識符。
關于重定向,就是本來信息輸出到標準通道,現在都輸出到文件中了。
交互
讀取信息獲取:QProcess::ProcessChannel readChannel() const設置:void setReadChannel(QProcess::ProcessChannel channel)信號[signalvoid readyReadStandardError()[signalvoid readyReadStandardOutput()讀取QByteArray readAllStandardError()QByteArray readAllStandardOutput()關閉:void closeReadChannel(QProcess::ProcessChannel channel) 寫入信息獲取:QProcess::InputChannelMode inputChannelMode() const設置:void setInputChannelMode(QProcess::InputChannelMode mode)關閉:void closeWriteChannel() 進程A->進程B:void setStandardOutputProcess(QProcess *destination)關于交互,因為 QProcess 是繼承于 QIODevice 的,那么 QIODevice 中的讀寫函數都可以用在 QProcess 類中。請參考《QIODeivce 類 - 什么是設備?》.
關于 setStandardOutputProcess(),就是將1進程的信息輸出到2進程中,例如“command1 | command2”就可以用如下代碼表示:
QProcess p1; QProcess p2; p1.setStandardOutputProcess(&p2); p1.start("command1"); p2.start("command2");錯誤
獲取:QProcess::ProcessError error() const 信號:[signal]void errorOccurred(QProcess::ProcessError error)同步進程
bool waitForFinished(int msecs = 30000) bool waitForStarted(int msecs = 30000)關于同步進程,因為 QProcess 啟動程序是異步的,當需要同步處理程序時就需要 waitFor... 相關的函數。
退出階段
退出void kill()void terminate() 退出代碼:int exitCode() const 退出狀態:QProcess::ExitStatus exitStatus() const 信號:[signal]void finished(int exitCode, QProcess::ExitStatus exitStatus)關于 kill(),作用是殺死當前進程使之退出。這個函數也是調用平臺相關的 API,如在 Windows 上調用 TerminateProcess,而在 Unix 和 macOS 上是將 SIGKILL 信號發送到進程中。
關于 terminate(),區別于 kill() 這種暴力的退出不同,它在退出進程的時候是有機會提示用戶輸入任何為保存的文件等。在 Windows 上是發送 WM_CLOSE 到進程的頂級窗口,然后發到進程本身的主線程,而 在 Unix 和 macOS 上是發送 SIGTERM 信號。注意在 Windows 上,沒有事件循環或者不處理 WM_CLOSE 消息的控制臺程序只能調用 kill() 來終止。
其他
Windows相關QProcess::CreateProcessArgumentModifier createProcessArgumentsModifier() constvoid setCreateProcessArgumentsModifier(QProcess::CreateProcessArgumentModifier modifier)[static]QStringList systemEnvironment()關于 Windows 相關函數,只能在 Windows 平臺上用。
關于 systemEnvironment(),該函數獲取系統的“鍵值對”環境變量,例如“PATH=/usr/bin:/usr/local/bin”、“HOME=/home/greg”等。
附:所有函數
- 準備階段 
- 指定程序 
- 獲取:QString?program() const
 - 設置:void?setProgram(const QString &program)
 
 - 指定參數 
- 獲取:QStringList?arguments() const
 - 設置:void?setArguments(const QStringList &arguments)
 - Windows專屬 
- 獲取:QString?nativeArguments() const
 - 設置:void?setNativeArguments(const QString &arguments)
 
 
 - 設置 stdout、stderr 
- 獲取:QProcess::ProcessChannelMode?processChannelMode() const
 - 設置:void?setProcessChannelMode(QProcess::ProcessChannelMode mode)
 
 - 特殊程序的設置 
- 進程環境 
- 獲取:QProcessEnvironment?processEnvironment() const
 - 設置:void?setProcessEnvironment(const QProcessEnvironment &environment)
 
 - 工作目錄 
- 獲取:QString?workingDirectory() const
 - 設置:void?setWorkingDirectory(const QString &dir)
 
 
 - 進程環境 
 
 - 指定程序 
 - 啟動階段 
- 啟動 
- 合并式 
- void?start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)
 - void?start(const QString &command, QIODevice::OpenMode mode = ReadWrite)
 - void?start(QIODevice::OpenMode mode = ReadWrite)
 - [static]int?execute(const QString &program, const QStringList &arguments)
 - [static]int?execute(const QString &command)
 
 - 分離式 
- bool?startDetached(qint64 *pid = nullptr)
 - bool?startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr)
 - bool?startDetached(const QString &command)
 
 - 信號 
- [signal]void?started()
 
 
 - 合并式 
 - 狀態 
- 獲取:QProcess::ProcessState?state() const
 - 信號:[signal]void?stateChanged(QProcess::ProcessState newState)
 
 
 - 啟動 
 - 運行階段 
- 進程ID:qint64?processId() const
 - 重定向到文件 
- 錯誤:void?setStandardErrorFile(const QString &fileName, QIODevice::OpenMode mode = Truncate)
 - 輸入:void?setStandardInputFile(const QString &fileName)
 - 輸出:void?setStandardOutputFile(const QString &fileName, QIODevice::OpenMode mode = Truncate)
 - [static]QString?nullDevice()
 
 - 交互 
- 讀取信息 
- 獲取:QProcess::ProcessChannel?readChannel() const
 - 設置:void?setReadChannel(QProcess::ProcessChannel channel)
 - 信號 
- [signalvoid?readyReadStandardError()
 - [signalvoid?readyReadStandardOutput()
 
 - 讀取 
- QByteArray?readAllStandardError()
 - QByteArray?readAllStandardOutput()
 
 - 關閉:void?closeReadChannel(QProcess::ProcessChannel channel)
 
 - 寫入信息 
- 獲取:QProcess::InputChannelMode?inputChannelMode() const
 - 設置:void?setInputChannelMode(QProcess::InputChannelMode mode)
 - 關閉:void?closeWriteChannel()
 
 - 進程A->進程B:void?setStandardOutputProcess(QProcess *destination)
 
 - 讀取信息 
 - 錯誤 
- 獲取:QProcess::ProcessError?error() const
 - 信號:[signal]void?errorOccurred(QProcess::ProcessError error)
 
 - 同步進程 
- bool?waitForFinished(int msecs = 30000)
 - bool?waitForStarted(int msecs = 30000)
 
 
 - 退出階段 
- 退出 
- void?kill()
 - void?terminate()
 
 - 退出代碼:int?exitCode() const
 - 退出狀態:QProcess::ExitStatus?exitStatus() const
 - 信號:[signal]void?finished(int exitCode, QProcess::ExitStatus exitStatus)
 
 - 退出 
 - 其他 
- Windows相關 
- QProcess::CreateProcessArgumentModifier?createProcessArgumentsModifier() const
 - void?setCreateProcessArgumentsModifier(QProcess::CreateProcessArgumentModifier modifier)
 
 - [static]QStringList?systemEnvironment()
 
 - Windows相關 
 
總結
以上是生活随笔為你收集整理的QProcess 类的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: debian与cenos常见命令不同处
 - 下一篇: Ubuntu20.04 远程桌面共享vn