PDA

View Full Version : Difficulties with QTableView and setModel



sekatsim
16th June 2008, 01:37
The Qt4.4 Doc, in the SQL section, has the following example for connecting an opened SQL form to a QTableView widget:


QTableView *view = new QTableView;
view->setModel(model);
view->show();

However, when I try something similar:


QSqlTableModel model;

model.setTable("employee");
model.setFilter("salary > 50000");
model.setSort(2, Qt::DescendingOrder);
model.select();

for (int i = 0; i < model.rowCount(); ++i) {
QString name = model.record(i).value("name").toString();
int salary = model.record(i).value("salary").toInt();
qDebug() << name << salary;
}

model.insertRows(row, 1);
model.setData(model.index(row, 0), 1013);
model.setData(model.index(row, 1), "Peter Gordon");
model.setData(model.index(row, 2), 68500);
model.submitAll();

ui.cueTable->setModel(model);

I get

"src/cues.cpp:38: error: no matching function for call to ‘QTableView::setModel(QSqlTableModel&)’
/usr/include/qt4/QtGui/qtableview.h:73: note: candidates are: virtual void QTableView::setModel(QAbstractItemModel*)
make: *** [build/cues.o] Error 1"

I cant tell why.. As far as I understood, QSqlTableModel Was a QAbstractItemModel. I'm trying to put the model into a QTableView, just like in the example, but it won't accept it.

Why is this?

Thank you

wysota
16th June 2008, 06:24
You have to pass a pointer to the model, not a reference to it. And don't create the model on the stack - it will go out of scope immediately.

cydside
16th June 2008, 06:48
Try this:

ui.cueTable->setModel(&model);

wysota
16th June 2008, 07:04
Try this:

ui.cueTable->setModel(&model);

This won't work because of the reasons I mentioned in my post.

cydside
16th June 2008, 10:30
Sorry, I've posted my hint without refresh the page with your post.

sekatsim
17th June 2008, 02:30
"ui.cueTable->setModel(*model);"

Doesn't work for me either. What syntax do you suggest? I'm not very comfortable with pointers yet.

Thank you for the help thus far

caduel
17th June 2008, 12:42
There are 2 errors in your code (both of which Wysota mentioned).
i) you must pass a POINTER in the call to setModel
ii) you must ensure that that pointer actually lives long enough

The easiest way to to do that, is:

QSqlTableModel *model = new QSqlTableModel(ui.cueTable);

<< replace your calls to "model." with "model->" >>

setModel(model);


If the method you posted should not go out of scope (e.g. if it is followed by a QApplication::exec() or so...); then you could leave your code as is and just write
setModel(&model);
otherwise you will leave your view with a dangling pointer and the code will crash in all probability.

HTH
Christoph

sekatsim
17th June 2008, 22:38
Thanks for your response, caduel, I think I understand it better now.

I've moved everything back into my ui class, just to make it simpler for now. I put a

QSqlTableModel *model;

in the public declaration for that class. In the implementation, I have:


QSqlDatabase cuedb = QSqlDatabase::addDatabase("QSQLITE");
cuedb.setHostName("westdalelighting");
cuedb.setDatabaseName("Cues");
cuedb.setUserName("Westdale");
cuedb.setPassword("westdale");
bool ok = cuedb.open();

int row = 1;

model->setTable("employee");
model->setFilter("salary > 50000");
model->setSort(2, Qt::DescendingOrder);
model->select();

for (int i = 0; i < model->rowCount(); ++i) {
QString name = model->record(i).value("name").toString();
int salary = model->record(i).value("salary").toInt();
qDebug() << name << salary;
}

model->insertRows(row, 1);
model->setData(model->index(row, 0), 1013);
model->setData(model->index(row, 1), "Peter Gordon");
model->setData(model->index(row, 2), 68500);
model->submitAll();

cueTable->setModel(model);

Which compiles successfully, but fails to put any items into my cueTable widget. The cueTable widget was constructed by QDesigner-- am I perhaps missing something there?

caduel
18th June 2008, 07:14
Where do you actually create that model?

A line of

QSqlTableModel *model;

just declares a pointer. When your class is instantiated, all you have is an (uninitialized, i.e. random!) pointer to a model.

You need to have a real model, i.e. a line like

model = new QSqlTableModel( <add Qt-parent here> );
somewhere.


(Side note: On the other hand, if you are willing to move the model (pointer) into your class, then you could of course put the real model there. Then you could revert to your original code in most places.)

sekatsim
18th June 2008, 22:37
I want the model to be accessible to other functions within that class, so I'll need to declare *model in the class definition, no?

Now I have "QSqlTableModel *model;" in the public declaration of the class, and


void MainWindowImpl::cueNewShowClick(){

-> model = new QSqlTableModel( cueTable );

QSqlDatabase cuedb = QSqlDatabase::addDatabase("QSQLITE");
cuedb.setHostName("westdalelighting");
cuedb.setDatabaseName("Cues");
cuedb.setUserName("Westdale");
cuedb.setPassword("westdale");
bool ok = cuedb.open();

int row = 1;

model->setTable("employee");
model->setFilter("salary > 50000");
model->setSort(2, Qt::DescendingOrder);
model->select();

for (int i = 0; i < model->rowCount(); ++i) {
QString name = model->record(i).value("name").toString();
int salary = model->record(i).value("salary").toInt();
qDebug() << name << salary;
}

model->insertRows(row, 1);
model->setData(model->index(row, 0), 1013);
model->setData(model->index(row, 1), "Peter Gordon");
model->setData(model->index(row, 2), 68500);
model->submitAll();

cueTable->setModel(model);
}

Still though, nothing appears in the QTableView. This event is executed when a "populate table" button is pressed.

jpn
19th June 2008, 04:52
Does such table exist?

caduel
19th June 2008, 07:05
try to print the output of your database calls
i.e. do something like

bool ok = cuedb.open();
qDebug() << "open: ok="<<ok;
Do the same for all calls that might fail.