2
votes

Let's have a look at this little application:

#include <QString>
#include <QDebug>

int main(int argc, char *argv[]) {
  const auto test_string = 
    QString{"Some string \n \x01 \u0002 with some \r special chars"};
  qDebug() << test_string;
  qDebug(qPrintable(test_string));
}

It gives the following output:

"Some string \n \u0001 \u0002 with some \r special chars"
Some string
 special chars
Press <RETURN> to close this window...

This demonstrates how the qDebug << operator comes with some functionality that converts all the special characters of a QString to some readable string, which can easily be put in a string declaration in C++.

I would like to use this functionality to feed strings into a custom logging framework. Is there a possibility to use the same conversion function directly?

Effectively, this would mean to convert test_string to a QString instance that gives the same output on both the above qDebug statements.

1
I looked for implementation of QDebug::operator<<(const QString&) and ended up in a function template static inline putEscapedString(). Btw. I found that QDebug has a constructor where a QString may be passed. So, you might instance QDebug with a QString to use this as formatter. To me, this seems less annoying as just copying the source code from putEscapedString() to make your own formatter but the latter might be an option too.Scheff's Cat
bitbucket.org/codeimproved/qslog Please check this. SO moderation seems determined that I should copy paste qslog's implementation as my answer. No. Way. In. Hell.Zeks

1 Answers

0
votes

I had the same question and I did not found the complete answer (yet). However, I found QVariant which allows you to call toString() on the most basic C and Qt types:

QVariant("foo").toString(); // "foo"
QVariant(true).toString(); // "true"
QVariant(QDateTime("2020-11-28")).toString(); // "2020-11-28"

Then you could wrap this into one method:

QString variantToString(const QVariant variant) {
    return (variant.userType() != QMetaType::QString
            && variant.canConvert(QMetaType::QStringList))
        ? "(" + variant.toStringList().join(", ") + ")"
        : variant.toString();
}

variantToString(42); // "42" // works due to implicit cast

You could do a few extra checks for non-stringifiable types (see also canConvert() and userType(), e.g. lists, regular expressions or whatever you need, but I totally agree that it would be nicer to reuse Qt's own logging functions instead ...