Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__LINE__ __FILE__ OR similar function in qml

Tags:

qt

qml

qtquick2

I am trying to print caller function, line number and file name without throwing an error for normal debugging purpose in QML. I can print caller function name as follows

console.log("Caller Function Name"+arguments.callee.caller.name); 
like image 775
SourabhKus Avatar asked Dec 27 '16 07:12

SourabhKus


1 Answers

You can override qInstallMessageHandler default function and provide your custom function which also prints line number / caller. You can find an example in the linked documentation. Another partial example:

void loggingMessageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg)
{
    QString timeStr(QDateTime::currentDateTime().toString("dd-MM-yy HH:mm:ss:zzz"));
    QString contextString(QString("[%1  %2]").arg(context.file).arg(context.line));

    mutex.lock();

    QString level;
    if(logFile.isOpen())
    {
        switch (type) {
        case QtInfoMsg:     level = QString("INF"); break;
        case QtDebugMsg:    level = QString("DEB"); break;
        case QtWarningMsg:  level = QString("WAR"); break;
        case QtCriticalMsg: level = QString("CRT"); break;
        case QtFatalMsg:    level = QString("FTL"); break;
        }
        QTextStream stream(&logFile);
        stream << timeStr << " " << contextString << "\t"  << level << "\t"  << msg << endl;
        stream.flush();
    }

#if defined(Q_OS_WIN)
    OutputDebugString(reinterpret_cast<const wchar_t *>(level.append(' ' + msg + '\n').utf16()));
#elif defined(Q_OS_ANDROID)
    android_default_message_handler(type, context, level.append(" " + msg));
#else   // MACX || IOS || LINUX
    fprintf(stderr, "%s\n", level.append(" " + msg).toLocal8Bit().constData());
#endif
      mutex.unlock();
}

If logFile is open, logging data is wrote to that in a critical section delimited by a QMutex otherwise it is simply output to the standard output of each platform.

Whatever is the handler you define, it can be combined with categorized logging (available since Qt 5.2) to easily setup a custom logging facility tailored on your needs. You just need to define your logging categories, as described in this blog post, and call qCDebug, qCInfo(), qCWarning() and so on. Depending on the active categories (set via the static function setFilterRules() of QLoggingCategory) different logging info can be printed or skipped.

That's especially interesting now that Qt 5.8 is available. Since this release, you can use categories also in QML, i.e. you can call console functions and pass along a category, e.g.

function myFancyFunction() {
    // foo code
    console.log(myFancyCategory, "message");
    // bar code
}

Also, categories declaration can be done fully in QML via the ad hoc type LoggingCategory.

ADDENDUM (Qt < 5.0)

The proposed solution works in a Qt 5.0+ environment with categories fully usable with Qt 5.3+ and QML categories available in Qt 5.8+; in a Qt 4.x environment you should override qInstallMsgHandler but you do not have a QMessageLogContext. That means you should manage file/line info outside the handler, e.g. you have to use Q_FUNC_INFO or rely on __FILE__ and __LINE__ in C++ (note that the latters have been removed in latest 5.x releases as e.g. discussed here).

like image 194
BaCaRoZzo Avatar answered Oct 18 '22 06:10

BaCaRoZzo