web-dev-qa-db-fra.com

Sortie de la console dans une application Qt GUI?

J'ai une application graphique Qt sous Windows qui permet de transmettre les options de ligne de commande. Dans certaines circonstances, je souhaite envoyer un message à la console, puis quitter, par exemple:

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

Cependant, les messages de la console n'apparaissent pas lorsque j'exécute l'application à partir d'une invite de commande. Est-ce que quelqu'un sait comment je peux le faire fonctionner?

45
Rob

Windows ne prend pas vraiment en charge les applications en mode double. 

Pour voir la sortie de la console, vous devez créer une application console.

CONFIG += console

Cependant, si vous double-cliquez sur le programme pour démarrer la version en mode graphique, une fenêtre de console apparaîtra, ce qui n'est probablement pas ce que vous voulez. Pour éviter que la fenêtre de la console n'apparaisse, vous devez créer une application en mode graphique, auquel cas vous n'obtenez aucune sortie dans la console.

Une idée peut être de créer une deuxième petite application qui est une application console et fournit le résultat. Cela peut appeler le second pour faire le travail. 

Vous pouvez également placer toutes les fonctionnalités dans une DLL, puis créer deux versions du fichier .exe contenant des fonctions principales très simples qui appellent la DLL. L'un est pour l'interface graphique et l'autre est pour la console.

43
David Dibben

Ajouter:

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

au sommet de main(). Cela activera la sortie vers la console uniquement si le programme est démarré dans une console et ne fera pas apparaître une fenêtre de console dans d'autres situations. Si vous souhaitez créer une fenêtre de console pour afficher des messages lorsque vous exécutez l'application en dehors d'une console, vous pouvez modifier la condition en:

if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())
11
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!";

Vous ne pouvez pas utiliser std :: cout comme d'autres l'ont dit, ma méthode est parfaite, même si certains codes ne peuvent pas inclure "qdebug"!

5
Gank

Pas moyen de sortir un message sur la console en utilisant QT += gui.

fprintf(stderr, ...) également ne peut pas imprimer la sortie.

Utilisez plutôt QMessageBox pour afficher le message.

5
raidsan

Oh, vous pouvez générer un message lorsque vous utilisez QT += gui et CONFIG += console.

Vous avez besoin de printf("foo bar") mais cout << "foo bar" ne fonctionne pas

4
Seb

J'ai utilisé cet en-tête ci-dessous pour mes projets. J'espère que ça aide.

#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: vous pouvez ajouter dateString à la sortie si vous le souhaitez.

2
mosg

Vous voudrez peut-être étudier, du moins pour Windows, la fonction AllocConsole () dans l’API Windows. Il appelle plusieurs fois GetStdHandle pour rediriger stdout, stderr, etc. (Un test rapide montre que cela ne fait pas tout à fait ce que nous souhaitons. Vous ouvrez une fenêtre de console à côté de vos autres éléments Qt, mais vous Vraisemblablement, étant donné que la fenêtre de la console est ouverte, il existe un moyen d’y accéder, d’obtenir un descripteur, ou d’y accéder et de la manipuler d’une manière ou d’une autre. Voici la documentation MSDN pour ceux qui sont intéressés à comprendre ceci:

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

(J'ajouterais ceci comme commentaire, mais les règles m'empêchent de le faire ...)

2
Josh

Dans votre .pro ajouter

CONFIG          += console
0
Derick Schoonbee

Tant de réponses à ce sujet. 0.0

Je l’ai donc essayé avec Qt5.x de Win7 à Win10. Il m'a fallu quelques heures pour trouver une solution efficace qui ne pose aucun problème quelque part dans la chaîne:

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


Je l’ai essayé aussi sans la "CONFIG + = console", mais vous devez ensuite rediriger les flux et créer la console par vous-même:

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

MAIS cela ne fonctionne que si vous le démarrez via un débogueur, sinon toutes les entrées sont également dirigées vers le système. Cela signifie que si vous tapez un nom via std :: cin, le système tente d’exécuter le nom en tant que commande. (très étrange)

Deux autres avertissements à cette tentative seraient, vous ne pouvez pas utiliser :: FreeConsole () il ne le fermera pas et si vous le démarrez via une console l'application ne se fermera pas.



Enfin, il existe une section d’aide Qt dans QApplication relative à ce sujet. J'ai essayé l'exemple ici avec une application et il ne fonctionne pas pour l'interface graphique, il s'est coincé quelque part dans une boucle sans fin et l'interface graphique ne sera pas rendue ou se bloque simplement:

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


Donc, si vous utilisez Windows et Qt utilisez simplement l'option console, masquez la console si vous avez besoin de l'interface graphique et fermez-la via exit.

0
Pixtar

Tout d’abord, pourquoi auriez-vous besoin de sortir vers la console dans une version en mode édition? Personne ne songe à y regarder quand il y a une gui ...

Deuxièmement, qDebug est chic :)

Troisièmement, vous pouvez essayer d'ajouter console à votre CONFIG de .pro.

0
rubenvb

J'ai aussi joué avec cela, découvrant que la redirection de la sortie fonctionnait, mais je n'ai jamais vu de sortie dans la fenêtre de la console, présente pour toutes les applications Windows. C'est ma solution jusqu'à présent, jusqu'à ce que je trouve un remplaçant Qt pour ShowWindow et GetConsoleWindow.

Exécutez ceci à partir d'une invite de commande sans paramètre - récupérez la fenêtre. Exécuter à partir d'une invite de commande avec des paramètres (par exemple, cmd aaa bbb ccc) - vous obtenez le texte de sortie dans la fenêtre d'invite de commande - exactement comme vous le feriez pour n'importe quelle application de console Windows.

Veuillez excuser l’exemple boiteux - cela représente environ 30 minutes de bricolage.

#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

C’était peut-être un oubli des autres réponses, ou c’est peut-être une exigence de l’utilisateur d’avoir besoin de la sortie console, mais la réponse évidente est de créer une fenêtre secondaire pouvant être affichée ou masquée (avec une case à cocher ou un bouton) qui affiche tous les messages en ajoutant des lignes de texte à un widget de zone de texte et l’utilise comme console?

Les avantages d'une telle solution sont:

  • Une solution simple (tout ce qu’elle affiche est un simple journal).
  • La possibilité d'ancrer le widget 'console' sur la fenêtre principale de l'application. (En tout cas, de toute façon).
  • La possibilité de créer plusieurs consoles (si plus d'un thread, etc.).
  • Un changement assez facile de la sortie de la console locale à l'envoi d'un journal sur un réseau à un client.

J'espère que cela vous donne matière à réflexion, bien que je ne sois en aucun cas qualifié pour postuler sur la façon de procéder, mais je peux imaginer que c'est quelque chose de très réalisable pour n'importe lequel d'entre nous avec un peu de recherche/lecture!

0
Tech1337

Assurez-vous que Qt5Core.dll est dans le même répertoire que l'exécutable de votre application.

J'ai eu un problème similaire dans Qt5 avec une application en console: .Très étrange!

Je l'ai résolu en copiant Qt5Core.dll dans le répertoire contenant l'exécutable de l'application. 

Voici ma petite application console:

#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