QVariant::load: unable to load type 1038 and also QVariant::load: unknown user type with name BitcoinUnits::Unit.
-
Hello, I debug a code of Bitcoin-ABC, after compilation and run got this
./src/qt/bitcoin-qt
QVariant::load: unknown user type with name BitcoinUnits::Unit.debuggind shown legacy.allKeys() causes error:
QSettings // below picks up settings file location based on orgname,appname legacy(legacyOrg, legacyAppName), // default c'tor below picks up settings file location based on // QApplication::applicationName(), et al -- which was already set // in main() abc; const QStringList legacyKeys(legacy.allKeys());
full code of bitcoin.cpp and that line is 553:
https://github.com/Bitcoin-ABC/bitcoin-abc/blob/7d99a4ee502feed3adc8c9ca84ac3a18c2822f0e/src/qt/bitcoin.cpp#L553I tried a lot to register MetaType as documentation of QVariant Qt5 says https://doc.qt.io/qt-5/qvariant.html (qt5 is used in bitcoin-abc). But did not succeded, added compilation error or runtime warnings to comment:
//Q_DECLARE_METATYPE(BitcoinUnits) //error: use of deleted function ‘BitcoinUnits::BitcoinUnits(const BitcoinUnits&)’ //Q_DECLARE_METATYPE(BitcoinUnits *) //QVariant::load: unknown user type with name BitcoinUnits::Unit. //Q_DECLARE_METATYPE(BitcoinUnits::Unit *) //QVariant::load: unknown user type with name BitcoinUnits::Unit. Q_DECLARE_METATYPE(BitcoinUnits::Unit) //QVariant::load: unknown user type with name BitcoinUnits::Unit. //Q_DECLARE_METATYPE(QList::BitcoinUnits::Unit *) //error: template argument 1 is invalid //Q_DECLARE_METATYPE(BitcoinUnits::BitcoinUnits) //error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct QMetaTypeId’ //qRegisterMetaTypeStreamOperators<BitcoinUnits::BitcoinUnits>(); //error: no matching function for call to ‘qRegisterMetaTypeStreamOperators<BitcoinUnits::__ct >()’ //qRegisterMetaType<BitcoinUnits::Unit>("Unit"); //QVariant::load: unable to load type 1038. //qRegisterMetaType<QList<BitcoinUnits::Unit>>("BitcoinUnits::Unit"); //QVariant::load: unable to load type 1038. //qRegisterMetaType<QList<BitcoinUnits::Unit>>("BitcoinUnits::Unit::base"); //QVariant::load: unknown user type with name BitcoinUnits::Unit. qRegisterMetaType<BitcoinUnits::Unit>("BitcoinUnits::Unit"); //QVariant::load: unable to load type 1038. //qRegisterMetaType<QList>("BitcoinUnits::Unit"); //error: no matching function for call to
I know also there is a very curly way to run Qt Application in that code, that developers placed comment here:
https://github.com/Bitcoin-ABC/bitcoin-abc/blob/7d99a4ee502feed3adc8c9ca84ac3a18c2822f0e/src/qt/bitcoin.cpp#L327void BitcoinApplication::startThread() { if (coreThread) { return; } coreThread = new QThread(this); BitcoinABC *executor = new BitcoinABC(node()); executor->moveToThread(coreThread); /* communication to and from thread */ connect(executor, &BitcoinABC::initializeResult, this, &BitcoinApplication::initializeResult); connect(executor, &BitcoinABC::shutdownResult, this, &BitcoinApplication::shutdownResult); connect(executor, &BitcoinABC::runawayException, this, &BitcoinApplication::handleRunawayException); // Note on how Qt works: it tries to directly invoke methods if the signal // is emitted on the same thread that the target object 'lives' on. // But if the target object 'lives' on another thread (executor here does) // the SLOT will be invoked asynchronously at a later time in the thread // of the target object. So.. we pass a pointer around. If you pass // a reference around (even if it's non-const) you'll get Qt generating // code to copy-construct the parameter in question (Q_DECLARE_METATYPE // and qRegisterMetaType generate this code). For the Config class, // which is noncopyable, we can't do this. So.. we have to pass // pointers to Config around. Make sure Config &/Config * isn't a // temporary (eg it lives somewhere aside from the stack) or this will // crash because initialize() gets executed in another thread at some // unspecified time (after) requestedInitialize() is emitted! connect(this, &BitcoinApplication::requestedInitialize, executor, &BitcoinABC::initialize); connect(this, &BitcoinApplication::requestedShutdown, executor, &BitcoinABC::shutdown); /* make sure executor object is deleted in its own thread */ connect(coreThread, &QThread::finished, executor, &QObject::deleteLater); coreThread->start();
So, i think register of metatype might need pointers instead of copying type?
I do not know exactly,
- how does BitcoinUnits::Unit become a member of variable 'legacy' type QSettings? I did not found that in code in bitcoinunits.cpp
- How to register BitcoinUnits::Unit as MetaType in Qt5?
I also posted an issue to that repository, but wish to solve that issue today and hope it is not so difficult. Could you give some advise? What to try to provide to Q_DECLARE_METATYPE and qRegisterMetaType ? Maybe i need qRegisterMetaTypeStreamOperators or something?
-
C Christian Ehrlicher moved this topic from The Lounge on
-
I just figured out that our app name is Bitcoin-ABC, but we try to copy QSettings from app Bitcoin or Bitcoin-QT, but actually those apps may absent in our system:
static const QString legacyAppName("Bitcoin-Qt"), legacyOrg("Bitcoin"); QSettings legacy(legacyOrg, legacyAppName), abc; const QStringList legacyKeys(legacy.allKeys()); // We only migrate settings if we have Core settings but no Bitcoin-ABC // settings if (!legacyKeys.isEmpty() && abc.allKeys().isEmpty()) { for (const QString &key : legacyKeys) { // now, copy settings over abc.setValue(key, legacy.value(key)); } }
so this code is seeking app Bitcoin or Bitcoin-QT and copy settings. And if there is no such apps this code produces warning:
QVariant::load: unknown user type with name BitcoinUnits::Unit.So, first we need to check if apps Bitcoin or Bitcoin-Qt actually exist. Is it possible to check existence of apps in QT5?
I think this hack of copying settings from other apps is too self-confident action from Bitcoin-ABC developers, but if they want such, need to help them to check if such apps really exist. This hack might be related to old name of Bitcoin-ABC app, so in some commit number they changed app name and now try to copy settings from their app with old name. Please, is qt5 support such functionality of copying settings from other apps and how to check existence of apps Bitcoin, Bitcoin-Qt in this case?