web-dev-qa-db-ja.com

Qt GUIアプリでのコンソール出力?

コマンドラインオプションを渡すことができる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();
}

ただし、コマンドプロンプトからアプリを実行すると、コンソールメッセージは表示されません。誰も私がこれを機能させる方法を知っていますか?

47
Rob

Windowsは、デュアルモードアプリケーションを実際にサポートしていません。

コンソール出力を表示するには、コンソールアプリケーションを作成する必要があります

CONFIG += console

ただし、プログラムをダブルクリックしてGUIモードバージョンを起動すると、コンソールウィンドウが表示されますが、これはおそらく望んでいないことです。コンソールウィンドウが表示されないようにするには、GUIモードアプリケーションを作成する必要があります。この場合、コンソールに出力が表示されません。

1つのアイデアは、コンソールアプリケーションであり、出力を提供する2つ目の小さなアプリケーションを作成することです。これは、2番目の呼び出しを呼び出して作業を行うことができます。

または、すべての機能をDLLに入れてから、DLLを呼び出す非常に単純なメイン関数を持つ2つのバージョンの.exeファイルを作成できます。1つはGUI用で、もう1つはコンソール。

46
David Dibben

追加:

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

main()の上部。これにより、プログラムがコンソールで起動された場合にのみコンソールへの出力が有効になり、他の状況ではコンソールウィンドウがポップアップしません。コンソール外でアプリを実行したときにメッセージを表示するコンソールウィンドウを作成する場合は、条件を次のように変更できます。

_if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())
_
12
patstew
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」を含めることができないコードもあります。

6
Gank

_QT += gui_を使用する場合、コンソールにメッセージを出力する方法はありません。

fprintf(stderr, ...)も出力を印刷できません。

代わりにQMessageBoxを使用して、メッセージを表示します。

5
raidsan

ああ、_QT += gui_と_CONFIG += console_を使用しているときにメッセージを出力できます。

printf("foo bar")が必要ですが、_cout << "foo bar"_は機能しません

4
Seb

私はこのヘッダーをプロジェクトに使用しました。それが役に立てば幸い。

#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
mosg

少なくともウィンドウについては、Windows APIのAllocConsole()関数を調べてください。 GetStdHandleを数回呼び出して、stdout、stderrなどをリダイレクトします(簡単なテストでは、これが目的の処理を完全に実行しているわけではないことが示されています。おそらく、コンソールウィンドウが開いているため、コンソールウィンドウにアクセスする方法、ハンドルを取得する方法、または何らかの方法でアクセスして操作する方法があります。

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
Josh

.proに追加します

CONFIG          += console
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」を使用せずにwithoutを試しましたが、ストリームをリダイレクトして独自にコンソールを作成する必要があります。

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

[〜#〜] but [〜#〜]これは、デバッガから起動した場合にのみ機能します。そうでない場合、すべての入力もシステムに向けられます。つまり、std :: cinで名前を入力すると、システムはその名前をコマンドとして実行しようとします。 (非常に奇妙な)

この試みに対する他の2つの警告は、:: FreeConsole()を使用できないことであり、閉じられず、コンソールから起動するとアプリが起動します」閉じます。



最後に、このトピックに対する QApplicationのQtヘルプセクション があります。私はそこでアプリケーションを試してみましたが、は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が必要な場合はコンソールを非表示にして、終了して終了します。

0
Pixtar

まず、リリースモードビルドでコンソールに出力する必要があるのはなぜですか? GUIがあるとき、誰もそこを見るとは思わないでしょう...

第二に、qDebugは素晴らしいです:)

第三に、.proconsoleCONFIGを追加してみてください。うまくいくかもしれません。

0
rubenvb

また、これで遊んで、出力のリダイレクトが機能することを発見しましたが、すべてのウィンドウアプリケーションに存在するコンソールウィンドウへの出力を見たことはありません。 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
David Athersych

それは他の回答の見落としだったかもしれませんし、実際にコンソール出力が必要なのはユーザーの要件かもしれませんが、私にとって明らかな答えは、表示または非表示にできるセカンダリウィンドウを作成することです(チェックボックスまたはボタン付き)テキストボックスウィジェットにテキスト行を追加してすべてのメッセージを表示し、それをコンソールとして使用しますか?

このようなソリューションの利点は次のとおりです。

  • シンプルなソリューション(表示されるものすべてがシンプルなログです)。
  • 「コンソール」ウィジェットをメインアプリケーションウィンドウにドッキングする機能。 (Qtでは、とにかく)。
  • 多くのコンソールを作成する機能(複数のスレッドなどがある場合)。
  • ローカルコンソールの出力からネットワーク経由でクライアントにログを送信することへの非常に簡単な変更。

これがあなたに思考の糧を与えることを願っていますが、私はまだあなたがこれをどのようにすべきかを仮定する資格がありませんが、少しの検索/読書で私たちの誰もが非常に達成できるものであると想像できます!

0
Tech1337

Qt5Core.dllがアプリケーションの実行可能ファイルと同じディレクトリにあることを確認してください。

コンソールアプリケーションを使用したQt5でも同様の問題がありました。QtCreatorからアプリケーションを起動すると、出力テキストが表示され、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
user5157912