Консольный вывод в приложении Qt GUI? - PullRequest
47 голосов
/ 29 июля 2010

У меня есть приложение Qt GUI, работающее в Windows, которое позволяет передавать параметры командной строки, и в некоторых случаях я хочу вывести сообщение на консоль и затем выйти, например:

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();
}

Однако сообщения консоли не отображаются, когда я запускаю приложение из командной строки.Кто-нибудь знает, как я могу заставить это работать?

Ответы [ 16 ]

46 голосов
/ 30 июля 2010

Windows на самом деле не поддерживает двухрежимные приложения.

Чтобы увидеть вывод консоли, вам нужно создать консольное приложение

CONFIG += console

Однако, если вы дважды щелкнете по программе, чтобы запустить версию в режиме графического интерфейса, вы увидите окно консоли, которое, вероятно, не то, что вам нужно. Чтобы предотвратить появление окна консоли, вам нужно создать приложение в режиме графического интерфейса, в этом случае вы не получите вывод в консоли.

Одной из идей может быть создание второго небольшого приложения, которое является консольным приложением и обеспечивает вывод. Это может вызвать второй, чтобы сделать работу.

Или вы можете поместить всю функциональность в DLL, а затем создать две версии файла .exe, которые имеют очень простые основные функции, которые вызывают в DLL. Один для графического интерфейса, а другой для консоли.

12 голосов
/ 17 января 2017

Добавить:

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

вверху main().Это позволит выводить данные на консоль только в том случае, если программа запущена на консоли, и не будет отображаться в окне консоли в других ситуациях.Если вы хотите создать окно консоли для отображения сообщений при запуске приложения вне консоли, вы можете изменить условие на:

if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())
5 голосов
/ 22 декабря 2013
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"!

5 голосов
/ 29 мая 2011

Нет способа вывести сообщение на консоль при использовании QT += gui.

fprintf(stderr, ...) также не может распечатать вывод.

Используйте вместо этого QMessageBox, чтобы показать сообщение.

4 голосов
/ 04 января 2012

О, вы можете вывести сообщение при использовании QT += gui и CONFIG += console.

Вам нужно printf("foo bar"), но cout << "foo bar" не работает

2 голосов
/ 12 сентября 2012

Что-то, что вы, возможно, захотите исследовать, по крайней мере для Windows, - это функция AllocConsole () в Windows API. Он несколько раз вызывает 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

(я бы добавил это как комментарий, но правила не позволяют мне сделать это ...)

2 голосов
/ 29 июля 2010

Я использовал этот заголовок ниже для своих проектов.Надеюсь, это поможет.

#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 к выводу, если хотите в будущем.

0 голосов
/ 04 марта 2018

Так много ответов на эту тему.0.0

Так что я попробовал это с Qt5.x от Win7 до Win10 .Мне потребовалось несколько часов , чтобы найти хорошее рабочее решение, которое не вызывает каких-либо проблем в цепочке:

#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 в 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, просто используйте опцию консоли, скройте консоль, если вам нужен графический интерфейс, и закройте ее через выход.

0 голосов
/ 03 марта 2017

Легко

Шаг 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

Надеюсь, он вас научит.

Добрый день,

0 голосов
/ 21 июля 2016

После довольно долгой борьбы с точно такой же проблемой я обнаружил, что просто

CONFIG   += console

действительно справляется с задачей.Он не будет работать, пока вы явно не скажете QtCreator выполнить qmake над проектом (щелкнуть правой кнопкой мыши на проекте) И изменить что-то внутри исходного файла, а затем пересобрать.В противном случае компиляция пропускается, и вы все равно не увидите вывод в командной строке.Теперь моя программа работает как в графическом интерфейсе, так и в режиме командной строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...