diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 27ee9509e6b..d0e539632cb 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -70,12 +70,13 @@ class AddressTablePriv { public: QList cachedAddressTable; - AddressTableModel *parent; + AddressTableModel* const parent; + const bool pk_hash_only; - explicit AddressTablePriv(AddressTableModel *_parent): - parent(_parent) {} + explicit AddressTablePriv(AddressTableModel *_parent, bool pk_hash_only): + parent(_parent), pk_hash_only(pk_hash_only) {} - void refreshAddressTable(interfaces::Wallet& wallet, bool pk_hash_only = false) + void refreshAddressTable(interfaces::Wallet& wallet) { cachedAddressTable.clear(); { @@ -166,8 +167,7 @@ AddressTableModel::AddressTableModel(WalletModel *parent, bool pk_hash_only) : QAbstractTableModel(parent), walletModel(parent) { columns << tr("Label") << tr("Address"); - priv = new AddressTablePriv(this); - priv->refreshAddressTable(parent->wallet(), pk_hash_only); + priv = new AddressTablePriv(this, pk_hash_only); } AddressTableModel::~AddressTableModel() @@ -175,6 +175,11 @@ AddressTableModel::~AddressTableModel() delete priv; } +void AddressTableModel::preload() +{ + priv->refreshAddressTable(walletModel->wallet()); +} + int AddressTableModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 6cc14654ef4..83ceb4a3ae2 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -50,6 +50,8 @@ class AddressTableModel : public QAbstractTableModel static const QString Send; /**< Specifies send address */ static const QString Receive; /**< Specifies receive address */ + void preload(); + /** @name Methods overridden from QAbstractTableModel @{*/ int rowCount(const QModelIndex &parent) const override; diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 061513b58f5..e5139ad9a2a 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -23,11 +23,6 @@ RecentRequestsTableModel::RecentRequestsTableModel(WalletModel *parent) : QAbstractTableModel(parent), walletModel(parent) { - // Load entries from wallet - for (const std::string& request : parent->wallet().getAddressReceiveRequests()) { - addNewRequest(request); - } - /* These columns must match the indices in the ColumnIndex enumeration */ columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle(); @@ -36,6 +31,14 @@ RecentRequestsTableModel::RecentRequestsTableModel(WalletModel *parent) : RecentRequestsTableModel::~RecentRequestsTableModel() = default; +void RecentRequestsTableModel::preload() +{ + // Load entries from wallet + for (const std::string& request : walletModel->wallet().getAddressReceiveRequests()) { + addNewRequest(request); + } +} + int RecentRequestsTableModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index cf7cd24ce22..ae6d5e4f6fe 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -65,6 +65,8 @@ class RecentRequestsTableModel: public QAbstractTableModel NUMBER_OF_COLUMNS }; + void preload(); + /** @name Methods overridden from QAbstractTableModel @{*/ int rowCount(const QModelIndex &parent) const override; diff --git a/src/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp index a60e0647e33..4210cf13592 100644 --- a/src/qt/test/addressbooktests.cpp +++ b/src/qt/test/addressbooktests.cpp @@ -129,6 +129,7 @@ void TestAddAddressesToSendBook(interfaces::Node& node) WalletContext& context = *node.walletLoader().context(); AddWallet(context, wallet); WalletModel walletModel(interfaces::MakeWallet(context, wallet), clientModel, platformStyle.get()); + walletModel.preload(); RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt); EditAddressDialog editAddressDialog(EditAddressDialog::NewSendingAddress); editAddressDialog.setModel(walletModel.getAddressTableModel()); diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index 70b7f838728..df85babebe1 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -189,6 +189,7 @@ void TestGUI(interfaces::Node& node) WalletContext& context = *node.walletLoader().context(); AddWallet(context, wallet); WalletModel walletModel(interfaces::MakeWallet(context, wallet), clientModel, platformStyle.get()); + walletModel.preload(); RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt); sendCoinsDialog.setModel(&walletModel); transactionView.setModel(&walletModel); diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 4312b3cd24d..e6f4656877d 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -256,11 +256,7 @@ TransactionTableModel::TransactionTableModel(const PlatformStyle *_platformStyle fProcessingQueuedTransactions(false), platformStyle(_platformStyle) { - subscribeToCoreSignals(); - columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); - priv->refreshWallet(walletModel->wallet()); - connect(walletModel->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &TransactionTableModel::updateDisplayUnit); } @@ -270,6 +266,12 @@ TransactionTableModel::~TransactionTableModel() delete priv; } +void TransactionTableModel::preload() +{ + subscribeToCoreSignals(); + priv->refreshWallet(walletModel->wallet()); +} + /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */ void TransactionTableModel::updateAmountColumnTitle() { diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index f8576edd59c..5086c756336 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -76,6 +76,8 @@ class TransactionTableModel : public QAbstractTableModel RawDecorationRole, }; + void preload(); + int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index d27ddf1aba5..af884951651 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -125,21 +125,14 @@ WalletModel* WalletController::getOrCreateWallet(std::unique_ptrmoveToThread(thread()); - // setParent(parent) must be called in the thread which created the parent object. More details in #18948. - QMetaObject::invokeMethod(this, [wallet_model, this] { - wallet_model->setParent(this); + WalletModel* wallet_model; + // Instantiate model in GUI main thread. + QMetaObject::invokeMethod(this, [&] { + wallet_model = new WalletModel(std::move(wallet), m_client_model, m_platform_style, this); }, GUIUtil::blockingGUIThreadConnection()); + wallet_model->preload(); + m_wallets.push_back(wallet_model); // WalletModel::startPollBalance needs to be called in a thread managed by diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 1f6c90af4ad..0c3bce7f966 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -56,8 +56,6 @@ WalletModel::WalletModel(std::unique_ptr wallet, ClientModel addressTableModel = new AddressTableModel(this); transactionTableModel = new TransactionTableModel(platformStyle, this); recentRequestsTableModel = new RecentRequestsTableModel(this); - - subscribeToCoreSignals(); } WalletModel::~WalletModel() @@ -65,6 +63,14 @@ WalletModel::~WalletModel() unsubscribeFromCoreSignals(); } +void WalletModel::preload() +{ + addressTableModel->preload(); + transactionTableModel->preload(); + recentRequestsTableModel->preload(); + subscribeToCoreSignals(); +} + void WalletModel::startPollBalance() { // This timer will be fired repeatedly to update the balance diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 540fdaafe3c..d11a5d4bffb 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -77,6 +77,8 @@ class WalletModel : public QObject Unlocked // wallet->IsCrypted() && !wallet->IsLocked() }; + void preload(); + OptionsModel* getOptionsModel() const; AddressTableModel* getAddressTableModel() const; TransactionTableModel* getTransactionTableModel() const;