Qt GUI应用程序中的控制台输出?

问题描述 投票:46回答:16

我有一个在Windows上运行的Qt GUI应用程序,它允许传递命令行选项,在某些情况下我想向控制台输出一条消息,然后退出,例如:

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

  if (someCommandLineParam)
  {
    std::cout << "Hello, world!";
    return 0;
  }

  MainWindow w;
  w.show();

  return a.exec();
}

但是,当我从命令提示符运行应用程序时,不会显示控制台消息。有谁知道我怎么能让这个工作?

c++ windows qt qt4
16个回答
44
投票

Windows并不真正支持双模式应用程序。

要查看控制台输出,您需要创建一个控制台应用程序

CONFIG += console

但是,如果您双击该程序以启动GUI模式版本,那么您将出现一个控制台窗口,这可能不是您想要的。要防止出现控制台窗口,您必须创建GUI模式应用程序,在这种情况下,您不会在控制台中输出任何内容。

一个想法可能是创建第二个小应用程序,它是一个控制台应用程序并提供输出。这可以调用第二个来完成工作。

或者你可以将所有功能放在DLL中,然后创建两个版本的.exe文件,它们具有调用DLL的非常简单的主要功能。一个用于GUI,一个用于控制台。


0
投票

它可能是对其他答案的疏忽,或者可能是用户确实需要控制台输出的要求,但对我来说显而易见的答案是创建一个可以显示或隐藏的辅助窗口(带有复选框或按钮)通过将文本行附加到文本框小部件并将其用作控制台来显示所有消息?

这种解决方案的好处是:

  • 一个简单的解决方案(提供所有显示的是一个简单的日志)。
  • 将“控制台”小部件停靠在主应用程序窗口上的功能。 (无论如何,在Qt)。
  • 创建许多控制台的能力(如果超过1个线程等)。
  • 从本地控制台输出到通过网络发送日志到客户端的非常简单的更改。

希望这给你提供了思考的食物,虽然我没有任何资格可以假设你应该如何做到这一点,我可以想象这是我们任何一个人都可以通过一点点搜索/阅读来实现的!


0
投票

确保Qt5Core.dll与您的应用程序可执行文件位于同一目录中。

我在Qt5中遇到了一个与控制台应用程序类似的问题:如果我从Qt Creator启动应用程序,输出文本是可见的,如果我打开cmd.exe并在那里启动相同的应用程序,则看不到输出。很奇怪!

我通过将Qt5Core.dll复制到具有应用程序可执行文件的目录来解决它。

这是我的小控制台应用程序:

#include <QCoreApplication>
#include <QDebug>

int main(int argc, char *argv[])
{
    int x=343;
    QString str("Hello World");
    qDebug()<< str << x<<"lalalaa";

    QTextStream out(stdout);
    out << "aldfjals alsdfajs...";
}

0
投票

我也玩这个,发现重定向输出工作,但我从未看到输出到控制台窗口,这是每个Windows应用程序都有的。到目前为止,这是我的解决方案,直到找到ShowWindow和GetConsoleWindow的Qt替代品。

从没有参数的命令提示符运行它 - 获取窗口。从带有参数的命令提示符运行(例如cmd aaa bbb ccc) - 您可以在命令提示符窗口中获得文本输出 - 就像您对任何Windows控制台应用程序所期望的那样。

请原谅这个蹩脚的例子 - 它代表了大约30分钟的修修补补。

#include "mainwindow.h"
#include <QTextStream>
#include <QCoreApplication>
#include <QApplication>
#include <QWidget>
#include <windows.h>

QT_USE_NAMESPACE

int main(int argc, char *argv[])
{
    if (argc > 1)   {
        // User has specified command-line arguments
        QCoreApplication a(argc, argv);
        QTextStream  out(stdout);
        int     i;

        ShowWindow (GetConsoleWindow(),SW_NORMAL);
        for (i=1; i<argc; i++)
             out << i << ':' << argv [i] << endl;
        out << endl << "Hello, World" << endl;
        out << "Application Directory Path:" << a.applicationDirPath() << endl;
        out << "Application File Path:" << a.applicationFilePath() << endl;
        MessageBox (0,(LPCWSTR)"Continue?",(LPCWSTR)"Silly Question",MB_YESNO);
        return 0;
    } else  {
        QApplication a(argc, argv);
        MainWindow w;

        w.setWindowTitle("Simple example");
        w.show();
        return a.exec();
    }
}

