How to remove items from c++ model inside qml?
-
@CoderJeff Ok. Not sure then. I guess there's some other code that is causing the problem.
-
The entire code is the following.
In C++ (Q_INVOKABLE):
void MyCppClass::remove(const int idx)
{
bool bExe = mySqlModel->removeRow(idx);
}(Q_INVOKABLE)
QObject* MyCppClass::selectModel()
{
return mySqlModel->selectModel();
}MySqlModel* MySqlModel::selectModel()
{
QString strQuery("SELECT field1,field2,field3 FROM table WHERE field1='a'");
setQuery(QSqlQuery(strQuery));
return this;
}TableView {
id: tableView
TableViewColumn{ role: "field1"; title: "Field1"}
TableViewColumn{ role: "field2"; title: "Field2"}
TableViewColumn{ role: "field3"; title: "Field3"}
model: myCppClass.selectModel()
......
}Button{
onClicked: myCppClass.remove(tableView.currentRow);
} -
@CoderJeff Can you check if
mySqlModel
has data ?
You can check it by usingrecord
.mySqlModel->record(idx).value(0).toString() // checking value at column 0 and converting it to string
-
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.