2009-10-27 7 views
4

Ceci est une question spécifique à Qt.Dans Qt, créez une table avec une ligne vierge modifiable.

Il est pratique de pouvoir ajouter de nouvelles données à une table en tapant du contenu dans une rangée vide au bas d'une table. Lorsque les données sont validées, une nouvelle ligne vide est ajoutée à la table.

Est-ce que quelqu'un a trouvé un moyen de mettre en œuvre cela de façon générique, qui s'intègre dans l'architecture de programmation de vue-modèle de Qt? Ma tentative la plus proche implique la création d'un modèle de proxy, de sorte que le rowCount() renvoyé par le modèle soit toujours supérieur au modèle source.

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

Toutes les suggestions sont les bienvenues. Merci.

Répondre

0

Cela semble être une solution raisonnable, car cela devrait fonctionner pour n'importe quel modèle que vous pourriez vouloir comme le modèle de table réel, à savoir. SqlTableModel ou juste un simple. Tant que vous ajoutez la ligne lorsque l'utilisateur a terminé l'édition et veillez à ne pas ajouter la ligne lorsque l'utilisateur n'a pas ajouté de données.

1

Vos solutions semblent un peu hackish. Votre problème n'est pas seulement des ajouts, c'est aussi des éditions. Que se passe-t-il lorsque votre utilisateur édite une ligne, que les données saisies vont directement dans votre "couche de données" avant même que l'utilisateur ne commette son édition?

Une meilleure solution serait de restreindre le rôle de votre sourceModel. Plutôt que d'être une représentation "directe" de vos données, il devrait s'agir d'une représentation "tamponnée" de celles-ci. Lorsque le modèle source est créé, vous effectuez une copie de vos données dans un type d'instance Row(). Le modèle source, ayant sa propre copie des données, peut alors librement jouer, effectuer des éditions et des ajouts, et ne valider les données sur votre couche modèle que lorsque l'utilisateur valide ses modifications.

Si vous voulez un exemple PyQt d'une telle table, vous pouvez regarder la source d'un projet de la mine:

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

Vous pourriez avoir à fouiller pour trouver réellement la logique « tampon » parce que ce n'est pas dans le code de PyQt lui-même, mais plutôt la « cross-plateforme » partie du code:

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

Cette logique est alors utilisé dans mon sous-classe QAbstractItemModel:

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

2

D'une conception perspective, cela devrait faire partie de la vue, pas le modèle. Par conséquent, je suggère d'implémenter une vue avec la fonctionnalité et laisser le modèle inchangé. KOfficeKexi fait exactement cela avec kexitableview (screenshot, documentation). Peut-être que vous voulez utiliser une partie de leur code.

BTW, vous pourriez encore être en mesure d'utiliser votre hack et le combiner avec ma suggestion en le mettant dans une nouvelle vue de la table mise en œuvre YourTableView:

  1. QBlankRowModel re-implémente l'interface QAbstractTableModel . Il renvoie sourceModel.rowCount()+1 en tant que QBlankRowModel::rowCount(). Renvoie QVariant() si la n+1e ligne est demandée dans QBlankRowModel::data(). Tout le reste à l'intérieur de QBlankRowModel est transmis au sourceModel (avec montage la n+1 ième ligne dans QBlankRowModel tamponnée et remplacé par l'insertion, dans le sourceModel une fois terminé).

  2. La nouvelle YourTableView hérite de QTableView et enveloppe le sourceModel au sein YourTableView::setModel(), appelant QTableView::setModel(QBlankRowModel(sourceModel)).

Ainsi, votre hack est localisé en un point.

Questions connexes