• 30887阅读
  • 24回复

QProcess调用控制台程序,不弹出界面? [复制链接]

上一主题 下一主题
离线foxgod
 

只看楼主 倒序阅读 楼主  发表于: 2014-09-23
QProcess调用QT写的控制台程序,但是程序虽然执行了,但是界面不弹出来,程序在任务管理器里面虽然显示已经运行了,如何在界面显示出来呢??
离线dbzhang800

只看该作者 1楼 发表于: 2014-09-23
1. 不用 QProcess

2. 用 QProcess 启动你要显示的终端(Ternimal)或命令行(cmd.exe),在终端或命令行中启动你的程序

3.
离线foxgod

只看该作者 2楼 发表于: 2014-09-23
回 dbzhang800 的帖子
dbzhang800:1. 不用 QProcess
2. 用 QProcess 启动你要显示的终端(Ternimal)或命令行(cmd.exe),在终端或命令行中启动你的程序
3.  (2014-09-23 11:49) 

啥意思,没明白
离线dbzhang800

只看该作者 3楼 发表于: 2014-09-23
回 foxgod 的帖子
foxgod:啥意思,没明白 (2014-09-23 11:57) 

好吧,当我没说。

首先,所谓的控制台程序,就是在控制台下运行下的程序,这个没有疑问吧?  

先打开一个控制台,比如unix下的终端(Ternimal)或windows下的命令行(Command Prompt),而后在里面运行你的控制台程序。

注意:在Windows下的资源管理器中(explorer.exe),双击控制台程序也可以启动它,而且Windows会为其提供一个Console(可能是你这儿提到的界面)。 但是这个看似便利的东西却使得很多新手搞不清楚 命令行程序 基本特性(包括对命令行参数、标准输入、输出、出错和返回值理解困难等)。

其次,要启动一个进程,归根到底:在Windows下,就是CreateProcess(),在posix下,就是fork() 和 exec()。如果QProcess提供的封装不能满足你的要求,你可以直接去研究相应的系统API。或者其他库对系统API的封装,比如C标准库中的system() 和 popen() 等


离线foxgod

只看该作者 4楼 发表于: 2014-09-23
回 dbzhang800 的帖子
dbzhang800:好吧,当我没说。
首先,所谓的控制台程序,就是在控制台下运行下的程序,这个没有疑问吧?  
....... (2014-09-23 13:50) 

QProcess *process = new QProcess;
process->start("cmd.exe);
这样为啥CMD,还是弹不出界面呢,只是在任务管理器有显示??
离线dbzhang800

只看该作者 5楼 发表于: 2014-09-23
QProcess 有两种用法。

一个是调用 start() 或 execute():此时被调用函数的标准输入、标准输出、标准出错 都已经被重定向到QProcess创建的相应的管道中。在这种情况下,即使你的控制台程序有自己的Console,那么它既不能接收任何输入,也不会输出任何内容。

另一个用法是,startDetached():这是QProcess启动你的控制台程序后,没有任何额外的操作,你也在当前程序中无法控制它。不过,在Windows下,会有一个你期望的Console出现;在其他系统下,不会有终端显示出来。

如果你需要更详细的控制,你应该去MSDN上查相应的API(猜测你只对Windows程序感兴趣,并没考虑跨平台)。
离线foxgod

只看该作者 6楼 发表于: 2014-09-23
回 dbzhang800 的帖子
dbzhang800:QProcess 有两种用法。
一个是调用 start() 或 execute():此时被调用函数的标准输入、标准输出、标准出错 都已经被重定向到QProcess创建的相应的管道中。在这种情况下,即使你的控制台程序有自己的Console,那么它既不能接收任何输入,也不会输出任何内容。
另一个用法是,star .. (2014-09-23 16:26) 

没错,我现在可以通过QProcess::startDetached("cmd.exe",list,&pid);但是我想在cmd,启动后,执行一些命令,比如dir或是PING,如何做呢,这里面的PID,我如何使用呢?
离线dbzhang800

只看该作者 7楼 发表于: 2014-09-23
还是取决于你的设计,你要做什么。你是要那个Console窗口,让用于在里面操作。还是你需要启动cmd.exe程序,你的程序与之交互。
离线foxgod

只看该作者 8楼 发表于: 2014-09-24
回 dbzhang800 的帖子
dbzhang800:还是取决于你的设计,你要做什么。你是要那个Console窗口,让用于在里面操作。还是你需要启动cmd.exe程序,你的程序与之交互。 (2014-09-23 23:20) 

我现在用PROCESS,调用程序后,没有显示出来界面,当时我这个界面上有些log信息,我想把这个信息保存在一个日志里面,但是我可能调用了很多程序,每个log信息我想保存在不同日志里面,瑞然readAllStandardOutput()可以获得输出,但是如何把每个控制台输出信息,保存在不同的日志里面呢
离线dbzhang800

只看该作者 9楼 发表于: 2014-09-24
回 foxgod 的帖子
foxgod:
我现在用PROCESS,调用程序后,没有显示出来界面,当时我这个界面上有些log信息,我想把这个信息保存在一个日志里面,但是我可能调用了很多程序,每个log信息我想保存在不同日志里面,瑞然readAllStandardOutput()可以获得输出,但是如何把每个控制台输出信息,保存在不同的日志里面呢

可能还是没理解你要做什么。感觉上,你这个需求完全不需要那个Console出来。或者你说说看,在控制台下下面,你如何实现将其保存在不同日志里面的?

对一个控制台程序来说,和外界的交互无非是:命令行参数,标准输入,标准输出,标准出错,返回值,环境变量,工作目录 这几个东西。对此QProcess都已经提供完整支持。
离线foxgod

只看该作者 10楼 发表于: 2014-09-24
回 dbzhang800 的帖子
dbzhang800:可能还是没理解你要做什么。感觉上,你这个需求完全不需要那个Console出来。或者你说说看,在控制台下下面,你如何实现将其保存在不同日志里面的?
对一个控制台程序来说,和外界的交互无非是:命令行参数,标准输入,标准输出,标准出错,返回值,环境变量,工作目录 这几个东 .. (2014-09-24 10:52) 

for(int i = 0 ; i <m_MatrixName.size();i++)
{
QProcess *process = new QProcess;
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(startReadOutput()));
QString str = QCoreApplication::applicationDirPath();
process->setProgram(str);
  process->start();
}
对于这样的程序,如何让process调用的程序在控制台打印的信息,现在在不同的日志里面?
离线dbzhang800

