[Solved] Inserting a new row of data into QSqlTableModel via QTableView edit



  • I have a function that attempts to insert a string value to a new row in a table behind a QSqlTableModel. It does so via a QTableView with a F2 style edit called programatically.

    The data is not saving to the database. It shows the change in the view, but doesn't push it to the table. Edits to the existing rows don't save either.

    I know this because I query the table after closing the application and my inserted row is not there.

    Here is my code:

    [code]
    int row = periodModel->rowCount();
    periodModel->insertRow(row);
    QModelIndex index = periodModel->index(row, PeriodMetricsView_PeriodName);
    periodView->setCurrentIndex(index);
    periodView->edit(index);
    [/code]

    Also, I did add the following to my periodModelSettings:
    [code]
    periodModel->setEditStrategy(QSqlTableModel::OnRowChange);
    [/code]

    What do I need to do to get it to save the addition?

    BTW:
    To delete a row, I just have to do the following (it works!):
    [code]
    QModelIndex index = periodView->currentIndex();

    if (!index.isValid()) {
    return;
    }

    periodModel->removeRow(index.row());
    [/code]

    Both my insert and remove functions are attached to QAction objects.

    Thanks.



  • Hi there,
    The models can't handle just the insert and remove of rows. You MUST first call beginInsertRows function for the View to handle the insertion properly.
    "beginInsertRows()":http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#beginInsertRows
    Note: This function emits the rowsAboutToBeInserted() signal which connected views (or proxies) must handle before the data is inserted. Otherwise, the views may end up in an invalid state.

    So, that might cause stuff to fail and not get stored in the View/model concept.
    Good luck



  • Thanks Jeroen.

    Here is what I added to my QSqlTableModel subclass:

    [code]
    void SqlTableModel::beginInsertRow(const QModelIndex &parent, int row) {
    QSqlTableModel::beginInsertRows(parent, row, row);
    }

    void SqlTableModel::endInsertRow() {
    QSqlTableModel::endInsertRows();
    }
    [/code]

    Then I added the following to the aforementioned insert function in my main window (by the way, this is the contents of a QAction triggered slot, not a rewrite of insertRows):
    [code]
    int row = periodModel->rowCount();
    QModelIndex index = periodModel->index(row, PeriodMetricsView_PeriodName);

    periodModel->beginInsertRow(index, row);

    periodModel->insertRow(row);

    periodView->setCurrentIndex(index);
    periodView->edit(index);

    periodModel->endInsertRow();
    [/code]

    I did end up rearranging where the insertRow was called, as you can see.

    However, that did not fix the issue.

    Also, I am getting the following error message with the "period->edit(index); line (sorry I didn't realize or mention it before:
    [code]
    edit: index was invalid
    edit: editing failed
    [/code]



  • Hi,
    Maybe just an other idea, but try to use the insertRecord from the QsqlTableModel class. It calls insertRow etc on its own.
    Also set the row on -1, this will append your data to the model.
    If the view is updated it means the emit(datachanged) signal is called? If so, why not connect this signal to your saving function (slot). This way you know for sure the data is stored even if the program crashes later on. Otherwise maybe use the debugger to check the insertion of the row?
    The problem of not storing data might come from a complete different part of your program and not the model at all?
    greetz



  • Good points, Jeroen.

    I will implement those changes and test this evening and report back.

    Thanks.



  • [quote author="Jeroentje@home" date="1349941438"]Hi,
    The problem of not storing data might come from a complete different part of your program and not the model at all?
    [/quote]

    True. I actually need to tinker with my database triggers and see if that makes a difference. My Qt View is hitting an "INSTEAD OF" trigger on a sqlite view. (BTW: This is the only way to use a SQL view and be able to update through it to its source table.) However, I am pretty certain that these triggers are working because I have tested inserting into the view successfully through sqlite's scripting environment outside of my application.

    Anyhow, I am in the process using your ideas from earlier. So the edit event is asynchronous and I would have to be caught by connecting to the signal? That makes sense.



  • Your suspicion was correct.

    The problem lied with my insert trigger for the SQL view behind the Qt QTableView object. I was using the table field name behind the SQL view to do the SQL update and not the SQL view's field name.

    Thanks for your help and sorry I wasn't more aware of my database side before posting.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.