Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Qt, create a table with an blank editable row

Tags:

qt

qt4

This is a Qt-specific question.

It's convenient to be able to add new data to a table by typing content into a blank row at the bottom of a table. When the data is committed, a new blank row is added to the table.

Has anyone found a way of implementing this in a generic way, that fits into Qt's model-view programming architecture? My closest attempt involves creating a proxy model, such that the rowCount() returned from the model is always one greater than the source model.

QAbstractTableModel* sourceModel ; // Data is stored here
QBlankRowModel* model ; // Proxy model that adds one to rowCount()
QTableView* view ; // View
view->setModel( model ) ;
model->setSourceModel( sourceModel ) ;

Any suggestions are welcome. Thanks.

like image 692
swongu Avatar asked Oct 27 '09 00:10

swongu


2 Answers

From a design-perspective, this should be part of the view, not the model. Therefore, I suggest implementing a view with the functionality and leave the model unchanged. KOffice Kexi does just this with kexitableview (screenshot, documentation). Maybe you want to use some of their code.

BTW, you might still be able to use your hack and combine it with my suggestion by putting it inside a new table view implementation YourTableView:

  1. QBlankRowModel re-implements the QAbstractTableModel interface. It returns sourceModel.rowCount()+1 as the QBlankRowModel::rowCount(). It returns a QVariant() if the n+1th row is requested in QBlankRowModel::data(). All the rest within QBlankRowModel is forwarded to the sourceModel (with editing the n+1th row in QBlankRowModel buffered and replaced with inserting into the sourceModel when finished).

  2. The new YourTableView inherits from QTableView and wraps the sourceModel within YourTableView::setModel(), calling QTableView::setModel(QBlankRowModel(sourceModel)).

Thereby, your hack is localized at one point.

like image 144
stephan Avatar answered Oct 02 '22 19:10

stephan


Your solutions seems a little hackish. Your problem is not only additions, it's also editions. What happens when your user edits a row, the typed data goes directly to your "data layer" even before the user commits his edition?

A better solution would be to restrict the role of your sourceModel. Rather than being a "direct" representation of your data, it should be a "buffered" representation of it. When the sourceModel is created, you make a copy of your data in some kind of Row() instances. The sourceModel, having its own copy of the data can then freely play around, perform editions and additions, and only commit the data to your model layer when the user commits his edits.

If you want a PyQt example of such a table, you can look at the source of a project of mine:

http://hg.hardcoded.net/moneyguru/

You might have to dig around to actually find the "buffering" logic because it's not in the PyQt code itself, but rather the "cross-platform" part of the code:

http://hg.hardcoded.net/moneyguru/src/tip/core/gui/table.py

This logic is then used in my QAbstractItemModel subclass:

http://hg.hardcoded.net/moneyguru/src/tip/qt/controller/table.py

like image 27
Virgil Dupras Avatar answered Oct 02 '22 18:10

Virgil Dupras