I am creating a program where I run processes in Qt using the QProcess framework on Ubuntu 16.04 Qt 5.5.1 with C++ 11 enabled. I am directing the process output stream to a QTextEdit.
I would like to colorize this output to use the same colors which native terminals interpret by using the embedded ANSI escape color sequences. However, I am unable to parse the escape sequences as they appear to be missing from the QProcess output. I originally thought QString was stripping them, but after some testing I do not believe this to be the case.
I found some information to point me in the ANSI escape color interpretation direction if I could just keep the escape sequences in the QProcess output.
Here is an example project of what I am doing in Qt code.
The source file...
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QString>
#include <QProcess>
#include <QStringList>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStringList input = {"gcc will_not_build.c"};
QProcess * proc = new QProcess();
proc->setReadChannel(QProcess::StandardOutput);
proc->setProcessChannelMode(QProcess::MergedChannels);
proc->setWorkingDirectory("/path/to/test/c/file/");
//Start bash
proc->start("bash");
proc->waitForStarted();
// Write as many commands to this process as needed
foreach(QString str, input){
proc->write(str.toUtf8() + "\n");
proc->waitForBytesWritten(-1);
}
// Let bash close gracefully
proc->write("exit $?\n");
proc->waitForBytesWritten(-1);
proc->closeWriteChannel();
proc->waitForFinished();
proc->waitForReadyRead();
QByteArray read_data = proc->readAll();
// The use of tr(read_data) also works here.
QString output = tr(read_data);//QString::fromStdString (read_data.toStdString ());
proc->closeReadChannel(QProcess::StandardOutput);
proc->close();
delete proc;
// Add the output to the text box
ui->textEdit->append (output);
}
MainWindow::~MainWindow()
{
delete ui;
}
The header file...
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
The form file...
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>33</x>
<y>19</y>
<width>331</width>
<height>211</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>19</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
The C source file...
int main(){
// Intentionally will not build
I will not build :)
}
My output looks like this:
QProcess gcc output
The output of the native Linux terminal looks like this:
Linux terminal gcc output with colors
Does anyone know how I might go about keeping the ANSI escape color sequences in the QProcess output so I can simulate the Linux terminal colors?
As a side note I have dug around in the Qt Creator source code and there is a class which can convert ANSI escape colors to Rich Text colors so I know someone has been down this road. Then again, when building projects, Qt Creator does not colorize the build output in it's own Terminal for some reason.
QProcess
doesn't interfere with the process output, it's just that gcc
- as many other programs that emit colored output - by default emit color escape sequences only when it detects that it's writing on a TTY device.
If you want to disable this heuristic and ask to always produce colored output, you have to add the -fdiagnostics-color=always
option to the compiler command line.