【问题标题】:How to redirect qml's console.log() to cpp stdout如何将 qml 的 console.log() 重定向到 cpp 标准输出
【发布时间】:2013-08-26 23:03:28
【问题描述】:

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

通常错误消息会显示在控制台上,来自 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错误日志。

How to redirect qDebug, qWarning, qCritical etc output?

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

提前致谢。

【问题讨论】:

  • -1 “不必要的平台特定”只是我对这段代码所说的委婉说法

标签: c++ qt qml qt5 qtquick2


【解决方案1】:

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

披露:我是这个库的作者

【讨论】:

  • 花式。我可以使用您的记录器获得 QML 代码中的位置吗?从console.debug 我使用自定义QtMessageHandler 得到类似qrc:/myapp/ui/SomeColumn.qml:209 (expression for onConversationPositionsChanged) 的信息。甚至有可能收集这些数据吗?
  • @SimonWarta 在当前版本中这是不可能的:) 随意贡献
【解决方案2】:

Here你可以找到更详细的解释。

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

您可能应该摆脱它。

顺便说一句,Qt 4 使用 QML 查看器实现了类似的功能。 Here你可以找到实现示例的代码,有疑问。

希望我的回复能回答您的问题。如果不是,请澄清。

【讨论】:

  • 是的,你是对的。我的代码正在运行。我在放置 qInstallMsgHandler(myMessageOutput); 时犯了一些错误;功能。感谢您的帮助。
【解决方案3】:

如果您需要来自 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.debug 也给了我代码中的 pisition,例如qrc:/myapp/ui/SomeColumn.qml:209 (expression for onConversationPositionsChanged)。您认为使用自定义记录器也可以收集此类信息吗?
【解决方案4】:

对于其他 Qt 消息,它是 same processconsole.log() 发出的消息将到达您安装的带有 QtDebugMsg 严重性的 Qt 消息处理程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 2012-08-15
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    相关资源
    最近更新 更多