Qt QProcess问题,流程输出
我正在试图找出QProcess的用法。我看着Qt doc,一点运气都没有。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
问题示例。 示例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();
}