0
投票

这个话题有很多答案。 0.0

所以我尝试使用从Win7到Win10的Qt5.x。我花了几个小时才能找到一个好的工作解决方案,这个解决方案不会在链中产生任何问题:

#include "mainwindow.h"

#include <QApplication>

#include <windows.h>
#include <stdio.h>
#include <iostream>

//
// Add to project file:
// CONFIG += console
//

int main( int argc, char *argv[] )
{
    if( argc < 2 )
    {
    #if defined( Q_OS_WIN )
        ::ShowWindow( ::GetConsoleWindow(), SW_HIDE ); //hide console window
    #endif
        QApplication a( argc, argv );
        MainWindow *w = new MainWindow;
        w->show();
        int e = a.exec();
        delete w; //needed to execute deconstructor
        exit( e ); //needed to exit the hidden console
        return e;
    }
    else
    {
        QCoreApplication a( argc, argv );
        std::string g;
        std::cout << "Enter name: ";
        std::cin >> g;
        std::cout << "Name is: " << g << std::endl;
        exit( 0 );
        return a.exec();
    }
}


我也尝试了没有“CONFIG + = console”,但是你需要重定向流并自己创建控制台:

#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()){
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);
    freopen("CONIN$", "r", stdin);
}
#endif

但这仅在您通过调试器启动时才有效,否则所有输入也将指向系统。意味着,如果您通过std :: cin键入名称,系统会尝试将该名称作为命令执行。 (很奇怪)

对此尝试的另外两个警告是,您不能使用:: FreeConsole()它不会关闭它,如果您通过控制台启动它,应用程序将不会关闭。



最后有一个Qt help section in QApplication这个主题。我在那里尝试了一个带有应用程序的示例,它不适用于GUI,它在无限循环中停留在某处,GUI不会被渲染或者只是崩溃:

QCoreApplication* createApplication(int &argc, char *argv[])
{
    for (int i = 1; i < argc; ++i)
        if (!qstrcmp(argv[i], "-no-gui"))
            return new QCoreApplication(argc, argv);
    return new QApplication(argc, argv);
}

int main(int argc, char* argv[])
{
    QScopedPointer<QCoreApplication> app(createApplication(argc, argv));

    if (qobject_cast<QApplication *>(app.data())) {
       // start GUI version...
    } else {
       // start non-GUI version...
    }

    return app->exec();
}


因此,如果您正在使用Windows和Qt,只需使用控制台选项,如果需要GUI则隐藏控制台并通过退出将其关闭。


-1
投票

在经历了相当长时间的完全相同问题的斗争后,我发现这很简单

CONFIG   += console

真的有诀窍。在明确告诉QtCreator在项目上执行qmake(右键单击项目)并更改源文件中的内容然后重建之前,它将无法工作。否则将跳过编译,您仍然无法在命令行上看到输出。现在我的程序在GUI和cmd行模式下工作。


-1
投票

简单

第1步:创建新项目。转到文件 - >新建文件或项目 - >其他项目 - >清空项目

第2步:使用以下代码。

在.pro文件中

QT +=widgets
CONFIG += console
TARGET = minimal
SOURCES += \ main.cpp

第3步:创建main.cpp并复制以下代码。

#include <QApplication>
#include <QtCore>

using namespace  std;

QTextStream in(stdin);
QTextStream out(stdout);

int main(int argc, char *argv[]){
QApplication app(argc,argv);
qDebug() << "Please enter some text over here: " << endl;
out.flush();
QString input;
input = in.readLine();
out << "The input is " << input  << endl;
return app.exec();
}

我在代码中创建了必要的对象以供您理解。

跑吧

如果您希望程序在某些条件下获得多个输入。然后通过Main.cpp中的以下代码

#include <QApplication>
#include <QtCore>

