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. How to update QTableView when rows are inserted to it
Forum Updated to NodeBB v4.3 + New Features

How to update QTableView when rows are inserted to it

Scheduled Pinned Locked Moved Solved General and Desktop
model
23 Posts 4 Posters 16.2k Views 3 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.
  • R Offline
    R Offline
    Ratzz
    wrote on 27 Apr 2016, 10:54 last edited by Ratzz
    #1

    I am trying to insert rows to QTableView set to QAbstractTableModel using drag of item from another TreeView on to the QTableView.

       //Constructor of Tableview 
        model= new TableModel();
        TableRowCount=0;
        model->rCount=TableRowCount;
        this->setModel(model);
        setAcceptDrops(true);
    
       //dropEvent
            QTreeView * view= dynamic_cast<QTreeView*>(event->source());
            QModelIndexList list= view->selectionModel()->selectedIndexes();
            for(int i=0;i<list.count();i++)
            {
                QModelIndex dragIndex=list.at(i);
                if(dragIndex.parent().isValid())
                {
                    TableRowCount++;
                   model->rCount=TableRowCount;
                    
                    TableStruct Tstruct;
                    Tstruct.DeviceName=dragIndex.parent().data(Qt::DisplayRole).toString();
                    Tstruct.MessageName=dragIndex.parent().data(Qt::DisplayRole).toString();
                    Tstruct.TagName=dragIndex.data(Qt::DisplayRole).toString();
                    Tstruct.Value=QString::number(0);
                    Tstruct.Units=QString::number(0);
                    
                    TableStrList.append(Tstruct);
                    model->TableList=TableStrList;
                    model->insertRows(TableRowCount,1,dragIndex);
    

    And model looks like

    QVariant Model::data(const QModelIndex &index, int role) const
    {
        if (role == Qt::DisplayRole)
        {
            int column = index.column();
            int row  = index.row();
    
            switch(column)
            {
            case 0:
                return   TableList.at(row).DeviceName;
                break;
            case 1:
                return   TableList.at(row).MessageName;
                break;
            case 2:
                return   TableList.at(row).TagName;
                break;
            case 3:
                return   TableList.at(row).Value;
                break;
            case 4:
                return   TableList.at(row).Units;
                break;
            }
        }
    
        if(role == Qt::TextAlignmentRole)
        {
            return Qt::AlignCenter;
        }
    
        return QVariant();
    }
    
    int Model::rowCount(const QModelIndex & /*parent*/) const
    {
        qDebug()<< "row count "<<rCount;
        return rCount;
    }
    
    int Model::columnCount(const QModelIndex & /*parent*/) const
    {
        return 5;
    }
    
    QVariant Model::headerData( int section,Qt::Orientation orientation,int role ) const
    {
        if((role == Qt::DisplayRole || role ==Qt::ToolTipRole))
        {
            if(orientation == Qt::Horizontal)
            {
                switch( section )
                {
                case 0: return( QString( "Device Name" ) );
                case 1: return( QString( "Message Name" ) );
                case 2: return( QString( "Tag Name" ) );
                case 3: return( QString( "Value" ) );
                case 4:return (QString("units"));
                }
            }
        }
        return QAbstractItemModel::headerData( section, orientation, role );
    }
    
    bool Model::insertRows(int row, int count, const QModelIndex &parent)
    {
        beginInsertRows(parent,row,row+count-1);
        endInsertRows();
        return true;
    }
    

    Row count in the model is updated properly on drop of item but the view is not getting updated. How will the will know that the new rows re inserted??

    --Alles ist gut.

    K 1 Reply Last reply 27 Apr 2016, 11:01
    0
    • R Ratzz
      27 Apr 2016, 10:54

      I am trying to insert rows to QTableView set to QAbstractTableModel using drag of item from another TreeView on to the QTableView.

         //Constructor of Tableview 
          model= new TableModel();
          TableRowCount=0;
          model->rCount=TableRowCount;
          this->setModel(model);
          setAcceptDrops(true);
      
         //dropEvent
              QTreeView * view= dynamic_cast<QTreeView*>(event->source());
              QModelIndexList list= view->selectionModel()->selectedIndexes();
              for(int i=0;i<list.count();i++)
              {
                  QModelIndex dragIndex=list.at(i);
                  if(dragIndex.parent().isValid())
                  {
                      TableRowCount++;
                     model->rCount=TableRowCount;
                      
                      TableStruct Tstruct;
                      Tstruct.DeviceName=dragIndex.parent().data(Qt::DisplayRole).toString();
                      Tstruct.MessageName=dragIndex.parent().data(Qt::DisplayRole).toString();
                      Tstruct.TagName=dragIndex.data(Qt::DisplayRole).toString();
                      Tstruct.Value=QString::number(0);
                      Tstruct.Units=QString::number(0);
                      
                      TableStrList.append(Tstruct);
                      model->TableList=TableStrList;
                      model->insertRows(TableRowCount,1,dragIndex);
      

      And model looks like

      QVariant Model::data(const QModelIndex &index, int role) const
      {
          if (role == Qt::DisplayRole)
          {
              int column = index.column();
              int row  = index.row();
      
              switch(column)
              {
              case 0:
                  return   TableList.at(row).DeviceName;
                  break;
              case 1:
                  return   TableList.at(row).MessageName;
                  break;
              case 2:
                  return   TableList.at(row).TagName;
                  break;
              case 3:
                  return   TableList.at(row).Value;
                  break;
              case 4:
                  return   TableList.at(row).Units;
                  break;
              }
          }
      
          if(role == Qt::TextAlignmentRole)
          {
              return Qt::AlignCenter;
          }
      
          return QVariant();
      }
      
      int Model::rowCount(const QModelIndex & /*parent*/) const
      {
          qDebug()<< "row count "<<rCount;
          return rCount;
      }
      
      int Model::columnCount(const QModelIndex & /*parent*/) const
      {
          return 5;
      }
      
      QVariant Model::headerData( int section,Qt::Orientation orientation,int role ) const
      {
          if((role == Qt::DisplayRole || role ==Qt::ToolTipRole))
          {
              if(orientation == Qt::Horizontal)
              {
                  switch( section )
                  {
                  case 0: return( QString( "Device Name" ) );
                  case 1: return( QString( "Message Name" ) );
                  case 2: return( QString( "Tag Name" ) );
                  case 3: return( QString( "Value" ) );
                  case 4:return (QString("units"));
                  }
              }
          }
          return QAbstractItemModel::headerData( section, orientation, role );
      }
      
      bool Model::insertRows(int row, int count, const QModelIndex &parent)
      {
          beginInsertRows(parent,row,row+count-1);
          endInsertRows();
          return true;
      }
      

      Row count in the model is updated properly on drop of item but the view is not getting updated. How will the will know that the new rows re inserted??

      K Offline
      K Offline
      kshegunov
      Moderators
      wrote on 27 Apr 2016, 11:01 last edited by kshegunov
      #2

      @Ratzz
      Hello,
      I believe you should emit the QAbstractItemModel::rowsInserted signal from the model (after your call to endInsertRows), so the view knows to adapt to the changes.

      Kind regards.


      PS:

      switch(column)
      {
          case 0:
      

      You should really use (possibly unnamed) enums for that kind of switch constructs.

      Read and abide by the Qt Code of Conduct

      R 1 Reply Last reply 27 Apr 2016, 11:10
      1
      • K kshegunov
        27 Apr 2016, 11:01

        @Ratzz
        Hello,
        I believe you should emit the QAbstractItemModel::rowsInserted signal from the model (after your call to endInsertRows), so the view knows to adapt to the changes.

        Kind regards.


        PS:

        switch(column)
        {
            case 0:
        

        You should really use (possibly unnamed) enums for that kind of switch constructs.

        R Offline
        R Offline
        Ratzz
        wrote on 27 Apr 2016, 11:10 last edited by
        #3

        @kshegunov
        Thanks for the reply.
        But doc says

        Note: This is a private signal. It can be used in signal connections but cannot be emitted by the user.
        

        What does this mean?

        --Alles ist gut.

        K 1 Reply Last reply 27 Apr 2016, 11:14
        0
        • R Ratzz
          27 Apr 2016, 11:10

          @kshegunov
          Thanks for the reply.
          But doc says

          Note: This is a private signal. It can be used in signal connections but cannot be emitted by the user.
          

          What does this mean?

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 27 Apr 2016, 11:14 last edited by
          #4

          @Ratzz
          It means it can't be emitted from the user of the class. Since you're not the user of the class, but rather the designer, I think you should just ignore the note. ;)

          Read and abide by the Qt Code of Conduct

          R 1 Reply Last reply 27 Apr 2016, 11:23
          0
          • K kshegunov
            27 Apr 2016, 11:14

            @Ratzz
            It means it can't be emitted from the user of the class. Since you're not the user of the class, but rather the designer, I think you should just ignore the note. ;)

            R Offline
            R Offline
            Ratzz
            wrote on 27 Apr 2016, 11:23 last edited by
            #5

            @kshegunov
            It asks for QPrivateSignal http://postimg.org/image/bjpuc4bep/

            --Alles ist gut.

            K 2 Replies Last reply 27 Apr 2016, 11:26
            0
            • R Ratzz
              27 Apr 2016, 11:23

              @kshegunov
              It asks for QPrivateSignal http://postimg.org/image/bjpuc4bep/

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 27 Apr 2016, 11:26 last edited by
              #6

              @Ratzz
              Oops, sorry. The note above the one you cited states:

              It can only be emitted by the QAbstractItemModel implementation, and cannot be explicitly emitted in subclass code.
              

              Hm, in that case I'm not sure ... The documentation is somewhat cryptic whether endInsertRows() actually emits the aforementioned signal ...

              Read and abide by the Qt Code of Conduct

              R 1 Reply Last reply 27 Apr 2016, 11:31
              0
              • R Ratzz
                27 Apr 2016, 11:23

                @kshegunov
                It asks for QPrivateSignal http://postimg.org/image/bjpuc4bep/

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 27 Apr 2016, 11:31 last edited by
                #7

                @Ratzz
                Possibly, you could try implementing QAbstractItemModel::dropMimeData without intercepting the drop event?

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                2
                • K kshegunov
                  27 Apr 2016, 11:26

                  @Ratzz
                  Oops, sorry. The note above the one you cited states:

                  It can only be emitted by the QAbstractItemModel implementation, and cannot be explicitly emitted in subclass code.
                  

                  Hm, in that case I'm not sure ... The documentation is somewhat cryptic whether endInsertRows() actually emits the aforementioned signal ...

                  R Offline
                  R Offline
                  Ratzz
                  wrote on 27 Apr 2016, 11:31 last edited by Ratzz
                  #8

                  @kshegunov
                  The beginInsertRows doc http://doc.qt.io/qt-4.8/qabstractitemmodel.html#beginInsertRows says

                  Note: This function emits the rowsAboutToBeInserted() signal which connected views (or proxies) must handle before the data is inserted. Otherwise, the views may end up in an invalid state.
                  

                  Will it help?

                  --Alles ist gut.

                  K 1 Reply Last reply 27 Apr 2016, 11:34
                  0
                  • R Ratzz
                    27 Apr 2016, 11:31

                    @kshegunov
                    The beginInsertRows doc http://doc.qt.io/qt-4.8/qabstractitemmodel.html#beginInsertRows says

                    Note: This function emits the rowsAboutToBeInserted() signal which connected views (or proxies) must handle before the data is inserted. Otherwise, the views may end up in an invalid state.
                    

                    Will it help?

                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 27 Apr 2016, 11:34 last edited by kshegunov
                    #9

                    @Ratzz
                    Yes, I saw that, but this is to notify the view insertions will be happening. The question is whether endInsertRows() emits rowsInserted() thus telling the view the insertion has finished and it can actually update itself. Unfortunately, the documentation doesn't state anything specific about endInsertRows(), unless I completely missed it ...

                    PS. I just noticed something in your code:

                    QTreeView * view= dynamic_cast<QTreeView*>(event->source());
                    

                    Is this a typo?

                    Read and abide by the Qt Code of Conduct

                    R 1 Reply Last reply 27 Apr 2016, 11:56
                    1
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 27 Apr 2016, 11:47 last edited by
                      #10

                      Hi,

                      The documentation doesn't specify but the implementation does emit rowsInserted. However in this case insertRows doesn't do anything so I wonder if there isn't a caching mechanism that avoids to update the view if in fact nothing has changed.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      R K 2 Replies Last reply 27 Apr 2016, 11:57
                      1
                      • K kshegunov
                        27 Apr 2016, 11:34

                        @Ratzz
                        Yes, I saw that, but this is to notify the view insertions will be happening. The question is whether endInsertRows() emits rowsInserted() thus telling the view the insertion has finished and it can actually update itself. Unfortunately, the documentation doesn't state anything specific about endInsertRows(), unless I completely missed it ...

                        PS. I just noticed something in your code:

                        QTreeView * view= dynamic_cast<QTreeView*>(event->source());
                        

                        Is this a typo?

                        R Offline
                        R Offline
                        Ratzz
                        wrote on 27 Apr 2016, 11:56 last edited by
                        #11

                        @kshegunov said:

                        Is this a typo?

                        I drag the items from another QTreeView .The cast is for that..
                        Did you mean that?

                        --Alles ist gut.

                        1 Reply Last reply
                        0
                        • SGaistS SGaist
                          27 Apr 2016, 11:47

                          Hi,

                          The documentation doesn't specify but the implementation does emit rowsInserted. However in this case insertRows doesn't do anything so I wonder if there isn't a caching mechanism that avoids to update the view if in fact nothing has changed.

                          R Offline
                          R Offline
                          Ratzz
                          wrote on 27 Apr 2016, 11:57 last edited by
                          #12

                          @SGaist said:
                          Thanks for the reply.
                          So there is no way with insertRows?

                          --Alles ist gut.

                          1 Reply Last reply
                          0
                          • SGaistS SGaist
                            27 Apr 2016, 11:47

                            Hi,

                            The documentation doesn't specify but the implementation does emit rowsInserted. However in this case insertRows doesn't do anything so I wonder if there isn't a caching mechanism that avoids to update the view if in fact nothing has changed.

                            K Offline
                            K Offline
                            kshegunov
                            Moderators
                            wrote on 27 Apr 2016, 11:57 last edited by kshegunov
                            #13

                            @SGaist

                            However in this case insertRows doesn't do anything so I wonder if there isn't a caching mechanism that avoids to update the view if in fact nothing has changed.

                            After a quick look (without pretense to be complete) I couldn't clearly see any such caching done.
                            Here's what I peeked at (for Qt 5.6):
                            http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/itemmodels/qabstractitemmodel.cpp#n2601
                            http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/itemmodels/qabstractitemmodel.cpp#n582

                            @Ratzz

                            I drag the items from another QTreeView .The cast is for that..
                            Did you mean that?

                            Indeed I did. Have you considered handling the drag/drop events through the ordinary mechanism? Serializing on drag, then deserializing the mime data on drop?

                            Read and abide by the Qt Code of Conduct

                            R 1 Reply Last reply 27 Apr 2016, 12:03
                            1
                            • K kshegunov
                              27 Apr 2016, 11:57

                              @SGaist

                              However in this case insertRows doesn't do anything so I wonder if there isn't a caching mechanism that avoids to update the view if in fact nothing has changed.

                              After a quick look (without pretense to be complete) I couldn't clearly see any such caching done.
                              Here's what I peeked at (for Qt 5.6):
                              http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/itemmodels/qabstractitemmodel.cpp#n2601
                              http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/itemmodels/qabstractitemmodel.cpp#n582

                              @Ratzz

                              I drag the items from another QTreeView .The cast is for that..
                              Did you mean that?

                              Indeed I did. Have you considered handling the drag/drop events through the ordinary mechanism? Serializing on drag, then deserializing the mime data on drop?

                              R Offline
                              R Offline
                              Ratzz
                              wrote on 27 Apr 2016, 12:03 last edited by
                              #14

                              @kshegunov said:

                              Serializing on drag, then deserializing the mime data on drop?

                              No i have not considered this part.

                              --Alles ist gut.

                              K 1 Reply Last reply 27 Apr 2016, 12:08
                              0
                              • SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on 27 Apr 2016, 12:06 last edited by
                                #15

                                @kshegunov : I mean't view side caching.

                                @Ratzz currently you are not inserting anything through it. Like @kshegunov suggested, implement the drag and drop through the mechanism provided for model/view classes. It's described here

                                Interested in AI ? www.idiap.ch
                                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                R 1 Reply Last reply 27 Apr 2016, 12:08
                                0
                                • SGaistS SGaist
                                  27 Apr 2016, 12:06

                                  @kshegunov : I mean't view side caching.

                                  @Ratzz currently you are not inserting anything through it. Like @kshegunov suggested, implement the drag and drop through the mechanism provided for model/view classes. It's described here

                                  R Offline
                                  R Offline
                                  Ratzz
                                  wrote on 27 Apr 2016, 12:08 last edited by
                                  #16

                                  @SGaist
                                  I will try to implement through (link you provided ) this.

                                  --Alles ist gut.

                                  1 Reply Last reply
                                  0
                                  • R Ratzz
                                    27 Apr 2016, 12:03

                                    @kshegunov said:

                                    Serializing on drag, then deserializing the mime data on drop?

                                    No i have not considered this part.

                                    K Offline
                                    K Offline
                                    kshegunov
                                    Moderators
                                    wrote on 27 Apr 2016, 12:08 last edited by kshegunov
                                    #17

                                    @Ratzz

                                    No i have not considered this part.

                                    Then I suggest you try it out. It may prove to be easier and better behaved than pulling the records directly from the tree widget. As for your current implementation, I'm at a loss why it doesn't work. Maybe the tree view is losing the selection when dragging and the selection model returns no records?

                                    @SGaist

                                    I mean't view side caching.

                                    I see, well I didn't look at the view (obviously) but I suppose it's possible.

                                    Read and abide by the Qt Code of Conduct

                                    R 1 Reply Last reply 27 Apr 2016, 12:33
                                    1
                                    • mrjjM Offline
                                      mrjjM Offline
                                      mrjj
                                      Lifetime Qt Champion
                                      wrote on 27 Apr 2016, 12:30 last edited by
                                      #18

                                      Hi
                                      I am still wondering. Sorry.
                                      Lets say If I dont have drag&drop.

                                      I simply append to my internal list used in model.

                                      How will I tell the view(s) that?

                                      I though dataChanged would do it but not even begin/endInsertRow
                                      does it.

                                      Thanks

                                      K 1 Reply Last reply 27 Apr 2016, 15:31
                                      0
                                      • K kshegunov
                                        27 Apr 2016, 12:08

                                        @Ratzz

                                        No i have not considered this part.

                                        Then I suggest you try it out. It may prove to be easier and better behaved than pulling the records directly from the tree widget. As for your current implementation, I'm at a loss why it doesn't work. Maybe the tree view is losing the selection when dragging and the selection model returns no records?

                                        @SGaist

                                        I mean't view side caching.

                                        I see, well I didn't look at the view (obviously) but I suppose it's possible.

                                        R Offline
                                        R Offline
                                        Ratzz
                                        wrote on 27 Apr 2016, 12:33 last edited by
                                        #19

                                        @kshegunov said:

                                        Maybe the tree view is losing the selection when dragging and the selection model returns no records?

                                        I don't think so because the rowCount is getting updated as and when the new drop takes place.

                                        --Alles ist gut.

                                        1 Reply Last reply
                                        0
                                        • mrjjM mrjj
                                          27 Apr 2016, 12:30

                                          Hi
                                          I am still wondering. Sorry.
                                          Lets say If I dont have drag&drop.

                                          I simply append to my internal list used in model.

                                          How will I tell the view(s) that?

                                          I though dataChanged would do it but not even begin/endInsertRow
                                          does it.

                                          Thanks

                                          K Offline
                                          K Offline
                                          kshegunov
                                          Moderators
                                          wrote on 27 Apr 2016, 15:31 last edited by
                                          #20

                                          @mrjj

                                          I simply append to my internal list used in model.

                                          I'm by no means an expert, but possibly calling submit() (I don't know if it works I'm just guessing)?

                                          Read and abide by the Qt Code of Conduct

                                          1 Reply Last reply
                                          0

                                          2/23

                                          27 Apr 2016, 11:01

                                          topic:navigator.unread, 21
                                          • Login

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