HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Insert new row to a QTableView by double-clicking the last row

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
lasttheinsertnewclickingqtableviewdoublerow

Problem

Recently I was experimenting with QTableViews and I wanted to create something where I can add a new row to a table without having any additional button/menu item outside the table. I achieved this by adding a single item to the view's model and set that not editable. Then if a double-click happens on the table I check if it was on the last item. IF that is true I just add a new item before the last so my special item will be the last row every time.

Here is a minimal example which works:

#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTableView tableView;
    QStandardItemModel model{ 0, 1 };
    QStandardItem insertRow{ "" };
    insertRow.setEditable(false);

    tableView.setModel(&model);
    model.insertRow(0, &insertRow);

    QApplication::connect(&tableView, &QTableView::doubleClicked,
            [&model](const QModelIndex index)
    {
        int rowCount = model.rowCount();
        if (index.row() == rowCount - 1)
            model.insertRow(rowCount - 1, new QStandardItem{ "New item" });
    });

    tableView.show();

    return a.exec();
}


Is there a more proper way to implement this? Am I doing it right or this functionality is built into the Qt framework and I completely missed?

Solution

Your answer is a good one, but it has that non-editable last row hanging around. If you want to make the extra row editable, you can do as shown here. The idiom of hitting a return in the current last row that produces an empty row, is a standard one.

I don't believe there is a built-in mechanism in Qt.

A variation of the approach found in the above link

In my app, I use a slightly different approach, and thought I would share it here. For convenience, I summarize both approaches here.

In the answer at the above link, both MyTableModel and MyBlankRowModel are derived from QAbstractTableModel, and the former is set as a sourceModel in the latter. This idiom implies that all QAbstractTableModel methods overridden in MyTableModel must be re-implemented in MyBlankRowModel, mostly forwarding to the MyTableModel methods, with exceptions as noted in that answer. This approach can be cumbersome if a large number of QAbstractTableModel methods are overridden in MyTableModel as is the case in my app.

Therefore I derive MyBlankRowModel from MyTableModel, only override a few methods: rowCount() returning MyTableModel::rowCount() + 1; data(...) and setData(...) to handle the row buffer. This offers the flexibility that MyTableModel can be designed to handle a complex model, and nothing in MyBlankRowModel has to change! It also simplifies the view interaction since I simply do qTableView->setModel(myBlankRowModel).

Context

StackExchange Code Review Q#125622, answer score: 2

Revisions (0)

No revisions yet.