只看该作者 11楼 发表于: 2014-09-24
回 foxgod 的帖子
foxgod:
for(int i = 0 ; i <m_MatrixName.size();i++)
{
QProcess *process = new QProcess;
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(startReadOutput()));
.......



你这代码很不严谨,看不出你想表达的意思。另外,将当前进程所在目录 作为可执行程序启动? 内存泄露?

假定你在一个循环里面要调用一个程序 1000 次。按你的意思,你是想生成1000个文件,分别对应1000个的QProcess启动的进程的标准输出? 这样的话,你连readyReadStandardOutput 这种信号槽都不用就能实现。
离线foxgod

只看该作者 12楼 发表于: 2014-09-24
回 dbzhang800 的帖子
dbzhang800:你这代码很不严谨,看不出你想表达的意思。另外,将当前进程所在目录 作为可执行程序启动? 内存泄露?
....... (2014-09-24 14:50) 

那你觉得应该如何写?
离线dbzhang800

只看该作者 13楼 发表于: 2014-09-24
回 foxgod 的帖子
foxgod:
那你觉得应该如何写?

问题是,我现在不知道你要做什么
离线foxgod

只看该作者 14楼 发表于: 2014-09-24
回 dbzhang800 的帖子
dbzhang800:问题是,我现在不知道你要做什么 (2014-09-24 15:38) 

从XML,文件里面获取要启动的exe程序,然后启动这些程序, 这些程序都是用QT写的控制台程序,希望吧这些控制台的log保存在某个文件里面
离线dbzhang800

只看该作者 15楼 发表于: 2014-09-24
回 foxgod 的帖子
foxgod:从XML,文件里面获取要启动的exe程序,然后启动这些程序, 这些程序都是用QT写的控制台程序,希望吧这些控制台的log保存在某个文件里面 (2014-09-24 15:57) 

多看看QProcess的Manual,这应该都是比较基本的操作。感觉上一个 QProcess::setStandardOutputFile() 可能就足够了。


取决于你的设计,可以写出多种差异很大的Qt代码,来实现这任务。
离线foxgod

只看该作者 16楼 发表于: 2014-09-24
回 dbzhang800 的帖子
dbzhang800:多看看QProcess的Manual,这应该都是比较基本的操作。感觉上一个 QProcess::setStandardOutputFile() 可能就足够了。
取决于你的设计,可以写出多种差异很大的Qt代码,来实现这任务。
....... (2014-09-24 16:04)

你给我的建议是NULL??,要么给个代码,要么给个思路,要么直接无视我的帖子.
离线dbzhang800

只看该作者 17楼 发表于: 2014-09-24
回 foxgod 的帖子
foxgod:
你给我的建议是NULL??,要么给个代码,要么给个思路,要么直接无视我的帖子.


实在给不出来有意义的代码。因为到现在为止,不清楚你的具体要求是什么:包括一开始你要求的Console和你的log什么关系。你是同一个控制台程序执行多次还是多个控制台程序分别执行等等。思路的话,难道从从一开始我一直都在说不是思路?

for (int i=0; i<1000; ++i) {
    QProcess * p = new QProcess(this);
    p->setStandardOutputFile(QStringLiteral("Out-%1.log").arg(i));
    p.start("youConsole");
}
离线foxgod