using namespace  std;

QTextStream in(stdin);
QTextStream out(stdout);

int main(int argc, char *argv[]){
    QApplication app(argc,argv);
    qDebug() << "Please enter some text over here: " << endl;
    out.flush();
    QString input;
    do{
        input = in.readLine();
        if(input.size()==6){
            out << "The input is " << input  << endl;   
        }
        else
        {
            qDebug("Not the exact input man");
        }
    }while(!input.size()==0);

    qDebug(" WE ARE AT THE END");

    // endif
    return app.exec();
} // end main

希望它教育你。

美好的一天,


-3
投票

首先,您可以尝试刷新缓冲区

std::cout << "Hello, world!"<<std::endl;

对于更多基于Qt的日志记录,您可以尝试使用qDebug。


11
投票

加:

#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);
}
#endif

main()的顶部。仅当程序在控制台中启动时才会启用到控制台的输出,并且在其他情况下不会弹出控制台窗口。如果要在控制台外运行应用程序时创建控制台窗口以显示消息,可以将条件更改为:

if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())

5
投票

使用QT += gui时无法向控制台输出消息。

fprintf(stderr, ...)也无法打印输出。

请使用QMessageBox来显示消息。


5
投票
void Console()
{
    AllocConsole();
    FILE *pFileCon = NULL;
    pFileCon = freopen("CONOUT$", "w", stdout);

    COORD coordInfo;
    coordInfo.X = 130;
    coordInfo.Y = 9000;

    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),ENABLE_QUICK_EDIT_MODE| ENABLE_EXTENDED_FLAGS);
}

int main(int argc, char *argv[])
{
    Console();
    std::cout<<"start@@";
    qDebug()<<"start!";

你不能像其他人所说的那样使用std :: cout,我的方式是完美的甚至一些代码也不能包括“qdebug”!


4
投票

哦,你可以在使用QT += guiCONFIG += console时输出一条消息。

你需要printf("foo bar"),但cout << "foo bar"不起作用


2
投票

我在下面使用这个标题来完成我的项目。希望能帮助到你。

#ifndef __DEBUG__H
#define __DEBUG__H

#include <QtGui>    

static void myMessageOutput(bool debug, QtMsgType type, const QString & msg) {

    if (!debug) return;

    QDateTime dateTime = QDateTime::currentDateTime();
    QString dateString = dateTime.toString("yyyy.MM.dd hh:mm:ss:zzz");

    switch (type) {

        case QtDebugMsg:
            fprintf(stderr, "Debug: %s\n", msg.toAscii().data());
            break;
        case QtWarningMsg:
            fprintf(stderr, "Warning: %s\n", msg.toAscii().data());
            break;
        case QtCriticalMsg:
            fprintf(stderr, "Critical: %s\n", msg.toAscii().data());
            break;
        case QtFatalMsg:
            fprintf(stderr, "Fatal: %s\n", msg.toAscii().data());
            abort();
    }
}

#endif

PS:你可以在将来添加dateString输出。


2
投票

你可能想要调查的东西,至少对于windows来说,是windows api中的AllocConsole()函数。它调用GetStdHandle几次来重定向stdout,stderr等等。(一个快速测试显示这并不完全按我们的意愿去做。你确实得到了一个与你的其他Qt一起打开的控制台窗口,但你不能输出到它。据推测,因为控制台窗口是打开的,有一些方法可以访问它,获取它的句柄,或以某种方式访问​​和操作它。这是MSDN文档,对于那些有兴趣解决这个问题的人来说:

AllocConsole():http://msdn.microsoft.com/en-us/library/windows/desktop/ms681944%28v=vs.85%29.aspx

GetStdHandle(...):http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx

(我将此添加为评论,但规则阻止我这样做......)


0
投票

首先,为什么需要在发布模式构建中输出到控制台?当有一个gui时,没有人会想到那里看...

二,qDebug很花哨:)

第三,你可以尝试将console添加到你的.proCONFIG,它可能会奏效。


0
投票

在.pro中添加

CONFIG          += console
© www.soinside.com 2019 - 2024. All rights reserved.