How to remove items from c++ model inside qml?
-
A weird phenomenon. If using QSqlTableModel, the result is invalid. But if using QSqlQueryModel, the result is the expected.
Why?
The following is my debugging code.
MySqlModel* MySqlModel::selectModel() { QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'"); QVariant val0; QVariant val1; setQuery(QSqlQuery(strQuery)); val0 = record(0).value(0); //Invalid val1 = record(0).value(1); //Invalid QSqlQueryModel model; model.setQuery(strQuery); val0 = model.record(0).value(0); //Correct. The result is the expected. val1 = model.record(0).value(1); //Correct. The result is the expected. return this; }
-
@CoderJeff According to the doc here,
setTable
should be used instead ofsetQuery
forQSqlTableModel
. -
@p3c0 said:
@CoderJeff According to the doc here,
setTable
should be used instead ofsetQuery
forQSqlTableModel
.The cause is not as simple as I expected. Although I change MySqlModel's parent class to QSqlQueryModel instead of QSqlTableModel, it still does not work. But if using QSqlQueryModel directly, it works.
I am confusing.
class MySqlModel : public QSqlQueryModel
{
}MySqlModel* MySqlModel::selectModel()
{
QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'");QVariant val0; QVariant val1; //using MySqlQueryModel setQuery(strQuery); val0 = record(0).value(0); //Invalid val1 = record(0).value(1); //Invalid //using QSqlQueryModel directly QSqlQueryModel model; model.setQuery(strQuery); val0 = model.record(0).value(0); //Correct. The result is the expected. val1 = model.record(0).value(1); //Correct. The result is the expected.
return this;
} -
@CoderJeff Make sure the query is active before using
setQuery
.QSqlQuery sq; sq.prepare(strQuery); sq.exec(); qDebug() << sq.isActive(); setQuery(sq);
-
@p3c0 said:
@CoderJeff Make sure the query is active before using
setQuery
.QSqlQuery sq; sq.prepare(strQuery); sq.exec(); qDebug() << sq.isActive(); setQuery(sq);
I tested it in your way, but It still did not work. The query is definitely active because the return value of isActive() is true.
-
@CoderJeff Ok. Can you post your complete minimal runnable code somewhere in a zip to test ? Need to check whats actually going on.
-
Hi @CoderJeff,
Your code looks fine. Use method1 or method3 inMySqlModel
. The problem is with the view.TableView
insideScrollView
seems to break. I just keptTableView
intab01
and everything worked as expected. -
@p3c0 said:
Hi @CoderJeff,
Your code looks fine. Use method1 or method3 inMySqlModel
. The problem is with the view.TableView
insideScrollView
seems to break. I just keptTableView
intab01
and everything worked as expected.What's the meaning of "kept
TableView
intab01
"? Can you show me the code? -
@CoderJeff The contents of
tab01.qml
file. I justTableView
in it and deleted the rest. It works.//Tab01.qml import QtQuick 2.0 import QtQuick.Controls 1.2 import QtQuick.Layouts 1.1 TableView{ id: tableView anchors.fill: parent TableViewColumn{ role: "id"; title: "Id"} TableViewColumn{ role: "name"; title: "Name"} TableViewColumn{ role: "author"; title: "Author"} TableViewColumn{ role: "year"; title: "Year"} model:myCppClass.model() }
-
@CoderJeff Hmm that's strange. It doesn't work. Tested it with my other project, works there.
-
@CoderJeff If you replace the code in
data()
with the following, it will work:QVariant MySqlModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); switch(role) { case Id: { return record(index.row()).value(0).toString(); } case Name : { return record(index.row()).value(1).toString(); } case Author : { return record(index.row()).value(2).toString(); } case Year : { return record(index.row()).value(3).toString(); } } return QSqlQueryModel::data(index, role); } ... setQuery(strQuery); var0 = record(1).value(0); var1 = record(0).value(1); qDebug() << var0 << var1;
Trying to find the reason.
-
That's what I am confused with. In addition, I tested the following statements, and they all works.
record(0).indexof(...)
record(0).index(...)
data(...)I do not understand why only record(0).value(...) can not work.
I tried to delete a chosen row, but it could not.I do not know whether it is the above reason. I have updated my code. Can you please check them? Thank you.
-
@p3c0 said:
@CoderJeff If you replace the code in
data()
with the following, it will work:QVariant MySqlModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); switch(role) { case Id: { return record(index.row()).value(0).toString(); } case Name : { return record(index.row()).value(1).toString(); } case Author : { return record(index.row()).value(2).toString(); } case Year : { return record(index.row()).value(3).toString(); } } return QSqlQueryModel::data(index, role); } ... setQuery(strQuery); var0 = record(1).value(0); var1 = record(0).value(1); qDebug() << var0 << var1;
Trying to find the reason.
Yes, it works. The value of val0 and val1 are both right this time. But I still can not delete a row.
-
@CoderJeff That is because
QSqlquerymodel
is a read-only model. See here. You will need to delete the row using another query and then update the view. -
I tried to use QSqlTableModel, and it also did not work.
Here I do not want to use another query. I just want to delete a row from the model instead of the table. In other words, only on GUI it seems to be deleted, but it is still in the table actually.
-
@CoderJeff Sorry I too donot know about this. This QTBUG-37538 seems to be similar but using
ListView
.
Test it withQTableView
to see if it works ? -
@CoderJeff Ok, but then why not execute a delete query instead of creating another temporary table ? I guess
removeRow
forQSqlTableModel
too does the same internally.