Why does the last row remain in QTableView until the page is reloaded ?
Hi All,
I'm using [Qt] QTableView and QSqlQueryModel with SQLite Database, I'm trying to delete rows from the QTableView(from the database) by clicking on a row which opens up another page where I carry out the deletion and using 'emit' signal and slot to update the parent page, it all works fine till the VERY LAST ROW. It deletes from the database but remains in the
QTableView until I reload the page, why ?
Code:
while(qry.next())
{
model->setQuery(qry);
model
->setHeaderData
(0, Qt
::Horizontal,
QObject::tr("ID"));
model
->setHeaderData
(1, Qt
::Horizontal,
QObject::tr("Name"));
model
->setHeaderData
(2, Qt
::Horizontal,
QObject::tr("Depart"));
model
->setHeaderData
(3, Qt
::Horizontal,
QObject::tr("Car Reg"));
model
->setHeaderData
(4, Qt
::Horizontal,
QObject::tr("Srt Date"));
model
->setHeaderData
(5, Qt
::Horizontal,
QObject::tr("End Date"));
model
->setHeaderData
(6, Qt
::Horizontal,
QObject::tr("Contact"));
model
->setHeaderData
(7, Qt
::Horizontal,
QObject::tr("Photo"));
ui->tableView_staffLog->setModel(model);
}
connect(ui->tableView_staffLog, SIGNAL(pressed(const QModelIndex&)), this,
SLOT(on_tableView_staffLog_clicked(const QModelIndex&)));
}
void ControlPanel::on_tableView_staffLog_clicked(const QModelIndex& index)
{
int emp_id = tableModel->data(tableModel->index(index.row(),0), Qt::DisplayRole).toInt();
employeedetails = EmployeeDetails::instance(emp_id, index.row(), this);
connect( employeedetails, SIGNAL(employeeDeleted(int)), this, SLOT(deleteEmployee(int)) );
employeedetails->show();
}
Child page
Code:
query.prepare("UPDATE employee SET is_hidden = '1' WHERE emp_id = (:emp_id)");
query.bindValue(":emp_id", emp_id);
success = query.exec();
if(!success)
{
qDebug() << "removeEmployee error: "
<< query.lastError();
}
else
{
if( tableRow >= 0 )
emit employeeDeleted(tableRow);
this->close();
}
Re: Why does the last row remain in QTableView until the page is reloaded ?
show the deleteEmployee() slot.
Re: Why does the last row remain in QTableView until the page is reloaded ?
Thanks for your reply
Code:
void ControlPanel::deleteEmployee(int row)
{
loadAllData();
}
It basically reloads all the data in parent page.
Re: Why does the last row remain in QTableView until the page is reloaded ?
*sigh*
Do you want to be helped or not?
Show us the code that removes employees from your model, the problem is probably there.
Re: Why does the last row remain in QTableView until the page is reloaded ?
Thanks for your reply again, I have already posted that code it's a soft delete meaning it UPDATES and hides the record instead of complete delete.
Code:
query.prepare("UPDATE employee SET is_hidden = '1' WHERE emp_id = (:emp_id)");
query.bindValue(":emp_id", emp_id);
success = query.exec();
if(!success)
{
qDebug() << "removeEmployee error: "
<< query.lastError();
}
else
{
if( tableRow >= 0 )
emit employeeDeleted(tableRow);
this->close();
}
Re: Why does the last row remain in QTableView until the page is reloaded ?
Code:
while(qry.next())
{
model->setQuery(qry);
model
->setHeaderData
(0, Qt
::Horizontal,
QObject::tr("ID"));
model
->setHeaderData
(1, Qt
::Horizontal,
QObject::tr("Name"));
model
->setHeaderData
(2, Qt
::Horizontal,
QObject::tr("Depart"));
model
->setHeaderData
(3, Qt
::Horizontal,
QObject::tr("Car Reg"));
model
->setHeaderData
(4, Qt
::Horizontal,
QObject::tr("Srt Date"));
model
->setHeaderData
(5, Qt
::Horizontal,
QObject::tr("End Date"));
model
->setHeaderData
(6, Qt
::Horizontal,
QObject::tr("Contact"));
model
->setHeaderData
(7, Qt
::Horizontal,
QObject::tr("Photo"));
ui->tableView_staffLog->setModel(model);
}
This code makes no sense at all. Why would you create a new model for *every* result in your query? Each time through the loop, a new model is created, and you set it onto your table view (which replaces the model you created and set on the previous time through the loop).
Quite likely, this is the source of your bug. If the query returns no result, this loop isn't executed so the model held by the table is not replaced. That model still holds the last row.
Re: Why does the last row remain in QTableView until the page is reloaded ?
Code:
qry.prepare( "Some Query" );
if( !qry.exec() )
qDebug() << qry.lastError();
else
{
while(qry.next())
{
model->setQuery(qry);
model
->setHeaderData
(0, Qt
::Horizontal,
QObject::tr("ID"));
model
->setHeaderData
(1, Qt
::Horizontal,
QObject::tr("Name"));
model
->setHeaderData
(2, Qt
::Horizontal,
QObject::tr("Depart"));
model
->setHeaderData
(3, Qt
::Horizontal,
QObject::tr("Car Reg"));
model
->setHeaderData
(4, Qt
::Horizontal,
QObject::tr("Srt Date"));
model
->setHeaderData
(5, Qt
::Horizontal,
QObject::tr("End Date"));
model
->setHeaderData
(6, Qt
::Horizontal,
QObject::tr("Contact"));
model
->setHeaderData
(7, Qt
::Horizontal,
QObject::tr("Photo"));
ui->tableView_staffLog->setModel(model);
}
Thanks for your reply I have changed it according to your suggestion unfortunately it didn't help.
Re: Why does the last row remain in QTableView until the page is reloaded ?
Quote:
Thanks for your reply I have changed it according to your suggestion unfortunately it didn't help.
Your code still shows a basic misunderstanding. There is absolutely no need to set the model header data on every call to qry.next(). Set it once, after you create the model in line 1. The header data never changes so why set it repeatedly for every result in every query?
Think about what is happening in line 7: If the query succeeds (qry.exec() returns true) but the result contains ZERO rows (because you have successfully emptied the table), then qry.next() returns false and the code inside the while loop does not get executed. In particular, the line
Code:
model->setQuery( qry );
does not get executed, so the model is left holding the last query, which contained ONE result.
Re: Why does the last row remain in QTableView until the page is reloaded ?
d_stranz blue that was 10/10, I've been at it past two bloody days. Success at last Thank you
Re: Why does the last row remain in QTableView until the page is reloaded ?
Sure, no worries. One more thing:
This also needs to be done only once, when you create the class that contains this code. You do not need to create a new model each time you do a query (eg. on each data reload). Create the model one time, set it on the table, and remember the pointer as a member variable of your class (or retrieve it from the table in the data reload method via QAbstractItemView::model()). The only things you need to do in your reload data method are:
- prepare the query (maybe; if it is the same query every time, then make it a member variable too and prepare it once)
- exec() the query
- if exec() returns true, set the query on the model, otherwise clear() the model.
Everything else - setting the header data, setting the model on the view, etc. can be done once in the constructor.