PDA

View Full Version : SQLITE QTableView scrollTo problem



vogeljh
13th April 2008, 03:29
I am pretty new to Qt. I am having a problem with a call to QTableView::scrollTo. I am using an editable QSqlQueryModel for the data, connected to an SQLITE database. It works fine within the first 250 rows, but if I edit a row > 250, then refresh, the scrollTo call does not bring me back to the row I was editing; The view goes back to the top.

bool editableSqlQueryModel::setData( const QModelIndex &index, const QVariant &value, int )
{
...
// code to update the model data here

refresh();
view->scrollTo( index, QAbstractItemView::EnsureVisible );
return ok;
}

Thanks for any leads!

wysota
13th April 2008, 15:42
What does editableSqlQueryModel look like?

vogeljh
14th April 2008, 02:56
Here is my editablesqlquerymodel.h


#ifndef QUESTVIEW_H
#define QUESTVIEW_H
//
#include <QTableView>
#include <QSqlQueryModel>
#include <QModelIndex>
#include "mainwindowimpl.h"
//
class editableSqlQueryModel : public QSqlQueryModel
{
Q_OBJECT
public:
editableSqlQueryModel( QObject *parent = 0, QTableView *v = 0 );

Qt::ItemFlags flags( const QModelIndex &index ) const;
bool setData( const QModelIndex &index, const QVariant &value, int role );
bool insertRow( int qid, bool copied );
bool deleteRow( int qid );

private:
bool setRef( int qid, const QString ref );
bool setType( int qid, const QString &type );
bool setPreface( int qid, const QString &preface );
bool setQuest( int qid, const QString &quest );
bool setAns( int qid, const QString &ans );
bool setCR( int qid, const QString &cr );
bool parseRef( const QString ref, int *book, int *chap, int *verse, int *verses );
void refresh();
MainWindowImpl *pwin;
QTableView *view;
};

#endif

wysota
14th April 2008, 07:04
What about the implementation of setData()?

sadjoker
15th April 2008, 16:25
I have the very same problem... just i don`t know how to even scroll it. This is my constructor:


model1 = new QSqlTableModel();
model1->setTable("names");
if ( activeCheck->isChecked()==true ) {
model1->setFilter( QString("active='yes'"));
}
model1->setEditStrategy(QSqlTableModel::OnFieldChange);
model1->select();

tableView->setSortingEnabled(true);

tableView->setModel(model1);
tableView->setColumnHidden(0,true);
tableView->setColumnHidden(8,true);
tableView->setColumnWidth(2,83);
tableView->setColumnWidth(6,41);
tableView->setColumnWidth(7,41);
tableView->sortByColumn(2,Qt::AscendingOrder);

After every data change in the table and repopulating the model ... it goes to the top of the table... and sometimes its frustrating to browse down 400 results...
How to use tableView->scrollTo... how to get the index from the repopulated model?

Edit: he inherits the QSqlQueryModel... how can i scrollTo without inheriting QSqlTableModel and modding the setdata()?

vogeljh
16th April 2008, 04:07
What about the implementation of setData()?

I found a solution. First, I need to correct the original problem statement. The scrollTo() works fine up through row 256. Rows 257 and greater exhibit the problem. Here is a simplified version of setData() I used to replicate the problem, along with the refresh() call:


bool editableSqlQueryModel::setData( const QModelIndex &index, const QVariant &value, int )
{
if (index.column() < 2 || index.column() > 2)
return false;

QModelIndex primaryKeyIndex = QSqlQueryModel::index( index.row(), 0 );
int id = data( primaryKeyIndex ).toInt();
clear();

QString sql = QString( "UPDATE Questions SET Qtype=\'%1\' WHERE QID=%2" ).arg(value.toString()).arg(id);
QSqlQuery query = QSqlQuery( sql );

refresh();
qview->scrollTo( index, QAbstractItemView::EnsureVisible );
return true;
}

void editableSqlQueryModel::refresh()
{
setQuery( *(pwin->GetQuestQuery()) );
}

Here is my solution: change the refresh() function as follows:

void editableSqlQueryModel::refresh()
{
setQuery( *(pwin->GetQuestQuery()) );
while( canFetchMore() )
fetchMore();
}

Now the scrollTo() call works.

vogeljh
16th April 2008, 04:16
I don't know if this would work in your case, but I found the indexAt() member of QTableView useful. You would need to grab a index to the current position before the update occurs, passing the indexAt() function a position (perhaps by calling QCursor::pos()). This will give you an QModelIndex you can give to the scrollTo() function after the update.

sadjoker
16th April 2008, 19:45
QSqlTableModel QSqlTableModel::OnManualSubmit and QSqlTableModel::OnRowChange emits datachanged signal on setData(...) with 2 args QModelIndex


connect(model1, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(submitTbl(QModelIndex,QModelIndex)));

It was working... i could see the index.row() and index.column() on the changed value of the QTableVIew... but oddly enough anything inherited from QAbstractItemView didn`t work in another function apart from constructor. SO, I did it with OnManualSubmit option and an applying button + onclose event of the Dialog to check if the changed data was saved popping message box. Thats how i did it...