如何将 qml 的 console.log() 重定向到 cpp 标准输出

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

本文关键字:重定向 cpp 标准输出 log qml console      更新时间:2023-10-16

我正在使用qml(qtCreator)和cpp(visualstudio)。

通常,来自cpp和qml的错误消息都显示在控制台上。

我的要求是我不应该有控制台。

所以我写了一个窗口应用程序。

但当设置了标志后,我应该启动一个控制台。并在那里显示相应的错误消息。

我在一个函数中使用了以下代码来设置它。

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;

这将把stdout和stderr的错误日志打印到控制台。

要重定向qt错误日志,我们可以使用。

如何重定向qDebug、qWarning、qCritical等输出?

但是我们如何将qml的console.log()的输出重定向到控制台。

提前谢谢。

如果您需要QML源代码中的一些日志,您可以创建自己的Logger QML对象。这个对象将使用您的C++日志记录系统来记录您想要的位置和您喜欢的级别。为了实现这个结果,首先创建一个继承自QQuickItem的C++类,例如:

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

现在,您必须注册新对象以使其可用于QML引擎,然后我们必须使用QQmlEngine类中的模板函数qmlRegisterType。在进入主Qt循环后使用此功能,例如:

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

在C++中,我们已经完成了。现在在QML源中,我们可以以这种简单的方式使用新对象

import QmlLogger 1.0
Logger{
    id: logger
}
function aFunctionThatYouWantToDebug(iArgumentOne, iArgumentTwo){
    // logging
    logger.log(Logger.Debug, "Entering function aFunctionThatYouWantToDebug(" + iArgumentOne + ", " + iArgumentTwo + ")")
    // body of function ...
}

调用QML源中的log方法,相当于调用C++类QmlLogger中的log方式,即写入日志文件,记录数据。

这里可以找到更详细的解释。

console.log只是qDebug,与最终用途没有区别。你的代码应该可以工作,所以我想你只是没有正确测试它。尽管如此,您的代码似乎很奇怪,因为它是不必要的特定于平台的。

很可能你应该把它扔掉。

顺便说一下,Qt4正在用QML查看器实现类似的功能。在这里,您可以找到一个有疑问的实现示例的代码。

希望,我的回答回答了你的问题。如果没有,请澄清。

这与其他Qt消息的处理过程相同。console.log()发出的消息将到达您安装的具有QtDebugMsg严重性的Qt消息处理程序。

使用QMLLogging。它速度快,类型安全,功能丰富的

披露:我是这个库

的作者