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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3360548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:40:46  来源:igfitidea点击:

Console output in a Qt GUI app?

c++windowsqtqt4

提问by Rob

I have a Qt GUI application running on Windows that allows command-line options to be passed and under some circumstances I want to output a message to the console and then quit, for example:

我有一个在 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();
}

However, the console messages do not appear when I run the app from a command-prompt. Does anyone know how I can get this to work?

但是,当我从命令提示符运行应用程序时,控制台消息不会出现。有谁知道我怎样才能让它发挥作用?

采纳答案by David Dibben

Windows does not really support dual mode applications.

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

To see console output you need to create a console application

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

CONFIG += console

However, if you double click on the program to start the GUI mode version then you will get a console window appearing, which is probably not what you want. To prevent the console window appearing you have to create a GUI mode application in which case you get no output in the console.

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

One idea may be to create a second small application which is a console application and provides the output. This can call the second one to do the work.

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

Or you could put all the functionality in a DLL then create two versions of the .exe file which have very simple main functions which call into the DLL. One is for the GUI and one is for the console.

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

回答by patstew

Add:

添加:

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

at the top of main(). This will enable output to the console only if the program is started in a console, and won't pop up a console window in other situations. If you want to create a console window to display messages when you run the app outside a console you can change the condition to:

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

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

回答by Gank

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!";

You can't use std::cout as others have said,my way is perfect even for some code can't include "qdebug" !

您不能像其他人所说的那样使用 std::cout ,即使对于某些代码不能包含“qdebug”,我的方法也是完美的!

回答by raidsan

No way to output a message to console when using QT += gui.

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

fprintf(stderr, ...)also can't print output.

fprintf(stderr, ...)也不能打印输出。

Use QMessageBoxinstead to show the message.

QMessageBox改为使用来显示消息。

回答by Seb

Oh you can Output a message when using QT += guiand CONFIG += console.

哦,你可以在使用QT += guiand时输出消息CONFIG += console

You need printf("foo bar")but cout << "foo bar"doesn't works

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

回答by Josh

Something you may want to investigate, at least for windows, is the AllocConsole() function in the windows api. It calls GetStdHandle a few times to redirect stdout, stderr, etc. (A quick test shows this doesn't entirely do what we want it to do. You do get a console window opened alongside your other Qt stuff, but you can't output to it. Presumably, because the console window is open, there is some way to access it, get a handle to it, or access and manipulate it somehow. Here's the MSDN documentation for those interested in figuring this out:

您可能想要研究的东西,至少对于 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

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

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

(I'd add this as a comment, but the rules prevent me from doing so...)

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

回答by mosg

I used this header below for my projects. Hope it helps.

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

#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: you could add dateStringto output if you want in future.

PS:dateString如果将来需要,您可以添加到输出中。

回答by rubenvb

First of all, why would you need to output to console in a release mode build? Nobody will think to look there when there's a gui...

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

Second, qDebug is fancy :)

其次,qDebug 很花哨:)

Third, you can try adding consoleto your .pro's CONFIG, it might work.

第三,您可以尝试添加console到您的.pro's CONFIG,它可能会起作用。

回答by Derick Schoonbee

In your .pro add

在您的 .pro 添加

CONFIG          += console

回答by Tech1337

It may have been an oversight of other answers, or perhaps it is a requirement of the user to indeed need console output, but the obvious answer to me is to create a secondary window that can be shown or hidden (with a checkbox or button) that shows all messages by appending lines of text to a text box widget and use that as a console?

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

The benefits of such a solution are:

这种解决方案的好处是:

  • A simple solution (providing all it displays is a simple log).
  • The ability to dock the 'console' widget onto the main application window. (In Qt, anyhow).
  • The ability to create many consoles (if more than 1 thread, etc).
  • A pretty easy change from local console output to sending log over network to a client.
  • 一个简单的解决方案(提供它显示的所有内容是一个简单的日志)。
  • 能够将“控制台”小部件停靠在主应用程序窗口上。(无论如何,在 Qt 中)。
  • 创建多个控制台的能力(如果超过 1 个线程等)。
  • 从本地控制台输出到通过网络向客户端发送日志的非常简单的更改。

Hope this gives you food for thought, although I am not in any way yet qualified to postulate on how you should do this, I can imagine it is something very achievable by any one of us with a little searching / reading!

希望这能让你深思,虽然我还没有资格假设你应该如何做到这一点,我可以想象这是我们任何人只要稍微搜索/阅读就可以实现的事情!