Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt QProcess问题,流程输出_Qt_Qt4 - Fatal编程技术网

Qt QProcess问题,流程输出

Qt QProcess问题,流程输出,qt,qt4,Qt,Qt4,我正在试图找出QProcess的用法。我看着Qt doc,一点运气都没有。 问题示例。 示例1:下面的代码有效 #include <QtCore/QCoreApplication> #include <QTextStream> #include <QByteArray> #include <QProcess> int main(int argc, char *argv[]) { QCoreApplication a(ar

我正在试图找出QProcess的用法。我看着Qt doc,一点运气都没有。

问题示例。

示例1:下面的代码有效

    #include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QByteArray>
#include <QProcess>    

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextStream qout(stdout);    

    QProcess cmd;
    
    cmd.start("cmd");
    if (!cmd.waitForStarted())  {
        return false;
    }

    cmd.waitForReadyRead();
    QByteArray result = cmd.readAll();
    //qout << result.data() << endl;   //console junk captured, doesn't show. 

    //My test command
    cmd.write("echo hello");
    cmd.write("\n");

    //Capture my result
    cmd.waitForReadyRead();
    //This is my command shown by cmd, I don't show it, capture & discard it.
    result = cmd.readLine();
    //Read result of my command ("hello") and the rest of output like cur dir.   
    result = cmd.readAll();    
    qout << result.data();

    qout << "\n\n---End, bye----" << endl;
    return a.exec();
}
问题是,如果我试图通过Qprocess和cmd控制台以这种方式使用ipconfig或7zip,我将无法看到ipconfig或7zip的任何输出。我不知道是否做了什么,如果做了什么,为什么我看不到输出?下面的代码说明了这一点

示例2:不起作用。无法使用ipconfig

#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QByteArray>
#include <QString>
#include <QProcess>    

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QTextStream qout(stdout);
   
   QProcess cmd2;
    cmd2.setWorkingDirectory("C:/Program Files/7-Zip");   //not needed in this example.
    cmd2.setReadChannel(QProcess::StandardOutput);
    cmd2.setProcessChannelMode(QProcess::MergedChannels);

    cmd2.start("cmd");
    if (!cmd2.waitForStarted())
    {
        qout << "Error: Could not start!" << endl;
        return false;
    }

    cmd2.waitForReadyRead();
    QByteArray result = cmd2.readAll();
    qout << result.data() << endl;      //Console version info, etc.

    //My command
    cmd2.write("ipconfig");
    cmd2.write("\n");

    //Capture output of ipconfig command
    //DOES NOT WORK!!
    cmd2.waitForReadyRead();
    while (! cmd2.atEnd())
    {
        result = cmd2.readLine();
        qout << result;
        result.clear();
    }
    qout << endl;

    qout << "\n\n---end----" << endl;
    return a.exec();

}
C:\Documents and Settings\n名称>

显然,输出应该与上面的有所不同,但是作为“ipconfig”输出的连接信息应该已经被捕获。同样,如果我尝试通过cmd控制台使用7zip。。。我无法查看/捕获7zip的任何输出。所以我的问题是,如何通过QProcess和cmd控制台使用命令行应用程序(如ipconfig和7zip)并查看这些应用程序的输出结果

示例3:7zip不起作用