只看该作者 18楼 发表于: 2014-09-24
回 dbzhang800 的帖子
dbzhang800:实在给不出来有意义的代码。因为到现在为止,不清楚你的具体要求是什么:包括一开始你要求的Console和你的log什么关系。你是同一个控制台程序执行多次还是多个控制台程序分别执行等等。思路的话,难道从从一开始我一直都在说不是思路?
for (int i=0; i<1000; ++i) {
 & .. (2014-09-24 16:52) 

不知道是我的表达有问题,还是你的理解有问题,我不知道我那里说的不清楚了,我想做个守护程序,这个程序可以自动启动我用QT写的别的程序,这些程序是控制台程序,用PROCESS的SATart函数启动,是可以启动,但是不弹出界面,查看了VS的和QT的源码,一看QT就不让弹出界面,但是VS有个参数可以让弹出来,不弹出了就算了,但是我的控制程序里面有很多log信息,你不弹出来界面,我看不到信息,起码可以让我保存下来,我想做的就是我的守护程序,一次启动我写的不同的QT程序(这里至少有10个以上),每个程序里面打印的log信息,我想保存起来,你给的代码
p->setStandardOutputFile(QStringLiteral("Out-%1.log").arg(i));
    p.start("youConsole");
这个是无法保存log信息的,你可以自己做实验。
如果这次你在不懂我说的,请直接无视我。
离线dbzhang800

只看该作者 19楼 发表于: 2014-09-24
回 foxgod 的帖子
foxgod:
不知道是我的表达有问题,还是你的理解有问题,我不知道我那里说的不清楚了,我想做个守护程序,这个程序可以自动启动我用QT写的别的程序,这些程序是控制台程序,用PROCESS的SATart函数启动,是可以启动,但是不弹出界面,查看了VS的和QT的源码,一看QT就不让弹出界面,但是VS有个参数可以让弹出来,不弹出了就算了,但是我的控制程序里面有很多log信息,你不弹出来界面,我看不到信息,起码可以让我保存下来,我想做的就是我的守护程序,一次启动我写的不同的QT程序(这里至少有10个以上),每个程序里面打印的log信息,我想保存起来,你给的代码
p->setStandardOutputFile(QStringLiteral("Out-%1.log").arg(i));
    p.start("youConsole");
这个是无法保存log信息的,你可以自己做实验。
.......


好吧,都怪我手贱。还真的用Qt4.8 和 Qt5.3 试了一下:

  1. #include <QCoreApplication>
  2. #include <QProcess>
  3. int main(int argc, char *argv[])
  4. {
  5.     QCoreApplication a(argc, argv);
  6.     for (int i=0; i<10; i++) {
  7.         QProcess *p = new QProcess; //Ignore this memory leak.
  8.         p->setStandardOutputFile(QString("out-1.log").arg(i));
  9.         p->setStandardErrorFile(QString("err-%1.log").arg(i));
  10.         p->start("g++");
  11.         //p->start("cmd");
  12.     }
  13.     return a.exec();
  14. }

我只能说,在我这儿工作一切正常。

当然我眼神也不好,前面那么多帖子也我都没看到你说的是"守护程序"。我暂且理解它是Windows下的“服务”吧,这个我没有编写服务进行测试,不清楚Qt在这方面会不会有BUG。

离线foxgod

只看该作者 20楼 发表于: 2014-09-24
回 dbzhang800 的帖子
dbzhang800:好吧,都怪我手贱。还真的用Qt4.8 和 Qt5.3 试了一下:
#include <QCoreApplication>
....... (2014-09-24 17:32)

你写的和我写的是一样的,但是就像我上面说的一样,用PROCESS吊起来的程序,运行后的LOG信息,没有写在out-1.log文件里面,我想说的就是这个.我这里就是这样的情况,当然我的程序不是G++
  1. QProcess *process = new QProcess;
  2. QString str = QCoreApplication::applicationDirPath(); str = str + "/" + m_MatrixName.at(i);
  3. QString output = m_MatrixName.at(i)+".txt";
  4. process->setStandardOutputFile(output);
  5. process->setProgram(str);  process->start(QIODevice::Truncate);




离线dbzhang800

只看该作者 21楼 发表于: 2014-09-24
但是这并不能说明问题,也不能排除是你自己的控制台程序本身的问题。你应该了解,对一个 控制台程序来说,在控制台下直接运行,和做了重定向运行,还是有些细微差别的。前者是行缓冲的,后者是全缓冲的,如果你的控制台程序省略了一些 flush,那么...
离线gonboy

只看该作者 22楼 发表于: 2014-11-26
也没明白楼主想要实现什么功能?


Re:QProcess调用控制台程序,不弹出界面?
如果你要实现此功能,捕捉消息,显示在WIdget上不久可以了吗?
离线彩阳

只看该作者 23楼 发表于: 2014-11-28
我大概理解了。可以这么制作:
使用Qt Creator创建一个基于C和C++的应用程序,然后在pro文件中添加
CONFIG -= console
最后这个程序就真的不弹出界面了。
上海Qt开发联盟,热忱地欢迎你的加入!
离线砍猪佩琪

只看该作者 24楼 发表于: 2019-05-13
你好,请问你的问题解决了吗,我也是用start调用一个fortran写的控制台程序,但是调用之后一直看不到控制台界面
快速回复
限100 字节
 
上一个 下一个