1. 程式人生 > >Qt模組化筆記之core——QProcess控制外部程式

Qt模組化筆記之core——QProcess控制外部程式

QProcess是一個為程序間通訊建立的類。在linux相關係統中,可以很方便地用它呼叫執行命令。

它繼承自QIODevice.可以想像,它對其它程序的操作方式,就像讀寫一個檔案一樣方便。

下面瀏覽它的公共函式:

	QProcess(QObject * parent = 0)
virtual	~QProcess()

void	setProgram(const QString & program)//設定需要開啟的程序
void	setArguments(const QStringList & arguments)//設定引數部分
void	setInputChannelMode(InputChannelMode mode)
void	setReadChannel(ProcessChannel channel)//設定輸出通道。下邊解釋1
void	setNativeArguments(const QString & arguments)
void	setProcessChannelMode(ProcessChannelMode mode)
void	setProcessEnvironment(const QProcessEnvironment & environment)

void	start(const QString & program, const QStringList & arguments, OpenMode mode = ReadWrite)//較常用,直接啟動執行某個程序並傳入引數
void	start(OpenMode mode = ReadWrite)
void	start(const QString & command, OpenMode mode = ReadWrite)

QByteArray	readAllStandardError()//從輸出中得到被操作程式的輸出內容。輸出時有標準錯誤輸出和標準輸出兩個管道
QByteArray	readAllStandardOutput()

void	setStandardErrorFile(const QString & fileName, OpenMode mode = Truncate)//與readAllStandardXXX函式相似,只是將程式的輸出儲存到檔案中。設定以下幾個後,就read不到相應管道中的內容了。
void	setStandardInputFile(const QString & fileName)
void	setStandardOutputFile(const QString & fileName, OpenMode mode = Truncate)
void	setStandardOutputProcess(QProcess * destination)
void	setWorkingDirectory(const QString & dir)

QProcess::ProcessState	state() const
bool	waitForFinished(int msecs = 30000)
bool	waitForStarted(int msecs = 30000)
QString	workingDirectory() const

QStringList	arguments() const
void	closeReadChannel(ProcessChannel channel)
void	closeWriteChannel()
QProcess::ProcessError	error() const
int	exitCode() const
QProcess::ExitStatus	exitStatus() const
InputChannelMode	inputChannelMode() const
QString	nativeArguments() const
Q_PID	pid() const
ProcessChannelMode	processChannelMode() const
QProcessEnvironment	processEnvironment() const
QString	program() const
ProcessChannel	readChannel() const

1,enum QProcess::ProcessChannel
Constant Value Description
QProcess::StandardOutput預設 0 standard output (stdout) 標準輸出
QProcess::StandardError 1 standard error (stderr) 標準錯誤輸出

對於一些繼承來的操作函式,如:read(), readAll(), readLine(), 和 getChar(),它們讀取時,只能從兩個通道中的一個讀取得到被操縱程式的標準輸出。

可以通過連線訊號得到progress的狀態:

Signals

void error(QProcess::ProcessError error)
void (int exitCode, QProcess::ExitStatus exitStatus)
void (QProcess::ProcessState newState)

它的一些靜態函式:

Static Public Members

int (const QString & program, const QStringList & arguments)//阻塞式,直到progress退出
int (const QString & program
)
bool (const QString & program, const QStringList & arguments, const QString & workingDirectory, qint64 * pid = 0)
bool (const QString & program, const QStringList & arguments)
bool (const QString & program)
QStringList ()//一個有用的獲取系統環境變數的函式。使用如:QStringList environment = QProcess::systemEnvironment();
// environment = {"PATH=/usr/bin:/usr/local/bin",
// "USER=greg", "HOME=/home/greg"}

————————————————————————————————————————————————————————

下面用mentohust程式舉一個它的典型用法:

QString program = "/usr/bin/mentohust";
QStringList arguments;
arguments << "-h";

QProcess *myProcess = new QProcess(parent);
myProcess->start(program, arguments);
mentohust是一個校園網認證的工具,在linux中只有後臺,沒有UI。使用時可在shell中輸入mentohust -h。可以得到幫助資訊。上面程式碼的結果是一樣的。

這樣啟動後,可以用write函式向其寫入內容,通過readyReadStandardOutput()等訊號連到槽函式,然後用readAllStandardOutput()等讀函式讀取輸出進行處理。

給出一個它的引數的詳細連結:https://code.google.com/p/mentohust/wiki/Parameter。可用它試試。或網上有操控MPlayer的,百度下。

————————————————————————————————————————————————————————

接下來看它的更高階用法,以更深理解它:

以下內容來自:http://blog.csdn.net/dbzhang800/article/details/6877762點選開啟連結

簡單控制檯程式

一個程式如何從外界獲取資訊並向外輸出資訊呢?

方向

途徑

獲取

命令列引數

int main(int argc, char **argv)

標準輸入

scanf()/getc()/getchar()/...

環境變數

getenv()

輸出

標準輸出

printf() ...

