How to redirect qml's console.log() to cpp std

2019-05-14 14:25发布

I am using qml( qtCreator ) and cpp (visual studio).

Usually the error messages are shown to the console, both from cpp and qml.

My requirement is that I should not have a console.

So I wrote a window application.

But when a flag has been set, I should launch a console. And show the corresponding error messages there.

I have used the following code in a function to set up this.

HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
FILE* hf_out = _fdopen(hCrt, "w");
setvbuf(hf_out, NULL, _IONBF, 128);

// redirecting the buffers to the file handle
*stdout = *hf_out;
*stderr = *hf_out;

//attach std input to console
HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
FILE* hf_in = _fdopen(hCrt, "r");
setvbuf(hf_in, NULL, _IONBF, 128);
*stdin = *hf_in;

This will print the error log from stdout and stderr to a console.

To redirect qt error logs we can use.

How to redirect qDebug, qWarning, qCritical etc output?

But how do we redirect the output from console.log() of qml to the console.

Thanks in advance.

4条回答
地球回转人心会变
2楼-- · 2019-05-14 14:41

Use QMLLogging. It's fast, typesafe and feature-rich

Disclosure: I am author of this library

查看更多
放荡不羁爱自由
3楼-- · 2019-05-14 14:42

If you need some log from the QML source code, you can create your own Logger QML object. This object will use your C++ logging system to log where you want and at your preferred level. To achieve this result, first create a C++ class that inherit from QQuickItem, for example:

QmlLogger.hpp

#include <QQuickItem>

class QmlLogger : public QQuickItem
{
    Q_OBJECT
public:
    explicit QmlLogger(QQuickItem *iParent = 0);

    // Q_INVOKABLE log method will be called by Qml source.
    Q_INVOKABLE void log(unsigned int iLogLevel, const QString& iDataToLog) const;

    enum Level
    {
        Error = 0,
        Warning,
        Info,
        Debug,
        Trace            
    };
    Q_ENUMS(Level)

private:
    YourLogger mYourLogger; // YourLogger is your system to log on C++ world
};

QmlLogger.cpp

#include <QmlLogger.hpp>

// Your Constructor

// Implementation of log method callable from Qml source
void log(unsigned int iLogLevel, const QString& iDataToLog) const
{
    switch(iLogLevel)
    {
        case Error: // ERROR
            // use you logger to log iDataToLog at error level
            break;
        case Warning: // WARNING
            // use you logger to log iDataToLog at warning level
            break;
        case Info: // INFO
            // use you logger to log iDataToLog at info level
            break;
        case Debug: // DEBUG
            // use you logger to log iDataToLog at debug level
            break;
        case Trace: // TRACE
            // use you logger to log iDataToLog at trace level
            break;
    }
}

Now, you have to register the new object to make it available to QML engine, then we have to use the template function qmlRegisterType from the QQmlEngine class. Use this function after you entering the main Qt loop, for example in this way:

int typeId = qmlRegisterType<QmlLogger>("QmlLogger", 1, 0, "Logger");
// if typeId is 0 => Error
Q_ASSERT(typeId);

In C++ we have finished. Now in QML source, we can use the new object in this simple way

import QmlLogger 1.0

Logger{
    id: logger
}

function aFunctionThatYouWantToDebug(iArgumentOne, iArgumentTwo){
    // logging
    logger.log(Logger.Debug, "Entering function aFunctionThatYouWantToDebug(" + iArgumentOne + ", " + iArgumentTwo + ")")

    // body of function ...
}

Calling the log method in QML source, is equivalent to call the log method in C++ class QmlLogger, that write in your log file, the data logged.

查看更多
家丑人穷心不美
4楼-- · 2019-05-14 14:55

It's the same process as for other Qt messages. The message emitted by console.log() will reach the Qt message handler you install with a QtDebugMsg severity.

查看更多
神经病院院长
5楼-- · 2019-05-14 14:59

Here you can find a more verbose explanation.

console.log is simply just qDebug, there is no difference to an end use. Your code should work, so I guess you just have not tested it properly. Although, your code seems to be strange because it is unnecessarily platform specific.

Likely that you should get rid of that.

By the way, Qt 4 was implementing something similar with QML viewer. Here you can find the code for an implementation example, in doubt.

Hope, my reply answers your question. If not, please clarify.

查看更多
登录 后发表回答