How to remove items from c++ model inside qml?
-
My model is subclass of QAbstractListModel
What methods should I implement? I guess it's deleteRows but how do I "call" them inside of qml code? Especially if I don't have access to my model (or it's methods because of some strange qt magic which turns my model to QQmlDMAbstractItemModelData which has all the rolls but no methods, and I don't want to store my model as property in all qml delegates)
I mean then I do something like role = data it implicitly calls setData, when I just use role it uses data(). But how to make it remove current item (at index)? -
Hi @flashmozzg
You can create a Q_INVOKABLE function in C++ model which will internally call removeRow. Current item row can be retrieved from the QML itself and then pass to this function. -
@p3c0 said:
Hi @flashmozzg
You can create a Q_INVOKABLE function in C++ model which will internally call removeRow. Current item row can be retrieved from the QML itself and then pass to this function.Yeah I ended up doing like that. With propagating remove signal to the top and then deleting it. Was hoping there was some built-in mechanism for doing that like there is for reading and modifying items data.
-
I have the same question. But I did not solve it using removeRow.
In C++ (Q_INVOKABLE):
void MyCppClass::remove(const int idx)
{
bool bExe = mySqlModel->removeRow(idx);
}In QML:
TableView {
id: tableView
......
}Button{
onClicked: myCppClass.remove(tableView.currentRow);
}The application output is:
QSqlQuery::value: unknown field name ''Is there anything wrong with my code?
-
@CoderJeff Is
mySqlModel
a subclass ofQSqlQueryModel
? -
@CoderJeff Are you sure
tableView.currentRow
returns a valid row ? -
@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.