Qt를 사용할 때 콘솔에 인쇄하는 방법


159

컴퓨터 그래픽에서 일부 프로그램을 만들기 위해 Qt4 및 C ++을 사용하고 있습니다. 디버깅 cout하지 않고 런타임에 콘솔에서 일부 변수를 인쇄 할 수 있어야하지만 라이브러리를 추가해도 작동하지 않는 것 같습니다. 이것을 할 수있는 방법이 있습니까?


3
cout이 작동하지 않기 때문에 cout이 정교해질 수 있습니까? 컴파일 오류가 발생했습니다. 당신에게 효과가없는 cout의 코드 예제를 보여줄 수 있습니까? 응용 프로그램 실행 방법도 설명하십시오. 콘솔 또는 IDE에서 실행 중이고 출력 창에 출력이 표시되지 않습니까?
Arnold Spence

완전성을 위해 : @ArnoldSpence-라이브러리가 없으면 얻을 수 있습니다 error: ‘cout’ was not declared in this scope. iostream으로, 나는 얻는다 error: no match for ‘operator<<’ in ‘std::operator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char>&)(& std::cout)), ...; 대답에 명령을 사용하면 정상적으로 작동합니다.
sdaau 2016 년

문제 설명이 단순히 "작동하지 않습니다"인 경우 솔루션을 제공하기가 어렵습니다. 제발 편집 보다 완벽한 당신이 일어날 것으로 예상 무엇을 설명하는 방법과 실제 결과에서 해당 다르다을 제공하기 위해 귀하의 질문에. 유용한 설명에 대한 힌트 를 요청하는 방법을 참조하십시오 .
Toby Speight

이 경우 이러한 "변수"가 Qt 관련 개체 (예 :)임을 명시 적으로 지정해야합니다 QString.
user202729

답변:


203

에 인쇄하기에 충분하면 stderr원래 디버깅을 위해 의도 된 다음 스트림을 사용할 수 있습니다.

#include<QDebug>

//qInfo is qt5.5+ only.
qInfo() << "C++ Style Info Message";
qInfo( "C Style Info Message" );

qDebug() << "C++ Style Debug Message";
qDebug( "C Style Debug Message" );

qWarning() << "C++ Style Warning Message";
qWarning( "C Style Warning Message" );

qCritical() << "C++ Style Critical Error Message";
qCritical( "C Style Critical Error Message" );

// qFatal does not have a C++ style method.
qFatal( "C Style Fatal Error Message" );

주석에서 지적했듯이 qDebug 메시지 QT_NO_DEBUG_OUTPUT가 정의 되어 있으면 제거됩니다.

stdout이 필요한 경우 Kyle Strand가 지적한 것처럼 다음과 같이 시도 할 수 있습니다.

QTextStream& qStdOut()
{
    static QTextStream ts( stdout );
    return ts;
}

그런 다음 다음과 같이 전화를 걸 수 있습니다.

qStdOut() << "std out!";

1
나는 디버깅하지 않고 디버깅하는 동안이 아니라 런타임 동안 콘솔에 메시지를 쓸 수있는 기능이 있어야한다고 물었다.
lesolorzanov

11
이름에도 불구하고이 함수는 디버거를 사용한 디버깅과 관련이 없습니다. 그것은 Qt가 stderr로 출력을 보내기 위해 제공하는 편리한 기능으로, define으로 컴파일에서 제거 될 수 있습니다. 따라서 런타임시 콘솔로 출력을 얻는 대안입니다.
Arnold Spence

모두 감사합니다, 나는 이것을 사용하고 있습니다 :). 내가 사용한 코드를 작성할 필요가 없다고 생각합니다. 감사! 이것은 매우 유용했습니다.
lesolorzanov 님의

51
#include <QDebug>
ducky

62
모든 콘솔 출력에 qDebug를 사용하지 마십시오. 실제 디버그 인쇄에만 사용하십시오. 오류 및 경고에는 qWarning, qCritical 및 qFatal을 사용하십시오. QT_NO_DEBUG_OUTPUT으로 컴파일 할 때 qDebug 문을 제거하여 성능을 저장하고 응용 프로그램이 출력을 어지럽히는 것을 막을 수 있습니다.
JustMaximumPower

