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.
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.
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.
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.
Use QMLLogging. It's fast, typesafe and feature-rich
Disclosure: I am author of this library