Console Output in a Qt Gui App

Console output in a Qt GUI app?

Windows does not really support dual mode applications.

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.

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.

Display a Console in Qt

By default, GUI apps don't have the terminal enabled in QtCreator. Enabling it is simple:

  • In the left sidebar, click Projects
  • At the top, select your project's Run tab
  • In the Run section, check the Run in terminal checkbox

Sample Image

How to print version of a Qt GUI application to console

As we cleared some points in comments let's move on. ;)

Take a look at the documentation (http://doc.qt.io/qt-5/qapplication.html#details). In the detail section you see a sane way how to properly parse and handle command line options.

And here (https://stackoverflow.com/a/3886128/6385043) you can see a possibility for writing to standard output. Notice the QDebug caveat.

In my opinion, stick to the text file. You may generate it during build with qmake using the variable VERSION, which you can also use with QApplication::setApplicationVersion(QString).

Creating QT Application as GUI for existing console-based application on windows

I found a solution for my needs and can do what i want to do.. Actually i'm a bit disappointed. I thought it would be something more complex.

First i have to say it's an QtQuick Application .. Maybe i should have said that earlier.

I simply outsourced the process functions to another class. This class is passed to QML via the qmlRegisterType<>() function. I connected some signals from the process ( QProcess ) to slots in my own class and wrote my own functions to handle reading/writing data from and to the console application. With the QML-onClicked events i can pass my parameters and strings to the console app. And with some application logic i can handle the in/out requests and timings.

WrapperClass.h

class WrapperClass: public QObject
{
Q_OBJECT

public:
explicit WrapperClass(QObject *parent = nullptr);

QProcess *process;
QString str_proc_output;

Q_INVOKABLE void startProcess();
Q_INVOKABLE void stopProcess();

Q_INVOKABLE QString getOutput();
Q_INVOKABLE void writeByte(QString str);

Q_INVOKABLE QString getAllOutput();
private:

signals:

public slots:
void mReadyRead();
void mReadyReadStandardOutput();
void mFinished(int code);
void mBytesWritten(qint64 written);

};

WrapperClass.cpp

WrapperClass::WrapperClass(QObject *parent) : QObject(parent)
{
process = new QProcess();
process->setProgram("untitled.exe");
process->setProcessChannelMode(QProcess::MergedChannels);

str_proc_output = "";

connect(process, SIGNAL(readyRead()), this, SLOT(mReadyRead()));
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(mReadyReadStandardOutput()));
connect(process, SIGNAL(finished(int)), this, SLOT(mFinished(int)));
connect(process, SIGNAL(bytesWritten(qint64)), this, SLOT(mBytesWritten(qint64)));

}

void WrapperClass::startProcess() {
if(process->state() == QProcess::Running) {
stopProcess();
} else {
process->open(QProcess::ReadWrite);
}
}

void WrapperClass::stopProcess() {
process->close();
}

QString WrapperClass::getOutput() {
return str_proc_output;
}

QString WrapperClass::getAllOutput() {
QString str = process->readAll();

std::cout << str.toStdString() << std::endl;
return str;
}

void WrapperClass::writeByte(QString str) {

char cArr[str.length()] = {};

memcpy(cArr, str.toStdString().c_str(), str.length());

QByteArray arr = QByteArray(cArr, -1);
process->write(arr);
}

void WrapperClass::mReadyRead() {
QString s = QString(process->readAll());

std::cout << "ReadyRead: " << s.toStdString() << std::endl;
str_proc_output = s;
}

void WrapperClass::mReadyReadStandardOutput() {
QString s = QString(process->readAllStandardOutput());

std::cout << "ReadyReadStandardOutput: " << s.toStdString() << std::endl;

}

void WrapperClass::mFinished(int code) {
std::cout << "Process finished! (" << code << ')' << std::endl;
}

void WrapperClass::mBytesWritten(qint64 written) {

std::cout << "Bytes written: " << written << std::endl;

}

Main.cpp

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

qmlRegisterType<WrapperClass>("com.example.WrapperClass", 0, 1, "WrapperClass");

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;

return app.exec();
}

With registering the Cpp-Class to QML i'm able to trigger the read/write functions via Click-Events from QML-MouseArea or Button.

Redirect console output to pyqt5 gui in real time

When you redirect python output to file or pipe it is buffered for perfomance reasons. You need to run script with -u cli argument or flush every print output like this: print(something, flush=True). See this question for details.

self.process.start('python',['-u','Robot.py'])


Related Topics



Leave a reply



Submit