Unsolved Can't construct a QString from a QByteArray inside the code of a QtCreator plugin
-
Hi, I am writing a QtCreator plugin and noticed I can't construct a QString from a QByteArray inside the code of said plugin. It does however work when I create a normal desktop or console application based on Qt using the same set of tools. This happens regardless of whether I use prebuilt binaries of QtCreator (installed using the Qt installer) or a version I've built myself (or the version of Qt for that matter). The compiler basically produces an error message telling me that no viable conversion from QByteArray to QString could be found.
I could for instance create a brand new plugin using the QtCreator wizard and write
QString butItDoesntWork(QByteArray("That really should work"));
anywhere in the code, for example inside the plugins constructor:
MyPluginPlugin::MyPluginPlugin() { // Create your members QString butItDoesntWork(QByteArray("That really should work")); }
to produce the previously mentioned error message ... or in excruciating detail:
04:14:19: Running steps for project myplugin... 04:14:19: Configuration unchanged, skipping qmake step. 04:14:19: Starting: "/usr/bin/make" -j8 g++ -c -pipe -Wno-noexcept-type -g -std=gnu++1y -fvisibility=hidden -fvisibility-inlines-hidden -Wall -W -D_REENTRANT -fPIC -DMYPLUGIN_LIBRARY -DWITH_TESTS -D'RELATIVE_PLUGIN_PATH="../lib/qtcreator/plugins"' -D'RELATIVE_LIBEXEC_PATH="../libexec/qtcreator"' -D'RELATIVE_DATA_PATH="../share/qtcreator"' -D'RELATIVE_DOC_PATH="../share/doc/qtcreator"' -DIDE_LIBRARY_BASENAME=\"lib\" -DQT_CREATOR -DQT_NO_CAST_TO_ASCII -DQT_RESTRICTED_CAST_FROM_ASCII -DQT_DISABLE_DEPRECATED_BEFORE=0x050900 -DQT_USE_FAST_OPERATOR_PLUS -DQT_USE_FAST_CONCATENATION -DQT_QML_DEBUG -DQT_PLUGIN -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_TESTLIB_LIB -DQT_CONCURRENT_LIB -DQT_CORE_LIB -DQT_TESTCASE_BUILDDIR='"/home/mehdi/axivion/experiments/qt-based/build-plugin-test-Desktop_Qt_5_12_0_GCC_64bit-Debug"' -I/home/mehdi/applications/qtcreator-dev/v4.8/src -I../../../../projects/Qt/qt-creator/src -I../../../../projects/Qt/qt-creator/src/libs -I/home/mehdi/projects/Qt/qt-creator/tools -I../../../../projects/Qt/qt-creator/src/plugins -I../../../../projects/Qt/qt-creator/src/libs -I. -I../../../../Qt/5.12.0/gcc_64/include -I../../../../Qt/5.12.0/gcc_64/include/QtWidgets -I../../../../Qt/5.12.0/gcc_64/include/QtGui -I../../../../Qt/5.12.0/gcc_64/include/QtTest -I../../../../Qt/5.12.0/gcc_64/include/QtConcurrent -I../../../../Qt/5.12.0/gcc_64/include/QtCore -I.moc/debug-shared -isystem /usr/include/libdrm -I../../../../Qt/5.12.0/gcc_64/mkspecs/linux-g++ -o .obj/debug-shared/mypluginplugin.o ../plugin-test/mypluginplugin.cpp ../plugin-test/mypluginplugin.cpp: In constructor ‘MyPlugin::Internal::MyPluginPlugin::MyPluginPlugin()’: ../plugin-test/mypluginplugin.cpp:22:66: error: no matching function for call to ‘QString::QString(QByteArray)’ QString butItDoesntWork(QByteArray("That really should work")); ^ In file included from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhashfunctions.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qlist.h:47, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhash.h:46, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qdebug.h:45, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qloggingcategory.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/QLoggingCategory:1, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/extensionsystem_global.h:28, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/iplugin.h:28, from ../plugin-test/mypluginplugin.h:5, from ../plugin-test/mypluginplugin.cpp:1: ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:829:29: note: candidate: ‘constexpr QString::QString(QStringDataPtr)’ Q_DECL_CONSTEXPR inline QString(QStringDataPtr dd) : d(dd.ptr) {} ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:829:29: note: no known conversion for argument 1 from ‘QByteArray’ to ‘QStringDataPtr’ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:828:5: note: candidate: ‘QString::QString(int, Qt::Initialization)’ QString(int size, Qt::Initialization); ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:828:5: note: candidate expects 2 arguments, 1 provided ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:691:5: note: candidate: ‘template<int N> QString::QString(char (&)[N])’ <deleted> QString(char (&)[N]) = delete; ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:691:5: note: template argument deduction/substitution failed: ../plugin-test/mypluginplugin.cpp:22:66: note: mismatched types ‘char [N]’ and ‘QByteArray’ QString butItDoesntWork(QByteArray("That really should work")); ^ In file included from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhashfunctions.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qlist.h:47, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhash.h:46, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qdebug.h:45, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qloggingcategory.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/QLoggingCategory:1, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/extensionsystem_global.h:28, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/iplugin.h:28, from ../plugin-test/mypluginplugin.h:5, from ../plugin-test/mypluginplugin.cpp:1: ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:687:12: note: candidate: ‘template<int N> QString::QString(const char (&)[N])’ inline QString(const char (&ch)[N]) ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:687:12: note: template argument deduction/substitution failed: ../plugin-test/mypluginplugin.cpp:22:66: note: mismatched types ‘const char [N]’ and ‘QByteArray’ QString butItDoesntWork(QByteArray("That really should work")); ^ In file included from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhashfunctions.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qlist.h:47, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhash.h:46, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qdebug.h:45, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qloggingcategory.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/QLoggingCategory:1, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/extensionsystem_global.h:28, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/iplugin.h:28, from ../plugin-test/mypluginplugin.h:5, from ../plugin-test/mypluginplugin.cpp:1: ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:234:12: note: candidate: ‘QString::QString(QString&&)’ inline QString(QString && other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); } ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:234:12: note: no known conversion for argument 1 from ‘QByteArray’ to ‘QString&&’ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:957:8: note: candidate: ‘QString::QString(const QString&)’ inline QString::QString(const QString &other) Q_DECL_NOTHROW : d(other.d) ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:957:8: note: no known conversion for argument 1 from ‘QByteArray’ to ‘const QString&’ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:931:8: note: candidate: ‘QString::QString(QLatin1String)’ inline QString::QString(QLatin1String aLatin1) : d(fromLatin1_helper(aLatin1.latin1(), aLatin1.size())) ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:931:8: note: no known conversion for argument 1 from ‘QByteArray’ to ‘QLatin1String’ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:226:5: note: candidate: ‘QString::QString(int, QChar)’ QString(int size, QChar c); ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:226:5: note: candidate expects 2 arguments, 1 provided ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:225:5: note: candidate: ‘QString::QString(QChar)’ QString(QChar c); ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:225:5: note: no known conversion for argument 1 from ‘QByteArray’ to ‘QChar’ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:224:14: note: candidate: ‘QString::QString(const QChar*, int)’ <near match> explicit QString(const QChar *unicode, int size = -1); ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:224:14: note: conversion of argument 1 would be ill-formed: ../plugin-test/mypluginplugin.cpp:22:66: error: conversion from ‘QByteArray’ to ‘const QChar*’ is ambiguous QString butItDoesntWork(QByteArray("That really should work")); ^ In file included from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:49, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhashfunctions.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qlist.h:47, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhash.h:46, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qdebug.h:45, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qloggingcategory.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/QLoggingCategory:1, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/extensionsystem_global.h:28, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/iplugin.h:28, from ../plugin-test/mypluginplugin.h:5, from ../plugin-test/mypluginplugin.cpp:1: ../../../../Qt/5.12.0/gcc_64/include/QtCore/qbytearray.h:492:8: note: candidate: ‘QByteArray::operator const void*() const’ <near match> inline QByteArray::operator const void *() const ^~~~~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qbytearray.h:492:8: note: no known conversion from ‘const void*’ to ‘const QChar*’ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qbytearray.h:450:5: note: candidate: ‘QByteArray::operator QNoImplicitBoolCast() const’ <near match> operator QNoImplicitBoolCast() const; ^~~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qbytearray.h:450:5: note: no known conversion from ‘QNoImplicitBoolCast’ {aka ‘int’} to ‘const QChar*’ In file included from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhashfunctions.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qlist.h:47, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qhash.h:46, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qdebug.h:45, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/qloggingcategory.h:44, from ../../../../Qt/5.12.0/gcc_64/include/QtCore/QLoggingCategory:1, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/extensionsystem_global.h:28, from ../../../../projects/Qt/qt-creator/src/libs/extensionsystem/iplugin.h:28, from ../plugin-test/mypluginplugin.h:5, from ../plugin-test/mypluginplugin.cpp:1: ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:1134:8: note: candidate: ‘QString::QString()’ inline QString::QString() Q_DECL_NOTHROW : d(Data::sharedNull()) {} ^~~~~~~ ../../../../Qt/5.12.0/gcc_64/include/QtCore/qstring.h:1134:8: note: candidate expects 0 arguments, 1 provided Makefile:986: recipe for target '.obj/debug-shared/mypluginplugin.o' failed make: *** [.obj/debug-shared/mypluginplugin.o] Error 1 04:14:20: The process "/usr/bin/make" exited with code 2. Error while building/deploying project myplugin (kit: Desktop Qt 5.12.0 GCC 64bit) When executing step "Make" 04:14:20: Elapsed time: 00:01.
I could, of course, resort to some hacks and convert QByteArray to a stdString and then read that back into a QString using QString::fromStdString but I am trying to use code generated by a code generator that makes heavy use of the conversion in question and would like to avoid having to mess around with the generator templates or edit the generated code. Any idea what the cause of this rather weird behaviour is?
Thanks in advance
-
@mehdi said in Can't construct a QString from a QByteArray inside the code of a QtCreator plugin:
Can't construct a QString from a QByteArray
QString s = QString::fromLatin1(QByteArray("That really should work"))
-
Hi and welcome to devnet,
Why are you creating a QByteArray to create a QString in the first place ? Especially for that kind of constant.
QString butItDoesntWork(QStringLiteral("That really should work"));
but since it seems to be user facing text you should rather use:
QString butItDoesntWork(tr("That really should work"));
so it can be translated.
-
@mehdi the behavior is not weird, but rather intentional to prohibit implicit conversions.
As
QByteArray
is not unicode-aware, you have to specify the encoding when converting toQString
.The reason for the compile restriction is the
QT_RESTRICTED_CAST_FROM_ASCII
define, btw. -
Hi and thanks for the responses. The code I provided was just a minimal example highlighting the issue. The actual code is generated by openapi-generator (https://github.com/OpenAPITools/openapi-generator) (for the purpose of communicating with a REST api) and uses this type of conversion all over the place, e.g.:
QString OAICommentRequest_result_object::asJson () const { QJsonObject obj = this->asJsonObject(); QJsonDocument doc(obj); QByteArray bytes = doc.toJson(); // bytes is a QByteArray return QString(bytes); }
or
fullPath.append("?"); fullPath.append(QUrl::toPercentEncoding("start")) .append("=") .append(QUrl::toPercentEncoding(::API::toStringValue(start))); // QUrl::toPer... returns a QByteArray
or
QString msg; QString error_str = worker->error_str; QNetworkReply::NetworkError error_type = worker->error_type; if (worker->error_type == QNetworkReply::NoError) { msg = QString("Success! %1 bytes").arg(worker->response.length()); } else { msg = "Error: " + worker->error_str; } OAISample output(QString(worker->response)); // response is a QByteArray worker->deleteLater();
It's literally all over the place and everywhere and I would like to avoid having to patch the code-generator.
-
I see. Qt-Creator defines this in its pro file which is then included by my plugin. Thanks a lot!