Results 1 to 14 of 14

Thread: Insert rows...

  1. #1
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Insert rows...

    Hi,

    Can anybody please explain why the following keeps adding rows to my table view :

    Qt Code:
    1. void DAStaticModel::setCanData( int nAmount )
    2. {
    3. if( nAmount <= 0 )
    4. return;
    5.  
    6. beginInsertRows(QModelIndex(), 0, 0 );
    7. endInsertRows();
    8.  
    9. }
    10.  
    11. QVariant DAStaticModel::data( const QModelIndex& index, int role) const
    12. {
    13. QVariant data;
    14.  
    15. if (!index.isValid())
    16. return QVariant();
    17.  
    18. if(index.column() > 3 )
    19. {
    20. return QVariant();
    21. }
    22.  
    23. if( role == Qt::DisplayRole )
    24. {
    25.  
    26. QString strId = "";
    27. static QMapIterator<QString, QObject*>i(*theApp->GetCanMap());
    28. static CanMessages* pMess = NULL;
    29. if( i.hasNext() && index.column() == 0 )
    30. {
    31. i.next();
    32. pMess = (CanMessages*)i.value();
    33. strId = i.key();
    34. }
    35. else
    36. if( !i.hasNext() ) // need to reset to begining of the list
    37. {
    38. i.toFront();
    39. }
    40.  
    41. switch( index.column() )
    42. {
    43. case 0:
    44. data = strId;
    45. break;
    46. case 2:
    47. {
    48. if( pMess )
    49. {
    50. data = pMess->m_strData;
    51. }
    52. }
    53. break;
    54. case 1:
    55. {
    56. if( pMess )
    57. {
    58. data = pMess->m_strTime;
    59. }
    60. }
    61. break;
    62. case 3:
    63. {
    64. if( pMess )
    65. {
    66. QString strCount;
    67. strCount.sprintf( "%d", pMess->m_nCount );
    68. data = strCount;
    69. }
    70. }
    71. break;
    72. }
    73. }
    74.  
    75. return data;
    76. }
    77.  
    78. int DAStaticModel::rowCount( const QModelIndex& parent ) const
    79. {
    80. return theApp->GetCanMap()->size();
    81. }
    To copy to clipboard, switch view to plain text mode 

    If I don't call the beginInsertRows / endInsertRows nothing is displayed in my table view.

    Please note that the rowCount is always one...

    Thanks,
    Steve

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Insert rows...

    There is something wrong with your model. Could you attach the complete model code? You can skip the contents of data(), we already have it here. What does GetCanMap() return? A copy or a reference?

  3. #3
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Insert rows...

    Hi,

    This is the model :

    Qt Code:
    1. DAStaticModel::DAStaticModel(QObject *parent)
    2. {
    3. }
    4.  
    5.  
    6. DAStaticModel::~DAStaticModel()
    7. {
    8.  
    9. }
    10.  
    11.  
    12. int DAStaticModel::rowCount( const QModelIndex& parent ) const
    13. {
    14. return theApp->GetCanMap()->size();
    15. }
    16.  
    17. int DAStaticModel::columnCount(const QModelIndex &) const
    18. {
    19. return 4;
    20. }
    21.  
    22. void DAStaticModel::SetHeaders( QStringList& strHeaders )
    23. {
    24. strHeaderList = strHeaders;
    25. }
    26.  
    27. QVariant DAStaticModel::headerData(int section, Qt::Orientation orientation, int role) const
    28. {
    29. if( role != Qt::DisplayRole )
    30. return QVariant();
    31.  
    32. if (orientation == Qt::Horizontal)
    33. return strHeaderList[section];
    34.  
    35. return QVariant();
    36. }
    37.  
    38.  
    39. void DAStaticModel::setCanData( int nAmount )
    40. {
    41. if( nAmount <= 0 )
    42. return;
    43.  
    44. beginInsertRows(QModelIndex(), 0, 0);//theApp->GetCanMap()->size() ); // insert nAmount of rows
    45.  
    46.  
    47. endInsertRows();
    48.  
    49. }
    To copy to clipboard, switch view to plain text mode 

    The GetCanMap :

    Qt Code:
    1. QMap<QString, QObject*>* GetCanMap() { return &m_oCanMessages; }
    To copy to clipboard, switch view to plain text mode 

    where m_oCanMessages is :

    Qt Code:
    1. QMap<QString, QObject*> m_oCanMessages;
    To copy to clipboard, switch view to plain text mode 

    Many thanks for looking.

    Steve

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Insert rows...

    You surely have to get rid of those begin/end statements in setCanData. Use "emit layoutChanged()" instead. It should suffice.

  5. #5
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Unhappy Re: Insert rows...

    Hi,

    Getting rid of the begin/end rows and adding emit layoutChanged results in nothing being shown?

    I'm at a loss

    Thanks,
    Steve

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Insert rows...

    How and when exactly do you create and populate the model?

  7. #7
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Insert rows...

    Hi,

    Model is populated every second via a thread.

    The following function is called from the thread :

    Qt Code:
    1. void QTCanMonitor::AddStaticCanData( QString strId, QString strTime, QString strData )
    2. {
    3. CanMessages* pMess = NULL;
    4. QMap<QString, QObject*>::const_iterator i = m_oCanMessages.find( strId );
    5. if( i != m_oCanMessages.end() ) // must be one
    6. {
    7. pMess = (CanMessages*)i.value();
    8. pMess->m_nCount++;
    9. pMess->m_strData = strData;
    10. pMess->m_strTime = strTime;
    11. }
    12. else // new one
    13. {
    14. pMess = new CanMessages();
    15. pMess->m_nCount = 1;
    16. pMess->m_strData = strData;
    17. pMess->m_strTime = strTime;
    18. pMess->m_strId = strId;
    19. m_oCanMessages.insert( strId, (QObject*)pMess );
    20. m_oMessages.append( (QObject*)pMess );
    21. }
    22. }
    To copy to clipboard, switch view to plain text mode 

    Once the thread has called the above, it emits a signal back to the view which then calls the setCanData method of the model.

    The function theApp->GetCanMap() returns the above m_oCanMessages map which is used in the models data method.

    Regards and thanks,
    Steve

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Insert rows...

    The model is not populated here. You're manipulating its data structures and I might add without any synchronisation which will sooner or later lead to inconsistency of the data. Every time you add a row to the model, you need to call beginInsertRows() and endInsertRows(). There is no point in having two interfaces to the same data storage - either use the model approach from within the thread as well or forget the model and use item-based approach for your view. Because now you're manipulating two different APIs for the same set of data which is just a waste of time. Start treating the model as a mean to access data, not only as a mean to visualize data using a view.

  9. The following user says thank you to wysota for this useful post:

    steg90 (18th September 2007)

  10. #9
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Insert rows...

    So I guess I really should have AddStaticCanData within the model code which would then in turn call begin/end rows?

    Thanks,
    Steve

  11. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Insert rows...

    Yes, you should. Or you can use the model's insertRow() method (provided you implement it).

  12. #11
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Insert rows...

    Thanks.

    One more thing though which I still can't get my head round...in order for the data method to be 'fired' you have to update the models data within the model class - is this a correct assumption?

    Thanks,
    Steve

  13. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Insert rows...

    I don't know if I understand you correctly, but if I do, then the answer is "no". The view will use data() to ask for the data it needs when it knows that a particular index is valid and it is calculated based on what the rowCount() and columnCount() of the model return. Of course most of such info is cached in the view, so you have to notify the outside world from within the model that something has changed in the model. That's where the model's signals enter the scene.

  14. #13
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Insert rows...

    Thanks again for all your help, it has been very much appreciated.

    I have removed the methods to update the data to all now be contained in the data model which now in turn lets me call emit layoutChanged :-)

    Many thanks!

    Steve

  15. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Insert rows...

    Actually calling beginInsertRows() and endInsertRows() should be enough. If not, you should emit rowsInserted() after inserting rows. That'll make it a bit faster as the view only needs to update itself if it currently shows the inserted rows. With layoutChanged() you don't carry information about how the layout was changed, so the view has to update itself regardless of the part of the model changed.

  16. The following user says thank you to wysota for this useful post:

    steg90 (18th September 2007)

Similar Threads

  1. Bulk insert into SQLite
    By munna in forum Qt Programming
    Replies: 6
    Last Post: 19th November 2007, 03:56
  2. Removing rows
    By indifference in forum Qt Programming
    Replies: 1
    Last Post: 30th August 2007, 16:54
  3. Replies: 1
    Last Post: 28th September 2006, 06:21
  4. how to insert an ' in a database
    By jh in forum General Programming
    Replies: 3
    Last Post: 17th August 2006, 02:47
  5. QTableView number of rows and scrollbar issue
    By jnk5y in forum Qt Programming
    Replies: 3
    Last Post: 1st March 2006, 06:55

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.