#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QByteArray>
#include <QProcess>    

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QTextStream qout(stdout);

    QProcess cmd2;
    cmd2.setWorkingDirectory("C:/Program Files/7-Zip");
    cmd2.setReadChannel(QProcess::StandardOutput);
    cmd2.setProcessChannelMode(QProcess::MergedChannels);

    cmd2.start("cmd");
    if (!cmd2.waitForStarted()) {
        return false;
    }

    //My Command
    cmd2.write("7z.exe");
    cmd2.write("\n");

    //Capture output of ipconfig command
    cmd2.waitForReadyRead();
    QByteArray result;

    while (! cmd2.atEnd()) {
        result = cmd2.readLine();
        qout << result;
        result.clear();
    }
    qout << endl;

    qout << "\n\n---end----" << endl;
    return a.exec();
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
qcorea应用程序(argc、argv);
QTextStream-qout(stdout);
qprocesscmd2;
cmd2.setWorkingDirectory(“C:/Program Files/7-Zip”);
setReadChannel(QProcess::StandardOutput);
cmd2.setProcessChannelMode(QProcess::MergedChannels);
cmd2.启动(“cmd”);
如果(!cmd2.waitForStarted()){
返回false;
}
//我的命令
cmd2.write(“7z.exe”);
cmd2.写入(“\n”);
//捕获ipconfig命令的输出
cmd2.waitForReadyRead();
QByteArray结果;
而(!cmd2.atEnd()){
结果=cmd2.readLine();
库特

我看到一个大问题。 在windows下,按Enter键发出一个命令。正在写入

cmd.write("command");
cmd.write("\n");

光是写作是不够的

cmd.write("command");
cmd.write("\n\r");
请注意尾随\r。试试这个,它应该会工作得更好,我指的是7zip。我不知道您是否能让ipconfig正常工作

祝你好运,并致以最良好的祝愿
D

编辑 以下是一个可行的解决方案:


#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QString>
#include <QtCore/QTextStream>

// Not clean, but fast
QProcess *g_process = NULL;

// Needed as a signal catcher
class ProcOut : public QObject
{
  Q_OBJECT
public:
  ProcOut (QObject *parent = NULL);
  virtual ~ProcOut() {};

public slots:
  void readyRead();
  void finished();
};

ProcOut::ProcOut (QObject *parent /* = NULL */):
QObject(parent)
{}

void
ProcOut::readyRead()
{
  if (!g_process)
    return;

  QTextStream out(stdout);
  out << g_process->readAllStandardOutput() << endl;
}

void
ProcOut::finished()
{
  QCoreApplication::exit (0);
}

int main (int argc, char **argv)
{
  QCoreApplication *app = new QCoreApplication (argc, argv);

  ProcOut *procOut = new ProcOut();
  g_process        = new QProcess();

  QObject::connect (g_process, SIGNAL(readyReadStandardOutput()),
    procOut, SLOT(readyRead()));
  QObject::connect (g_process, SIGNAL(finished (int, QProcess::ExitStatus)),
    procOut, SLOT(finished()));

  g_process->start (QLatin1String ("cmd"));
  g_process->waitForStarted();

  g_process->write ("ipconfig\n\r");

  // Or cmd won't quit
  g_process->write ("exit\n\r");

  int result = app->exec();

  // Allright, process finished.
  delete procOut;
  procOut = NULL;

  delete g_process;
  g_process = NULL;

  delete app;
  app = NULL;

  // Lets us see the results
  system ("pause");

  return result;
}

#include "main.moc"

#包括
#包括
#包括
#包括
//不干净,但很快
QProcess*g_process=NULL;
//作为一个信号捕捉器需要
类ProcOut:公共QObject
{
Q_对象
公众:
ProcOut(QObject*parent=NULL);
虚拟~ProcOut(){};
公众时段:
void readyRead();
无效完成();
};
ProcOut::ProcOut(QObject*parent/*=NULL*/):
QObject(父对象)
{}
无效的
ProcOut::readyRead()
{
if(!g_过程)
返回;
QTextStream out(标准输出);
out readAllStandardOutput()启动(QLatin1String(“cmd”);
g_进程->waitForStarted();
g_进程->写入(“ipconfig\n\r”);
//否则cmd不会退出
g_进程->写入(“退出\n\r”);
int result=app->exec();
//好的,过程结束了。
删除procOut;
procOut=NULL;
删除g_过程;
g_过程=NULL;
删除应用程序;
app=NULL;
//让我们看看结果
系统(“暂停”);
返回结果;
}
#包括“main.moc”

希望有帮助。它在我的机器上每次都能工作。

尽管Dariusz Scharsig已经提供了问题的解决方案,但我想指出我认为可以使用信号槽机制解决的实际问题

问题1。while循环中的条件基于
boolqprocess::atEnd()const
,它取决于以下状态:

从QIODevice::atEnd()重新实现

如果进程为空,则返回true 未运行,并且没有更多数据可供读取;否则 返回false

但如果您查看文档,它会指出:

如果当前读写位置位于 设备(即,没有更多的数据可供读取) 否则返回false

对于某些设备,atEnd()可以返回 即使有更多数据要读取,也为true。仅此特殊情况 适用于生成数据以直接响应您的设备 调用read()(例如,Unix和Mac OS X上的/dev或/proc文件,或 所有平台上的控制台输入/stdin

解决方案1。更改while循环条件以检查进程的状态:
while(cmd2.state()!=QProcess::NotRunning){

问题2。您在循环之外使用了
cmd2.waitForReadyRead();
可能现在已经准备好读取一些数据,当您完成读取时,还可以获得更多数据:

  • 您阅读了刚才编写的命令:
    ipconfig\n
  • ipconfig需要一些时间来启动并向控制台发送文本。但是到那时,您已经退出了循环,因为
    atEnd()
    给出了true,即使您的进程仍在运行
解决方案2。
waitForReadyRead()
放入循环中

结果2。
waitForReadyRead()
将告诉您何时有可用的数据,这些数据可能不止一行,因此您也应该将
cmd2.ReadLine()
更改为
cmd2.ReadAll()

问题3。如中所述

对于读取输入的程序,必须关闭写入通道 数据,直到通道关闭

解决方案3。完成输入后,下列选项之一应该可以工作

  • 结束进程:
    cmd2.write(“exit\n”);
  • 关闭Writechannel:
    cmd2.closeWriteChannel();
工作代码:

#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QByteArray>
#include <QString>
#include <QProcess>    

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextStream qout(stdout);
    QByteArray result;
    QProcess cmd2;

    cmd2.setReadChannel(QProcess::StandardOutput);
    cmd2.setProcessChannelMode(QProcess::MergedChannels);
    cmd2.start("cmd");
    if (!cmd2.waitForStarted()){
        qout << "Error: Could not start!" << endl;
        return 0;
    }
    cmd2.write("ipconfig\n");
    cmd2.closeWriteChannel();   //done Writing

    while(cmd2.state()!=QProcess::NotRunning){
        cmd2.waitForReadyRead();
        result = cmd2.readAll();
        qout << result;
    }
    qout << endl << "---end----" << endl;
    return a.exec();
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
qcorea应用程序(argc、argv);
QTextStream-qout(stdout);
QByteArray结果;
qprocesscmd2;
setReadChannel(QProcess::StandardOutput);
cmd2.setProcessChannelMode(QProcess::MergedChannels);
cmd2.启动(“cmd”);
如果(!cmd2.waitForS

#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QString>
#include <QtCore/QTextStream>

// Not clean, but fast
QProcess *g_process = NULL;

// Needed as a signal catcher
class ProcOut : public QObject
{
  Q_OBJECT
public:
  ProcOut (QObject *parent = NULL);
  virtual ~ProcOut() {};

public slots:
  void readyRead();
  void finished();
};

ProcOut::ProcOut (QObject *parent /* = NULL */):
QObject(parent)
{}

void
ProcOut::readyRead()
{
  if (!g_process)
    return;

  QTextStream out(stdout);
  out << g_process->readAllStandardOutput() << endl;
}

void
ProcOut::finished()
{
  QCoreApplication::exit (0);
}

int main (int argc, char **argv)
{
  QCoreApplication *app = new QCoreApplication (argc, argv);

  ProcOut *procOut = new ProcOut();
  g_process        = new QProcess();

  QObject::connect (g_process, SIGNAL(readyReadStandardOutput()),
    procOut, SLOT(readyRead()));
  QObject::connect (g_process, SIGNAL(finished (int, QProcess::ExitStatus)),
    procOut, SLOT(finished()));

  g_process->start (QLatin1String ("cmd"));
  g_process->waitForStarted();

  g_process->write ("ipconfig\n\r");

  // Or cmd won't quit
  g_process->write ("exit\n\r");

  int result = app->exec();

  // Allright, process finished.
  delete procOut;
  procOut = NULL;

  delete g_process;
  g_process = NULL;

  delete app;
  app = NULL;

  // Lets us see the results
  system ("pause");

  return result;
}

#include "main.moc"
#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QByteArray>
#include <QString>
#include <QProcess>    

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextStream qout(stdout);
    QByteArray result;
    QProcess cmd2;

    cmd2.setReadChannel(QProcess::StandardOutput);
    cmd2.setProcessChannelMode(QProcess::MergedChannels);
    cmd2.start("cmd");
    if (!cmd2.waitForStarted()){
        qout << "Error: Could not start!" << endl;
        return 0;
    }
    cmd2.write("ipconfig\n");
    cmd2.closeWriteChannel();   //done Writing

    while(cmd2.state()!=QProcess::NotRunning){
        cmd2.waitForReadyRead();
        result = cmd2.readAll();
        qout << result;
    }
    qout << endl << "---end----" << endl;
    return a.exec();
}