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. Why doesn't QVariant work in this tree model's setData()?
Forum Updated to NodeBB v4.3 + New Features

Why doesn't QVariant work in this tree model's setData()?

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 3 Posters 1.8k Views 2 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.
  • S Offline
    S Offline
    SRaD
    wrote on last edited by SRaD
    #1

    I am using Qt 5.9 on linux. I have the Simple Tree Model Example running in my app, but now I'd like to add child nodes to the TreeView after the initial model has already been constructed. The only thing I've changed from the example is that the data is supplied by an external source rather than how it does it internally.

    I have a tree model that inherits QAbstractItemMode ...

    class MyTreeModel : public QAbstractItemModel { 
        ...
        bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
        ...
    }
    

    and my problem is calling the setData function like so ...

    QVector<QVariant> new_data;
    new_data << name << "";
    
    const QModelIndex parent = tree_model->index(0, 0);
    
    tree_model->insertRow(0, parent);
    
    tree_model->setData(tree_model->index(0, 0, parent), QVariant(new_data));
    

    I get the following error ...

    error: no matching function for call to ‘QVariant::QVariant(QVector<QVariant>&)’         
    tree_model->setData(tree_model->index(0, 0, parent), QVariant(new_data));
    

    If I change it to ...

    tree_model->setData(tree_model->index(0, 0, parent), QStringLiteral("test"));
    

    Then it all works ok but I don't understand why the QVariant doesn't work as in my method signature. I do it this way because eventually I want to add checkboxes to these items.

    Thanks,

    mrjjM 1 Reply Last reply
    0
    • S SRaD

      I am using Qt 5.9 on linux. I have the Simple Tree Model Example running in my app, but now I'd like to add child nodes to the TreeView after the initial model has already been constructed. The only thing I've changed from the example is that the data is supplied by an external source rather than how it does it internally.

      I have a tree model that inherits QAbstractItemMode ...

      class MyTreeModel : public QAbstractItemModel { 
          ...
          bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
          ...
      }
      

      and my problem is calling the setData function like so ...

      QVector<QVariant> new_data;
      new_data << name << "";
      
      const QModelIndex parent = tree_model->index(0, 0);
      
      tree_model->insertRow(0, parent);
      
      tree_model->setData(tree_model->index(0, 0, parent), QVariant(new_data));
      

      I get the following error ...

      error: no matching function for call to ‘QVariant::QVariant(QVector<QVariant>&)’         
      tree_model->setData(tree_model->index(0, 0, parent), QVariant(new_data));
      

      If I change it to ...

      tree_model->setData(tree_model->index(0, 0, parent), QStringLiteral("test"));
      

      Then it all works ok but I don't understand why the QVariant doesn't work as in my method signature. I do it this way because eventually I want to add checkboxes to these items.

      Thanks,

      mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @SRaD
      Hi
      Can you try QVariant::fromValue(new_data);

      • eventually I want to add checkboxes to these items.
        Just so you are aware, items can already be Checked
        (like listbox)
      Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
      {
          if (!index.isValid())
              return 0;
      
          Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
      
          if ( index.column() == 0 ) // or where ever you want it
              flags |= Qt::ItemIsUserCheckable;
      
          return flags;
      }
      
      1 Reply Last reply
      0
      • S Offline
        S Offline
        SRaD
        wrote on last edited by SRaD
        #3

        I was able to eventually get QStrings to appear in the TreeView, so now I've changed QString to a MyTreeItem, just like in the Simple Tree Model examples. And I'm having the same issue.

        QVector<QVariant> part_data;
        new_data << name << "";
        
        const QModelIndex parent = tree_model->index(0, 0);
        
        MyTreeItem *new_part = new MyTreeItem(new_data,
            QVariant::fromValue(parent));
            // parent);
        
        tree_model->insertRow(0, parent);
        
        tree_model->setData(tree_model->index(0, 0, parent),
            QVariant::fromValue(new_part));
            //new_part));
        

        I can see that the constructor to MyTreeItem doesn't match, but just now sure how this should be called.

        MyTreeItem(const QVector<QVariant> &data, MyTreeItem *parent = 0);
        

        Here's the error ...

        error: no matching function for call to ‘MyTreeItem::MyTreeItem(QVector<QVariant>&, const QModelIndex&)’ parent);
        

        Any help much appreciated.

        @mrjj thanks for the checkbox info, i tried it, but it didn't work, but you've given me something to look at.

        1 Reply Last reply
        0
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #4

          Hi
          something like
          TreeItem *new_part = new MyTreeItem(new_data part_data,nullptr);
          if the signature really is
          MyTreeItem(const QVector<QVariant> &data, MyTreeItem *parent = 0);
          then it wont take index but pointer to other MyTreeItem

          1 Reply Last reply
          0
          • S Offline
            S Offline
            SRaD
            wrote on last edited by
            #5

            Here's what I've got so far ...

            QVector<QVariant> new_data;
            new_data << name << "";
            
            const QModelIndex parent = tree_model->index(0, 0);
            
            MyTreeItem *new_item = new MyTreeItem(new_data, parent_item);
            
            tree_model->insertRow(0, parent);
            
            tree_model->setData(tree_model->index(0, 0, parent), QVariant(*new_item));
            

            But I still can't get past this error ...

            error: no matching function for call to ‘QVariant::QVariant(MyTreeItem&)’
            tree_model->setData(tree_model->index(0, 0, parent), QVariant(*new_item));    
                                                                                 ^
            
            mrjjM kshegunovK 2 Replies Last reply
            0
            • S SRaD

              Here's what I've got so far ...

              QVector<QVariant> new_data;
              new_data << name << "";
              
              const QModelIndex parent = tree_model->index(0, 0);
              
              MyTreeItem *new_item = new MyTreeItem(new_data, parent_item);
              
              tree_model->insertRow(0, parent);
              
              tree_model->setData(tree_model->index(0, 0, parent), QVariant(*new_item));
              

              But I still can't get past this error ...

              error: no matching function for call to ‘QVariant::QVariant(MyTreeItem&)’
              tree_model->setData(tree_model->index(0, 0, parent), QVariant(*new_item));    
                                                                                   ^
              
              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @SRaD
              But why do you set Data with a new item ???
              Are you trying to add extra data to the tree or trying to insert new items?

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SRaD
                wrote on last edited by SRaD
                #7

                I'm trying to add (insert) new child nodes to the tree? Am I using the wrong call?

                mrjjM 1 Reply Last reply
                0
                • S SRaD

                  I'm trying to add (insert) new child nodes to the tree? Am I using the wrong call?

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @SRaD
                  Hi
                  Well you tried to use QVector<QVariant> new_data;
                  but it takes
                  TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)

                  also, i had to surface rootItem to allow adding new items. Else only
                  void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
                  seems the only way.

                  anyway, i did

                  QList<QVariant> new_data;
                  new_data << "test" << "test2";
                  TreeItem *new_item = new TreeItem(new_data, model.rootItem);
                  model.rootItem->appendChild(new_item);
                  

                  alt text

                  1 Reply Last reply
                  0
                  • S SRaD

                    Here's what I've got so far ...

                    QVector<QVariant> new_data;
                    new_data << name << "";
                    
                    const QModelIndex parent = tree_model->index(0, 0);
                    
                    MyTreeItem *new_item = new MyTreeItem(new_data, parent_item);
                    
                    tree_model->insertRow(0, parent);
                    
                    tree_model->setData(tree_model->index(0, 0, parent), QVariant(*new_item));
                    

                    But I still can't get past this error ...

                    error: no matching function for call to ‘QVariant::QVariant(MyTreeItem&)’
                    tree_model->setData(tree_model->index(0, 0, parent), QVariant(*new_item));    
                                                                                         ^
                    
                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by
                    #9

                    @SRaD said in Why doesn't QVariant work in this tree model's setData()?:

                    tree_model->insertRow(0, parent);

                    This does nothing for the QAbstractItemModel, so if you haven't you need to implement it.

                    tree_model->setData(tree_model->index(0, 0, parent), QVariant(*new_item));

                    This should rather be:

                    int row = 0; // This is the index of the newly inserted row in the parent's table. It may differ from 0
                    for (int i = 0, size = new_data.size(); i < size; i++)
                        tree_model->setData(tree_model->index(row, i, parent), new_data[i]);
                    

                    Read and abide by the Qt Code of Conduct

                    mrjjM 1 Reply Last reply
                    0
                    • kshegunovK kshegunov

                      @SRaD said in Why doesn't QVariant work in this tree model's setData()?:

                      tree_model->insertRow(0, parent);

                      This does nothing for the QAbstractItemModel, so if you haven't you need to implement it.

                      tree_model->setData(tree_model->index(0, 0, parent), QVariant(*new_item));

                      This should rather be:

                      int row = 0; // This is the index of the newly inserted row in the parent's table. It may differ from 0
                      for (int i = 0, size = new_data.size(); i < size; i++)
                          tree_model->setData(tree_model->index(row, i, parent), new_data[i]);
                      
                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @kshegunov
                      Just to be clear
                      The poster should implement setData and in there use RootItem
                      to add new TreeItem in there?

                      kshegunovK 1 Reply Last reply
                      0
                      • mrjjM mrjj

                        @kshegunov
                        Just to be clear
                        The poster should implement setData and in there use RootItem
                        to add new TreeItem in there?

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #11

                        No, the OP should already have either a pointer or an ID to the parent object which is stored in the model index. Whenever [s]he needs to add a new node that's what should be used as a parent. The model index itself is just an identifier to the data. setData you implement to drumroll ... set the data. If the data is coming from outside the model, then you just notify the connected proxy models and/or view by emitting the relevant signals - that is you call beginInsertRows/beginInsertColumns an endInsertRows/endInsertColumns in the appropriate places.

                        Read and abide by the Qt Code of Conduct

                        mrjjM 1 Reply Last reply
                        1
                        • kshegunovK kshegunov

                          No, the OP should already have either a pointer or an ID to the parent object which is stored in the model index. Whenever [s]he needs to add a new node that's what should be used as a parent. The model index itself is just an identifier to the data. setData you implement to drumroll ... set the data. If the data is coming from outside the model, then you just notify the connected proxy models and/or view by emitting the relevant signals - that is you call beginInsertRows/beginInsertColumns an endInsertRows/endInsertColumns in the appropriate places.

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @kshegunov
                          Ok, but i don't see how the model will let you know the existing TreeItem you want to¨
                          append the new node to. (from outside)
                          Something like ?

                          const QModelIndex parent = model.index(0, 0);
                          TreeItem *itemParent = static_cast<TreeItem *>(parent.internalPointer());
                          
                          
                          kshegunovK 1 Reply Last reply
                          0
                          • mrjjM mrjj

                            @kshegunov
                            Ok, but i don't see how the model will let you know the existing TreeItem you want to¨
                            append the new node to. (from outside)
                            Something like ?

                            const QModelIndex parent = model.index(0, 0);
                            TreeItem *itemParent = static_cast<TreeItem *>(parent.internalPointer());
                            
                            
                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on last edited by
                            #13

                            @mrjj said in Why doesn't QVariant work in this tree model's setData()?:

                            Something like ?

                            Exactly like. However you already get the parent index from the Qt runtime, you don't create it with QAbstractItemModel::index.

                            Read and abide by the Qt Code of Conduct

                            1 Reply Last reply
                            1
                            • mrjjM Offline
                              mrjjM Offline
                              mrjj
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              ok super.
                              So basically the poster would have more fun using the model
                              from
                              https://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html
                              as it already implemented setData and support for altering the data.

                              1 Reply Last reply
                              0

                              • Login

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