150

나는 이것이 가장 유용하다고 생각했다.

#include <QTextStream>

QTextStream out(stdout);
foreach(QString x, strings)
    out << x << endl;

14
왜 답변이 수락되지 않는지는 모르겠지만 가장 유용합니다.
Semyon Danilov

4
동의했다. stderr는 오류 (및 디버깅)를위한 것입니다. stdout 및 qt를 사용하는 유일한 답변이므로 이것이 허용되는 답변이어야합니다.
Marshall Eubanks

1
이것은 나를 위해 일했고-cout을 통해 정보를 출력하는 올바른 방법처럼 보였습니다
Michael Vincent

2
오류 / 경고를 인쇄하는 방법에 대한 Goz의 답변 정보와 qDebug()실제로 수행하는 작업 에 대한 약간의 정보 (Gaz의 답변이 슬프지 만 아래 주석에 표시됨)와 함께 정보를 통합하면 이것이 최고의 답변이 될 것입니다. (IMO는 OP가 대체를 요구하고 있기 때문에 이미 우월 std::cout하지만 40 명의 유권자는 동의하지 않는 것으로 보입니다).
Kyle Strand

QTextStream qStdout() { return {stdout}; }이것을 감싸는 유용한 방법 일 수 있습니다 qWarning(). 그리고 static일시적인 스트리밍을 피하기 위해 어떤 상태일까요?
Yakk-Adam Nevraumont

36

에 쓰기 stdout

와 같은 것을 std::cout응용 프로그램의 표준 출력에 쓰는 것을 원한다면 간단히 다음을 수행 할 수 있습니다 ( CapelliC ).

QTextStream(stdout) << "string to print" << endl;

임시 QTextStream객체를 만들지 않으려면 아래 주석에서 Yakk의 제안에 따라 static핸들 을 반환하는 함수를 만듭니다 stdout.

inline QTextStream& qStdout()
{
    static QTextStream r{stdout};
    return r;
}

...

foreach(QString x, strings)
    qStdout() << x << endl;

기억flush주기적으로 출력이 실제로 인쇄 보장하기 위해 스트림입니다.

에 쓰기 stderr

위의 기술은 다른 출력에도 사용될 수 있습니다. 그러나 글을 읽을 수있는 더 읽기 쉬운 방법이 있습니다 stderr( Goz의 신용 및 그의 답변 아래 주석).

qDebug() << "Debug Message";    // CAN BE REMOVED AT COMPILE TIME!
qWarning() << "Warning Message";
qCritical() << "Critical Error Message";
qFatal("Fatal Error Message");  // WILL KILL THE PROGRAM!

qDebug()QT_NO_DEBUG_OUTPUT컴파일 타임에 켜져 있으면 닫힙니다 .

(콘솔 이외의 앱의 경우 stderr. 와 다른 스트림으로 인쇄 할 수 있다는 의견에 Goz 메모가 있습니다 .)


참고 : 모든 Qt 인쇄 방법 const char*인수\0문자 가 끝나는 ISO-8859-1로 인코딩 된 문자열 이라고 가정합니다 .


1
QTextStream qStdout() { static QTextStream r{stdout}; return r; }?
Yakk-Adam Nevraumont

1
@Yakk 좋은 제안! 나는 내 대답에 포함시킬 것이다.
Kyle Strand

QT5로 컴파일 할 때 qFatal ()에서 오류가 발생합니다. 어쨌든 (있거나 거기에 / 일하지 않았 음) 게시물을 읽었습니다 ... 사용하지 마십시오! :)
relascope

1
@KyleStrand 그 기능을 사용할 수 없습니까? template <typename C> constexpr typename std::remove_const<typename std::remove_reference<C>::type>::type& no_const(C* c) { return const_cast<typename std::remove_const<typename std::remove_reference<C>::type>::type&>(*c); } 사용하십시오 : no_const(this).method() . 당신은 클래스에하는 방법으로 그 기능을 삽입 할 수 있으며, 다음도 통과 할 필요가 없습니다 것입니다 this: Foo& no_const() const { return ::no_const(this); } 없음 오타, 약속.
Reinstate Monica

1
@Mitch Hm, 해당 링크 및 Qt 설명서를 검토하면 옳습니다. 임시 QTextStream개체로 인해 실제로 알려진 문제가 있음을 나타내는 내용이 없습니다 . 편집했습니다.
Kyle Strand

32

이것을 프로젝트 파일에 추가하십시오.

CONFIG += console

5
어떤 빌드 시스템이 사용되는지에 관한 정보는 없습니다. 이것은를 사용할 때만 관련이 qmake있습니다.
Kyle Strand

19

어떤 변수를 인쇄 하시겠습니까? QString을 의미하는 경우이를 c-String으로 변환해야합니다. 시험:

std::cout << myString.toAscii().data();

8
@CoderaPurpa 당신은 추가 할 필요가#include <iostream>
세바스찬 Negraszus

myString.toUtf8().data()ASCII 범위 밖의 문자를 인쇄하기 때문에 더 좋습니다. 한자 예
peterchaula

8

또한 prinft와 유사한 구문이 있습니다. 예 :

qDebug ("message %d, says: %s",num,str); 

매우 편리합니다


8

프로젝트로 이동 한 Properties -> Linker-> System -> SubSystem다음로 설정하십시오 Console(/S).


1
Kyle Lutz의 답변과 같은 이것은 빌드 시스템에 따라 다릅니다.
Kyle Strand

3

iostream 라이브러리 를 포함 하고 coutstd 의 객체 라는 것을 정확히 설명 하십시오.

#include <iostream>

std::cout << "Hello" << std::endl;

1

stdio 라이브러리를 사용하여 stderr에 인쇄하는 경우 호출 fflush(stderr)하면 버퍼를 비우고 실시간 로깅을 받아야합니다.



0

글쎄, 인터넷에서 Qt의 GUI에서 stdout으로 메시지를 출력하는 방법을 설명하는 몇 가지 예제를 연구 한 후 qDebug ()를 통해 메시지를 콘솔로 리디렉션하고 qInstallMessageHandler ()를 설치하는 독립 실행 형 예제를 개선했습니다. 콘솔은 GUI와 동시에 표시되며 필요한 경우 숨길 수 있습니다. 코드는 프로젝트의 기존 코드와 쉽게 통합 할 수 있습니다. 라이센스 GNU GPL v2를 준수하는 한 여기에 전체 샘플이 있으며 원하는대로 자유롭게 사용할 수 있습니다. 당신은 일종의 형태와 MainWindow를 사용해야한다고 생각합니다. 그렇지 않으면 샘플이 실행되지만 강제로 종료하면 충돌 할 수 있습니다. 참고 : 대안을 테스트했기 때문에 닫기 버튼이나 메뉴 닫기를 통해 종료 할 수있는 방법이 없으며 결국 응용 프로그램이 중단 될 수 있습니다. 닫기 버튼이 없으면 응용 프로그램이 안정되어 기본 창에서 닫을 수 있습니다. 즐겨!

#include "mainwindow.h"
#include <QApplication>

//GNU GPL V2, 2015-02-07
#include <QMessageBox>
#include <windows.h>
#define CONSOLE_COLUMNS 80
#define CONSOLE_ROWS    5000
#define YOURCONSOLETITLE "Your_Console_Title"

typedef struct{

    CONSOLE_SCREEN_BUFFER_INFOEX conScreenBuffInfoEX;

    HANDLE con_screenbuf;
    HWND hwndConsole;
    HMENU consoleMenu ;
    QString consoleTitle;

    QMessageBox mBox;
    QString localMsg;
    QString errorMessage;
    WINBOOL errorCode;

} consoleT;

static consoleT *console;

BOOL WINAPI catchCTRL( DWORD ctrlMsg ){

        if( ctrlMsg == CTRL_C_EVENT ){

            HWND hwndWin = GetConsoleWindow();
               ShowWindow(hwndWin,SW_FORCEMINIMIZE);
        }

    return TRUE;
}

