Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QStandardItem setData does not work
Forum Updated to NodeBB v4.3 + New Features

QStandardItem setData does not work

Scheduled Pinned Locked Moved Unsolved General and Desktop
qvariantqstandarditem
2 Posts 2 Posters 367 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    johnco3
    wrote on 26 Apr 2023, 01:57 last edited by johnco3
    #1

    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;
    };
    
    J 1 Reply Last reply 26 Apr 2023, 07:40
    0
    • J johnco3
      26 Apr 2023, 01:57

      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;
      };
      
      J Offline
      J Offline
      JonB
      wrote on 26 Apr 2023, 07:40 last edited by
      #2

      @johnco3
      I'm afraid I know nothing about std::variant, but a couple of observations.

      Your setData() is void. QStandardItemModel's is bool. Have you checked the return result when you call that, you never know if it might be barfing?

      Your setData() defaults to Qt::UserRole + 1. How does your item->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 your item->data().

      I assume all the various component types in your structs are serializable to QVariant without further registration.

      1 Reply Last reply
      0

      1/2

      26 Apr 2023, 01:57

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved