QtPlugin: connect or redirect stdout / stdcerr
-
My full application is composed by:
a) A Qt GUI main application
b) A set of custom plugins (shared libraries with Qt interfaces + GUI) that are loaded inside the main application in run-time.I would like to connect these plugins
stdout / stdcerrto aQPlainTextEditcomponent located in my main application.I did something like this using
QProcesshere, and works good:
https://forum.qt.io/topic/109682/qprocess-not-reading-only-std-cerr/3// Topic example connecting stdout of QProcess: connect(_process, &QProcess::readyReadStandardOutput, [&]() { auto data = _process->readAllStandardOutput(); ui->console_txt->appendPlainText(data); });Following this topic above, I think that somehow I have to
connectthereadyReadStandardOutputplugin method to myui->qPlainTextEdit->appendPlainText(data);Of course, my plugin class / interface don't have these
readyReadStandardOutputandreadyReadStandardErrorQProcess methods.Looking this topic, I would like to apply the same
connectidea but replacing theQProcessby my own "shared library" (plugins with Qt interface).Here is my plugin header interface (API):
#ifndef PLUGIN_API_H #define PLUGIN_API_H #include <QString> #include <QDebug> #include <QJsonObject> #include <QObject> class Plugin_API : public QObject { Q_OBJECT public: virtual ~Plugin_API() = default; virtual QJsonObject get_data(void) = 0; virtual void open_ui(const QJsonObject ui_data) = 0; virtual void run(const int job_id) = 0; // ===== SIGNALS ===== // virtual void send_msg(const QJsonObject msg) = 0; }; // Declare our interface: Q_DECLARE_INTERFACE(Plugin_API, "com.lamar.plugin") #endif // PLUGIN_API_HBelow is one plugin example header that is using the
PLUGIN_APIinterface above:#ifndef ANALYSIS_X_H #define ANALYSIS_X_H #include <QObject> #include <QtPlugin> #include <QJsonDocument> #include <QJsonArray> #include <QJsonObject> #include <QFile> #include <QByteArray> #include "analysis_x_global.h" #include "plugin_api.h" #include "dialog.h" class ANALYSIS_XSHARED_EXPORT Analysis_x: public Plugin_API { Q_OBJECT Q_PLUGIN_METADATA(IID "com.lamar.plugin") Q_INTERFACES(Plugin_API) public: explicit Analysis_x(QObject* parent = nullptr); ~Analysis_x() override; QJsonObject get_data(void) override; void open_ui(const QJsonObject ui_data) override; void run(const int step_id) override; private: QJsonObject _data; Dialog _ui; signals: void send_msg(const QJsonObject msg) override; public slots: void save_ui(QJsonObject updated_ui); }; #endif // ANALYSIS_X_HHow can I connect the plugin
stdout/stdcerrto theQPlainTextEditin the main Qt GUI application?Here are some related Qt topics:
https://forum.qt.io/topic/22538/solved-qt-capture-stdout
https://wiki.qt.io/Plugins
https://doc.qt.io/qt-5/qtplugin.html -
It's the std::out and std::err of your application that are going to be used.
See this stack overflow answer of a way to capture it.
-
Hi,
If you using Qt logging facilities, then use a message handler.
-
Hi
Just so i understand fully.
The plugins runs "things" with QProcess and you want to send the results to MainWindow ?
Like you show
// Topic example connecting stdout of QProcess:
connect(_process, &QProcess::readyReadStandardOutput, & {
auto data = _process->readAllStandardOutput();
ui->console_txt->appendPlainText(data);
});just that ui->console_txt is in main and you cant do that directly or where does
stdout / stdcerr come into play ?first i though you wanted to capture std::cout but then realized you were talking about QProcess.
-
Hi
Just so i understand fully.
The plugins runs "things" with QProcess and you want to send the results to MainWindow ?
Like you show
// Topic example connecting stdout of QProcess:
connect(_process, &QProcess::readyReadStandardOutput, & {
auto data = _process->readAllStandardOutput();
ui->console_txt->appendPlainText(data);
});just that ui->console_txt is in main and you cant do that directly or where does
stdout / stdcerr come into play ?first i though you wanted to capture std::cout but then realized you were talking about QProcess.
@mrjj No...
My old example is usingQProcess...and it works good!Now, I would like to do the same idea with my custom plugin classes.
These plugins are NOTQProcess. They areQtPlugin(shared library with GUI).So I would like to know how can I connect the plugin
stdout/stdcerrto theQPlainTextEditlocated in my main application. -
@mrjj No...
My old example is usingQProcess...and it works good!Now, I would like to do the same idea with my custom plugin classes.
These plugins are NOTQProcess. They areQtPlugin(shared library with GUI).So I would like to know how can I connect the plugin
stdout/stdcerrto theQPlainTextEditlocated in my main application.@fem_dev
Hi
Sorry I don't understand
what stdout/stdcerr
you mean when its a plugin. (and you run nothing in Qprocess)What is it you want capture and send to QPlainTextEdit ?
Do you mean cout ? printf ? cerr ?
Can you give an example ?Anyway, i assume you mean messages of some sort
and qDebug is excellent for that.
All messages from plugins could go to same place and be shown on screen.About the message handler
https://doc.qt.io/qt-5/qtglobal.html#qInstallMessageHandlerexample
https://stackoverflow.com/questions/4954140/how-to-redirect-qdebug-qwarning-qcritical-etc-output -
@fem_dev
Hi
Sorry I don't understand
what stdout/stdcerr
you mean when its a plugin. (and you run nothing in Qprocess)What is it you want capture and send to QPlainTextEdit ?
Do you mean cout ? printf ? cerr ?
Can you give an example ?Anyway, i assume you mean messages of some sort
and qDebug is excellent for that.
All messages from plugins could go to same place and be shown on screen.About the message handler
https://doc.qt.io/qt-5/qtglobal.html#qInstallMessageHandlerexample
https://stackoverflow.com/questions/4954140/how-to-redirect-qdebug-qwarning-qcritical-etc-output@mrjj Thank you, for your quick response. I will try to explain this better.
Forget completely the
QProcess. I'm not using it any more.
TheQProcessexample above was only a conceptual idea of what I really want to do at this point.In this image below I did a abstract example of what I want to do:

Explanation:
-
When the "Open Plugin X GUI" button was clicked, I call the
PLUGIN_APIinterface method calledopen_ui().
So, the plugin GUI is showed in the screen as a separated window.
At this moment, I have 2 windows in my screen:
a) Main Application
b) Plugin X -
Inside que Plugin X GUI, I have a button. If I click this button, I trigger an action, I mean, a
Plugin Xinternal method called:button_clicked() -
The
PluginX::button_clicked()uses Standard Output and Standard Error (std::coutandstd::cerr) -
I would like to see these outputs from Plugin X
std::coutandstd::cerrin theQPlainTextEditlocated inside the Main Application GUI.
So, every time that the user trigger thePluginX::button_clicked()method, I want to see these 2 messages in theQPlainTextEdit:
Plugin X: Button A clicked Plugin X: Error exampleI known that I can do it using
signals and slots, but I would like to do that connecting/capturing thestd::coutandstd::cerrbecause of software design reasons.Is this possible? How can I do it?
Thank you again,
-
-
It's the std::out and std::err of your application that are going to be used.
See this stack overflow answer of a way to capture it.
-
You should know that your plugin does not have its own output. Since it is part of the main application it will share its output. @SGaist proposed the right solution. But you should know that the output will be mixed between your plugin and the regular application. It will not be the same as your previous experiment with a
QProcess. If you want to separate those you need to use something else for output. Since you know that it should show up in the text edit, you could write your own stream operator which will update the text edit. Then use your new stream operator. -
You should know that your plugin does not have its own output. Since it is part of the main application it will share its output. @SGaist proposed the right solution. But you should know that the output will be mixed between your plugin and the regular application. It will not be the same as your previous experiment with a
QProcess. If you want to separate those you need to use something else for output. Since you know that it should show up in the text edit, you could write your own stream operator which will update the text edit. Then use your new stream operator.@SimonSchroeder thank you! I will think about that!