2015-09-15 59 views
0

在Qt/C++中,從動態庫(Qt C++ Class Project)中,我需要爲命令行命令產生一個新進程(dir /s就是一個很好的例子)鎖定調用該庫函數的GUI。然後,我需要查看這個標準輸出和標準錯誤,直到產生的過程完成。如何從動態庫中產生一個異步QProcess,然後在輸出完成前查看它?從動態庫產生異步QProcess,直到完成Peek輸出

下面的代碼不起作用,但它具有顯示思考過程的部分。

QString ctCommand::testCommand() 
{ 
    QObject *parent; 
    QProcess *console = new QProcess(parent); 
    console->connect(console,SIGNAL(readyReadStandardOutput()),this,SLOT(out())); 
    console->setReadChannel(QProcess::StandardOutput); 
    console->start("dir /s"); 
} 

QString ctCommand::out() 
{ 
    QByteArray processOutput; 
    processOutput = console->readAllStandardOutput(); 
    return QString(processOutput); 
} 
+0

_dir_命令不會與'QProcess'工作://doc.qt。 io/qt-5/qprocess.html#notes-for-windows-users) –

+0

「以下代碼不起作用」不工作**如何**?您必須檢查錯誤條件並提供一些調試輸出以讓您知道發生了什麼。一旦你這樣做了,問題就會變得明顯。 –

+0

@AlexanderSorokin我可以使用'cmd.exe/c'技術。不過,那只是我的例子。我實際上是在Mac上運行它,建立一個第三方工具的前端,不幸的是它只能用命令行格式。 – Volomike

回答

3

你需要連接信號從對象從庫開始你的主類對象。

圖書館

process.h

#include <QtCore/qglobal.h> 
#include <QObject> 
#include <QProcess> 

#if defined(PROCESS_LIBRARY) 
# define PROCESSSHARED_EXPORT Q_DECL_EXPORT 
#else 
# define PROCESSSHARED_EXPORT Q_DECL_IMPORT 
#endif 

class PROCESSSHARED_EXPORT Process : public QObject 
{ 
    Q_OBJECT 
public: 
    Process(const QString &p_Command, QObject *p_Parent = nullptr); 
    QString getCommand() const; 

signals: 
    void readyRead(QByteArray); 

public slots: 
    void runCommand(const QString &p_Command); 
    void runCommand(); 
    void setCommand(const QString &p_Command); 

private slots: 
    void out(); 
    void processFinished(int p_Code); 

private: 
    QString command; 
}; 

process.cpp

#include "process.h" 

Process::Process(const QString &p_Command, QObject *p_Parent) 
    : QObject(p_Parent) 
{ 
    command = p_Command; 
} 

void Process::runCommand(const QString &p_Command) { 
    command = p_Command; 
    runCommand(); 
} 

void Process::runCommand() { 
    QProcess *console = new QProcess(this); 
    console->connect(console, SIGNAL(readyRead()), 
     this, SLOT(out())); 
    console->connect(console, SIGNAL(finished(int)), 
     this, SLOT(processFinished(int))); 
    console->start(command); 
} 

void Process::out() { 
    QProcess *console = qobject_cast<QProcess*>(QObject::sender()); 
    QByteArray processOutput = console->readAll(); 
    emit readyRead(processOutput); 
} 

void Process::processFinished(int p_Code) { 
    QProcess *console = qobject_cast<QProcess*>(QObject::sender()); 
    QByteArray processOutput = console->readAll() 
     + QString("Finished with code %1").arg(p_Code).toLatin1(); 
    emit readyRead(processOutput); 
} 

QString Process::getCommand() const { 
    return command; 
} 

void Process::setCommand(const QString &p_Command) { 
    command = p_Command; 
} 

用法

void MainWindow::showCustomMessage() 
{ 
    Process *tempProcess = new Process("ping google.com", this); 
    connect(tempProcess, SIGNAL(readyRead(QByteArray)), 
     this, SLOT(processResponded(QByteArray))); 
    tempProcess->runCommand(); 
} 

void MainWindow::processResponded(QByteArray p_Data) { 
    qDebug() << p_Data; 
} 

如果有人有關於Qt中創建庫的問題 - 訪根據[文件](HTTP官方Wiki

+0

每次啓動命令時是否需要創建新進程?如果您堅持只在需要時才懶惰地構建過程,您當然可以這樣做,但每次都不需要新過程。 –

+0

可以重用'Process'。將'void finished(int);''Process'類的'signals'節添加並從Process :: processFinished(int p_Code)中發出''將使它更容易。然後你需要聽主類的'finished(int)'信號。之後調用'Process :: runCommand(QString)'傳遞新的命令作爲參數。 –

+0

C++同事建議我也應該考慮使用QtConcurrent API。它可能會使這個代碼更簡單? http://doc.qt.io/qt-5/qtconcurrent-index。html – Volomike

相關問題