2013-03-25 81 views
3

我有這個簡單的C++程序:如何從QProcess讀取?

int main(int argc, char *argv[]) 
{ 

    QCoreApplication a(argc, argv); 

    QProcess ps; 
    QByteArray ba; 

    ps.start("ls J:"); 
    ba = ps.readAllStandardOutput(); 
    char *someData = ba.data(); 

    cout << "Testing QProcess ..." << endl; 
    cout << someData << endl; 
    cout << "done!" << endl; 

    return a.exec(); 
} 

輸出是:

Testing QProcess ... 


done! 

如果我運行 「LS記者:」 從Windows在cmd它的工作原理。 我錯過了什麼?

+0

hmmm ... M $實現linux的'ls'? – borisbn 2013-03-25 12:38:56

+0

@borisbn:因爲我的系統中有我的MSS工作的MSYS。即使我換成Windows的東西,例如「dir J:」它不適用於我的程序,但它適用於Windows cmd。 – Amani 2013-03-25 12:41:50

回答

5

在一個循環中使用QIODevice::waitForReadyRead(),只有在返回後,然後調用readAllStandardOutput()。正如它在文檔中所述,QProcess::readAllStandardOutput()將讀取所有可用的數據,但不會等待。在你開始閱讀之前,你需要等待那個過程開始於QProcess::waitForStarted()

快速未經測試的部分代碼,這種替換線ba = ps.readAllStandardOutput();

if (ps.waitForStarted(-1)) { 
    while(ps.waitForReadyRead(-1)) { 
     ba += ps.readAllStandardOutput(); 
    } 
} 
// else report error or whatever 

這應該退出循環,當出現錯誤或子進程終止,但請繼續閱讀在那之前,沒有超時。

注意:在「常規」Qt程序中,您將有事件循環運行,然後您不會調用waitForReadyRead()或其他類似的便利功能。他們會阻止事件循環並阻止其他事情。在這樣的程序中,你最好最好是使用信號和插槽,或者開始使用線程(但這通常不是首選,它只是增加了不必要的複雜性)。

+0

在循環中使用QIODevice :: waitForReadyRead(),你是指事件循環還是while/if-else循環? – Amani 2013-03-25 12:55:27

+0

測試了你添加的那段代碼,它給出了和以前相同的輸出。 – Amani 2013-03-25 12:59:19

+0

@Amani你確定這個'ls'打印到標準輸出而不是標準錯誤嗎?嘗試使用'setProcessChannelMode(QProcess :: MergedChannels)'。 – hyde 2013-03-25 13:03:09

2

QProcess documentation說,即QProcess對象發出信號時,有可供讀取數據:readyRead()readyReadStandardOutput()readyReadStandardError()

最簡單的方法是將這些信號連接到您的插槽,並使用例如。 readAllStandardOutput()那裏。

當然hydes循環也可以。