Bonjour,
J'ai une table, avec des cases texte éditables. Je veux que la première colonne ne comporte que des noms uniques. Donc lorsque l'on modifie une case de cette colonne, je veux que la modification ne soit acceptée que si ce texte est unique sur la colonne.
Premier problème : intercepter l'édition
Pour ça, le mieux que j'ai trouvé c'est :
Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 class MaTable : public QTableWidget { Q_OBJECT public: MaTable ( QWidget * parent = 0 ); ~MaTable(); private: bool commitOk; void commitData ( QWidget * editor ); void closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint ); }; MaTable::MaTable ( QWidget * parent ) : QTableWidget ( parent ) { } MaTable::~MaTable() { } void MaTable::commitData ( QWidget * editor ) { QSet<QString> premiereColonne; for ( int i = 0; i < rowCount(); i++ ) { premiereColonne << item ( i, 0 )->text().trimmed(); } QLineEdit* leEditor = qobject_cast<QLineEdit*> ( editor ); if ( premiereColonne.contains ( leEditor->text().trimmed() ) ) { commitOk = false; QMessageBox::critical ( this, "Erreur", "Cette donnée doit être unique, mais elle existe déjà." ); leEditor->setFocus(); leEditor->selectAll(); } else { commitOk = true; QTableWidget::commitData ( editor ); } } void closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint ) { if ( commitOk ) { QTableWidget::closeEditor ( editor, hint ); } }
J'ai choisi en cas de souci d'afficher une popup d'erreur, et de laisser le champ éditable, avec le texte sélectionné. Ça me semble pas mal comme comportement. L'avantage de redéfinir commitData(), c'est que je peux rester au texte d'avant en n'acceptant pas le commit.
Bon ça marchouille à quelques détails-près : commitData() est déclenchée deux fois (pour la case de droite aussi)... Et aussi un deuxième gros problème :
Deuxième problème : ne traiter que les éléments de la première colonne
Et oui, en passant dans commitData(), je n'ai qu'un pauvre QWidget*, et le souci c'est de trouver à quelle case il correspond pour savoir si je dois le traiter ou non ! J'ai vu que createEditor() semble être le seul endroit où on peut faire le lien entre une case (QModelIndex) et un editor. J'ai voulu redéfinir QStyledItemDelegate pour "sauvegarder" l'editor et avoir une méthode pour le récupérer, mais il n'y a qu'un seul objet delegate de créé pour toutes les cases... Vous n'auriez pas une bonne idée ? Ou un autre chemin à prendre pour faire la même chose ?
Je ne comprends pas qu'on n'ait pas une méthode editor(index) disponible, alors que dans les sources de Qt il y en a une d'utilisée en private. Ce serait utile je pense.
Partager