How to edit a cell in a model inheriting from QSqlTableModel
-
I have created a model that stores list of users with their profile information. The users are shown on
main.qml
and their profile onprofile.qml
.The profile can be access by swiping the user name to right which will bring
profile.qml
into view. After that the user can edit his/her info by hitting the save button.What is the problem:
When I click on the save button to save the profile info the model seems to get updated but the view doesn't. The view is only updated when I re-run the application once again.
main.qml:
// this file displays the list of users from the model StackView { id: home anchors.fill: parent padding: 0 property var model: null initialItem: Pane { ColumnLayout { id: body ListView { id: view currentIndex: -1 height: body.height width: body.width delegate: SwipeDelegate { id: content width: parent.width height: 50 text: model.name swipe.onCompleted: { if (swipe.position > 0){ home.model = model home.pop() home.push("Profile.qml") } swipe.close() } swipe.left: Label { text: qsTr("Profile") color: "white" verticalAlignment: Label.AlignVCenter padding: 12 height: parent.height anchors.left: parent.left opacity: 2 * content.swipe.position } } model: UserModel { id: user_model } ScrollIndicator.vertical: ScrollIndicator {} } } } }
Profile.qml:
// this file displays the user profile which can be edited and submitted with save button ColumnLayout { id: info spacing: 10 RowLayout { id: phone_g width: parent.width TextField { id: phone text: home.model.phone font.pixelSize: 13 } } RowLayout { id: address_g width: parent.width TextField { id: address text: home.model.address font.pixelSize: 13 } } RowLayout { id: save_l width: parent.width Button { id: save_btn text: "save" onClicked: { console.log("addr: "+user_model.setData(user_model.index(home.model.index, 2), address.text)) console.log("phn: "+user_model.setData(user_model.index(home.model.index, 3), phone.text)) } } } }
usermodel.cpp:
// this is how i update/edit the model UserModel::UserModel(QObject *parent, QSqlDatabase db) : QSqlTableModel (parent, db) { setTable("users"); select(); setEditStrategy(QSqlTableModel::OnFieldChange); } bool UserModel::setData(const QModelIndex &index, const QVariant &value, int role){ if (index.isValid() && role == Qt::EditRole){ bool response = QSqlTableModel::setData(index, value, role); response = QSqlTableModel::submitAll(); // tried "emit dataChanged(index, index);" also which doesn't work return response; } return false; }
-
Why do you reimplement setData() at all when you don't do anything with the data there? QSqlTableModel does all for you in this case.
-
@Christian-Ehrlicher Right but after hitting save the view doesn't get updated I need to re-run the application to show the change how to overcome this ?
-
Hi,
From what I can see you are using the model the same way you would for a widget based application except that in QtQuick things are slightly different.
Calling setData like you do won't trigger a refresh because the roles used to get the data do not match Qt::EditRole. The writing works because of the default value of the
role
parameters. -
@SGaist @Christian-Ehrlicher How would I let the view know about the data change ? And I would like to mention I am displaying the list of users with
UserRole
like this:QVariant UserModel::data(const QModelIndex &index, int role) const{ QVariant value; if (index.isValid()) { if (role < Qt::UserRole) value = QSqlQueryModel::data(index, role); else { int columnIdx = role - Qt::UserRole - 1; QModelIndex modelIndex = this->index(index.row(), columnIdx); value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole); } } return value; } QHash<int, QByteArray> UserModel::roleNames() const{ QHash<int, QByteArray> roles; for (int i = 0; i < record().count(); i ++) { roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8()); } return roles; }
-
This post is deleted!