void removeCloseMenu(){

    int i;

    for( i = 0; i < 10; i++){

        console->hwndConsole = FindWindowW( NULL, console->consoleTitle.toStdWString().data());

        if(console->hwndConsole != NULL)
            break;
    }

    if( !(console->errorCode = 0) && (console->hwndConsole == NULL))
            console->errorMessage += QString("\nFindWindowW error: %1 \n").arg(console->errorCode);

    if( !(console->errorCode = 0) &&  !(console->consoleMenu = GetSystemMenu( console->hwndConsole, FALSE )) )
        console->errorMessage += QString("GetSystemMenu error: %1 \n").arg(console->errorCode);

    if(!(console->errorCode = DeleteMenu( console->consoleMenu, SC_CLOSE, MF_BYCOMMAND )))
           console->errorMessage += QString("DeleteMenu error: %1 \n").arg(console->errorCode);
}

void initialiseConsole(){

    console->conScreenBuffInfoEX.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
    console->consoleMenu = NULL;
    console->consoleTitle = YOURCONSOLETITLE;
    console->con_screenbuf = INVALID_HANDLE_VALUE;
    console->errorCode = 0;
    console->errorMessage = "";
    console->hwndConsole = NULL;
    console->localMsg = "";

    if(!(console->errorCode = FreeConsole()))
        console->errorMessage += QString("\nFreeConsole error: %1 \n").arg(console->errorCode);

    if(!(console->errorCode = AllocConsole()))
        console->errorMessage += QString("\nAllocConsole error: %1 \n").arg(console->errorCode);

    if( (console->errorCode = -1) && (INVALID_HANDLE_VALUE ==(console->con_screenbuf = CreateConsoleScreenBuffer( GENERIC_WRITE | GENERIC_READ,0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL))))
        console->errorMessage += QString("\nCreateConsoleScreenBuffer error: %1 \n").arg(console->errorCode);

    if(!(console->errorCode = SetConsoleActiveScreenBuffer(console->con_screenbuf)))
        console->errorMessage += QString("\nSetConsoleActiveScreenBuffer error: %1 \n").arg(console->errorCode);

    if(!(console->errorCode = GetConsoleScreenBufferInfoEx(console->con_screenbuf, &console->conScreenBuffInfoEX)))
        console->errorMessage += QString("\nGetConsoleScreenBufferInfoEx error: %1 \n").arg(console->errorCode);

    console->conScreenBuffInfoEX.dwSize.X = CONSOLE_COLUMNS;
    console->conScreenBuffInfoEX.dwSize.Y = CONSOLE_ROWS;

    if(!(console->errorCode = SetConsoleScreenBufferInfoEx(console->con_screenbuf, &console->conScreenBuffInfoEX)))
       console->errorMessage += QString("\nSetConsoleScreenBufferInfoEx error: %1 \n").arg(console->errorCode);

    if(!(console->errorCode = SetConsoleTitleW(console->consoleTitle.toStdWString().data())))
        console->errorMessage += QString("SetConsoleTitle error: %1 \n").arg(console->errorCode);

    SetConsoleCtrlHandler(NULL, FALSE);
    SetConsoleCtrlHandler(catchCTRL, TRUE);

    removeCloseMenu();

    if(console->errorMessage.length() > 0){
        console->mBox.setText(console->errorMessage);
        console->mBox.show();
    }

}

void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg){


    if((console->con_screenbuf != INVALID_HANDLE_VALUE)){

        switch (type) {

        case QtDebugMsg:
            console->localMsg = console->errorMessage + "Debug: " + msg;
            WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
            WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
            break;

        case QtWarningMsg:
            console->localMsg = console->errorMessage + "Warning: " + msg;
            WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length() , NULL, NULL );
            WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
            break;

        case QtCriticalMsg:
            console->localMsg = console->errorMessage + "Critical: " + msg;
            WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
            WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
            break;

        case QtFatalMsg:
            console->localMsg = console->errorMessage + "Fatal: " + msg;
            WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
            WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
            abort();
        }
    }
}



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

    qInstallMessageHandler(messageHandler);

    QApplication a(argc, argv);

    console = new consoleT();
    initialiseConsole();

    qDebug() << "Hello World!";

    MainWindow w;
    w.show();

    return a.exec();
}

0

"빌드 및 실행"> "터미널에서 실행"의 기본값-> 사용

버퍼를 플러시하려면이 명령을 사용하십시오-> fflush (stdout); printf또는 에서 "\ n"을 사용할 수도 있습니다 cout.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.