標準出錯

fprintf(stderr,...)

返回值

return(x)/exit(X)/_Exit(X)

命令列引數

大多控制檯程式都接受命令列引數,一個例子:

#include <stdio.h>
int main(int argc, char **argv)
{
    for (int i=1; i<argc; ++i)
        printf("%s\n", argv[i]);
    return 0;
}

編譯,呼叫程式時可指定命令列,結果:

$ ./process a b "c d"
a
b
c d

用QProcess呼叫外部程式時,可直接指定命令列引數

QProcess process;
process.start("./process", QStringList()<<"a"<<"b");
process.start("./process a b");

後一種寫法看起來寫起來比較簡潔,但是程式路徑或引數中包括空格時,就不如第一種方便了。

注:在Windows平臺的某些情況(比如QTBUG7620)下,你可能需要使用

  • QProcess::setNativeArguments()

標準輸出

對於控制檯程式來說,這個可能是用的最多的了。比如上一個程式,我們遍歷命令列引數,然後輸到標準輸出。

在控制檯下,我們通常會使用重定向功能,比如:

$./process a b "c d" > out.txt 

在QProcess下,我們使用

QProcess::readAllStandardOutput ()

獲取標準輸出

QProcess::setStandardOutputFile()

設定輸出到的檔案,相當於前面的重定向

QProcess process;
process.start("./process", QStringList()<<"a"<<"b");
process.readAllStandardOutput();

可以使用:

  • QProcess::setStandardOutputProcess()

將標準輸出作為另個程序的標準輸入。形成 ls -l | more 這樣的管道操作

由於QProcess是QIODevice的派生類,故:

  • read()
  • readLine()
  • ...

都可以直接用獲取被呼叫程式的標準輸出。

禁止緩衝

注意:如果寫的控制檯程式準備用於這種途徑,且需要實時被讀取標準輸出,那麼一般該程式內需要禁用緩衝

int main()
{
setvbuf(stdout, (char *)NULL, _IONBF, 0);
return 0;
}

因為在控制檯執行時,標準輸出是行緩的。但是使用管道或重定向以後,一般就是全緩衝。在緩衝區寫滿或程式退出前,你可能看不到任何輸出。

標準出錯

相對於標準輸出,這個東西大家似乎用的比較少了。

#include <stdio.h>

int main(int argc, char **argv)
{
    fprintf(stdout, "Hello STDOUT!\n");
    fprintf(stderr, "Hello STDERR!\n");
    return 0;
}

編譯執行(注意區分兩個流,標準出錯的檔案描述符是2):

$ ./process
Hello STDOUT!
Hello STDERR!
$ ./process > out.txt
Hello STDERR!
$ ./process > out.txt 2>err.txt
$

用QProcess讀取標準出錯,和前面標準輸出是類似的:

  • QProcess::readAllStandardError()
  • QProcess::setStandardErrorFile()
QProcess process;
process.start("./process", QStringList()<<"a"<<"b");
process.readAllStandardOutput();

但是,QProcess作為QIODevice的派生類,read()/readAll()只能讀標準輸出,不讀標準出錯,有點說不過去哈。

恩QProcess在這方面足夠靈活,你可以通過

  • QProcess::setReadChannel()

進行選擇

標準輸入

這個也不用多說,使用scanf()/gfets()等函式:

#include <stdio.h>

int main(int argc, char **argv)
{
    char contents[1024];
    fgets(contents, 1024, stdin);
    printf("output: %s", contents);
    return 0;
}

執行:

$ ./process 
1+1=2
output: 1+1=2

如果要輸入的內容在檔案內,也可以使用重定向

$ ./process < intput.txt
output: contents of input.txt

在QProcess中,直接使用QIODevice的write()函式

QProcess process;
process.start("./process")
process.write("intput");

也可以設定檔案作為輸入

  • QProcess::setStandardInputFile()

返回值

似乎很多人分不清返回值和標準輸出的概念。

int main()
{
return 0;
}

也就是程式中 return X/exit(X) 等函式中指定的值了。

在Windows下,通過

C:\> process.exe
C:\> echo %errorlevel%

在Linux下,通過

$ ./process
$ echo $?

獲得返回值。

在QProcess下,則通過:

  • int QProcess::execute()
  • int QProcess::exitCode()

獲得返回值。

環境變數

程式執行時可以通過環境變數傳遞資訊:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    char * path = getenv("MYPATH");
    printf("MYPATH= %s\n", path);
    return 1;
}

執行結果(Linux):

$ export MYPATH="/home/dbzhang800"
$ ./process
MYPATH= /home/dbzhang800

Windows下:

C:\> set MYPATH=E:\dbzhang800
C:\> process.exe
MYPATH= E:\dbzhang800

在Qt下,使用 QProcess::setProcessEnvironment() 設定程序的環境變數

QProcess process;
QProcessEnvironment env;
env.insert("MYPATH", "/home/dbzhang800");
process.setProcessEnvironment(env);
process.start("./process");