QStandardItem setData does not work
-
I need to associate one of 2 some custom data structs with each QStandardItem in a tree. Each item represents a leaf in QTreeView's QStandardItemModel, and I do not want to subclass the QStandardItem to add this extra data as I should be able so save it in item directly with:
void setData(const QVariant &value, int role = Qt::UserRole + 1)
Normally I would use a simple QVariant to store something like a simple string or something else in the QStandardItem, however this time since I need to associate one of the 2 structs below as alternative types (and neither of these 2 structs has a default constructor as required by a QVariant), I needed to use introduce a std::variant with a default std::monotype as the default variant type as a QVariant wrapper. QVariant has a converter from this std::variant QVariant fromStdVariant(const std::variant<Types...> &value) to a QVariant. Unfortunately after retrieving the value later by calling item->data().value<PortVariant>(); always results in a std::monotype value from the variant.
const auto& portVariant = item->data().value<PortVariant>();
I set the data this way
// searchable portID name - used for coloring PortVariant portVariant = port; portItem->setData(QVariant::fromStdVariant(portVariant));
and I retrieve it later this way, however it always contains the default std::monotype
const auto& portVariant = item->data().value<PortVariant>();
using PortVariant = std::variant<std::monostate, RxMessagePort, TxMessagePort>;
The RxMessagePort and TxMesssgePort are similar structs with explicit constructors
using RxMessagePort = struct RxMessagePort { /** * Explicit constructor. * * @param name [in] RxMessagePort name. * @param portId [in] RxMessagePort identifier. * @param network [in] A, B or Both network identifier. * @param rxSapUdpPort [in] receive SapUdpPort. */ constexpr explicit RxMessagePort( std::string name, const unsigned portId, const A664Network network, RxSapUdpPort rxSapUdpPort) : mName{ std::move(name) } , mPortId{ portId } , mNetwork{ network } , mRxSapUdpPort{ std::move(rxSapUdpPort) } {} std::string mName; unsigned mPortId; A664Network mNetwork; RxSapUdpPort mRxSapUdpPort; };
and
using TxMessagePort = struct TxMessagePort { /** * SapUdp TxMessagePort. * * @param name [in] Port name. * @param portId [in] Port ID. * @param txSapUdpPort [in] txSapUdpPort. */ constexpr explicit TxMessagePort( std::string name, const unsigned portId, TxSapUdpPort txSapUdpPort) : mName{ std::move(name) } , mPortId{ portId } , mTxSapUdpPort{ std::move(txSapUdpPort) } {} std::string mName; unsigned mPortId; TxSapUdpPort mTxSapUdpPort; };
-
@johnco3
I'm afraid I know nothing aboutstd::variant
, but a couple of observations.Your
setData()
isvoid
.QStandardItemModel
's isbool
. Have you checked the return result when you call that, you never know if it might be barfing?Your
setData()
defaults toQt::UserRole + 1
. How does youritem->data().value<PortVariant>()
pass that role to fetch?setData()
copies its argument. I assume the equivalent code to test would be something like:PortVariant portVariant = port; QVariant v = QVariant::fromStdVariant(portVariant); QVariant v2 = v1; const auto& portVariant = v2.value<PortVariant>();
How does that come out? You might also call
QVariant::canConvert<>()
to check, including on youritem->data()
.I assume all the various component types in your
struct
s are serializable toQVariant
without further registration.