PDA

View Full Version : beginInsertRows doesn't appear to be working?



steg90
10th May 2007, 15:41
Hi,

I had this working yesterday, my table was being updated / refreshed by doing the following :



QModelIndex index;

beginInsertRows(index, 1, nAmount);

if( pData )
{
for( int i = 0; i < nAmount; i++ )
{
m_Data.append(pData[i].strId);
m_Data.append(pData[i].strTime);
m_Data.append(pData[i].strData);
QString strCount;
strCount.sprintf( "%i", nCount );
m_Data.append(strCount);
nCount++;
}
}
endInsertRows();



Now, the table is only refreshed when it scrolls or I click on it?

Don't know what is wrong?!

Any help is appreciated.
Steve

jpn
10th May 2007, 18:15
void QAbstractItemModel::beginInsertRows(const QModelIndex& parent, int first, int last) (http://doc.trolltech.com/4.2/qabstractitemmodel.html#beginInsertRows)

Have you noticed that parameters first and last are both indexes (starting from 0)? The last parameter is not the count of inserted items but the index of the last inserted item. I don't know your case, but a range of "from 1 to nAmount" sounds incorrect to me.

steg90
11th May 2007, 07:07
Ok thanks,

I now tried setting first and last to one, but still, doesn't refresh?!

Regards,
Steve

wysota
11th May 2007, 09:06
I suggest emitting rowsInserted().

steg90
11th May 2007, 09:09
This not a private member?

jpn
11th May 2007, 09:11
I suggest emitting rowsInserted().
Actually one should not do that because QAbstractItemModel might get "out of sync". Methods beginInsertRows() and endInsertRows() emit corresponding rowsAboutToBeInserted() and rowsInserted() for you.

steg90
11th May 2007, 09:15
Thanks jpn,

I think maybe this has something to do with the fact that I cannot dynamically change the amount of rows in my model, for some reason the amount of rows doesn't get changed visually and I'm confused as to why?

Kind regards,
Steve

wysota
11th May 2007, 09:15
I think we'd have to see more code to understand what is going on.

How is this thread related to this one (http://www.qtcentre.org/forum/f-newbie-4/t-rowcount-and-model-6974.html)?

steg90
11th May 2007, 09:18
Ok, here is most of the code :



int DATreeModel::rowCount( const QModelIndex& parent ) const
{
int nCount = m_Data.count() / 4;
return nCount;
}

int DATreeModel::columnCount(const QModelIndex &) const
{
return 4;
}

QVariant DATreeModel::data( const QModelIndex& index, int role) const
{
QVariant data;

if (!index.isValid())
return QVariant();

if (index.row() > (m_Data.size() / 4) ) {
return QVariant();
}

if(index.column() > 3 ) {
return QVariant();
}

if( role == Qt::DisplayRole )
{
int nPos = index.column() + ( 4 * index.row() );
if( nPos < m_Data.size() )
data = m_Data.at( nPos );
}
return data;
}

void DATreeModel::setCanData( CANDATA *pData, int nAmount, int nCount )
{
beginInsertRows(QModelIndex(), 1, 1);//nAmount );

if( pData )
{
for( int i = 0; i < nAmount; i++ )
{
m_Data.append(pData[i].strId);
m_Data.append(pData[i].strTime);
m_Data.append(pData[i].strData);
QString strCount;
strCount.sprintf( "%i", nCount );
m_Data.append(strCount);
nCount++;

}
}
endInsertRows();

}



I'm so confused?:eek: :eek:

Kind regards,
Steve

wysota
11th May 2007, 09:19
You didn't answer my question :)

steg90
11th May 2007, 09:22
Sorry, yes, it is related. I have an emit function when data is read which goes back to the view which just then scrolls the table view.

jpn
11th May 2007, 09:25
Does DATreeModel::setCanData() get called only once or many times? I think you might be looking for something like this:


void DATreeModel::setCanData( CANDATA *pData, int nAmount, int nCount )
{
if( pData )
{
int row = rowCount();
beginInsertRows(QModelIndex(), row, row + nAmount - 1);
...
endInsertRows();
}
}

steg90
11th May 2007, 09:31
Hi,

setCanData() gets called over and over again from another thread. I tried what you suggested and still the data is not displayed until I click on the table view, also, the rowCount() function still not updating the tableview row amount?

Unless I do something like return 10000 or whatever from the rowCount function, no rows are inserted, I thought rowCount() would do this for you?

Kind regards,
Steve

steg90
11th May 2007, 09:49
I'm still struggling with this, the rowCount returns the amount of rows, but the view doesn't reflect this?

Also, QModelIndex() seems to have invalid row and column values in my beginInsertRows...

Can't believe how difficult this is proving for something so trivial!

Regards,
Steve

wysota
11th May 2007, 09:56
You can't do it from another thread. Containers are not thread safe. You can only emit a signal from the other thread and catch it in the model and update the model from within the main thread.

steg90
11th May 2007, 10:04
Sorry, the worker thread just reads data and emits a signal to main gui thread which then informs the model to update its data. The code below shows the code within the main gui which informs the model of the change with the setCanData function:




if( m_pCanReadThread->isRunning() ) // user may have stopped thread
{
if( nCount < 8000 )
{
m_ptreeModel->setCanData( pData, nAmount, nCount );
QModelIndex index = m_ptreeModel->index( nCount, 0 );
ui.tableView->scrollTo( index );
}
else
{
m_pCanReadThread->cancelThread();
}
}


Regards,
Steve

wysota
11th May 2007, 10:15
As a little check emit layoutChanged() at the end of setCanData(). If it makes it work, it means that you have something wrong in your model and using the Modeltest (http://labs.trolltech.com/page/Projects/Itemview/Modeltest) might be a good idea.

steg90
11th May 2007, 10:28
Hi,

emit layoutChanged() doesn't have any effect. Still not refreshing the view nor are the rows being inserted.

The only way I can get this to work is to set the row count to a big size right at the begining and click on the table view to get the items to appear, very, very strange and totally not acceptable. Obviously when the table has to scroll, the items appear. One thing I have noticed is that the items in the first column of the table always appear?

Regards,
Steve

steg90
11th May 2007, 10:42
Hi,

The problem is that I turn off the signals from the model and don't turn them back on, I do this for speed, having the signals on reduces the speed I can insert data.

Regards,
Steve

wysota
11th May 2007, 11:23
You don't have to block signals in this situation as you don't insert one row at a time.