Précédent   Forum des professionnels en informatique > C et C++ > Bibliothèques > Qt
Qt Forum d'entraide technique sur la bibliothèque Qt. Avant de poster -> F.A.Q Qt
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/12/2011, 20h44   #1
Modérateur
 
Homme
Ingénieur développement logiciels
Inscription : mai 2009
Messages : 572
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 23
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mai 2009
Messages : 572
Points : 914
Points : 914
Par défaut Contrôle de l'édition d'un QTableWidget sur une colonne

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++ :
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.
Troudhyl est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/12/2011, 10h53   #2
Modérateur
 
Homme
Ingénieur développement logiciels
Inscription : mai 2009
Messages : 572
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 23
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mai 2009
Messages : 572
Points : 914
Points : 914
Pas de réponse... Bon en attendant, je vais juste désactiver la possibilité d'éditer ma colonne. J'ai cherché encore, en mettant un delegate particulier à la colonne, mais même, je n'arrive pas à faire un lien avec l'editor.
Troudhyl est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/12/2011, 21h06   #3
Responsable 2D/3D/Jeux

 
Avatar de LittleWhite
 
Homme Alexandre Laurent
Étudiant
Inscription : mai 2008
Messages : 6 560
Détails du profil
Informations personnelles :
Nom : Homme Alexandre Laurent
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mai 2008
Messages : 6 560
Points : 14 057
Points : 14 057
Bonjour,

Pour détecter le changement de votre première colonne, il faut connecter un slot à ce signal itemChanged().
Comme le slot devra accepter un QTableWidgetItem vous aurez à disposition toutes les informations nécessaires, tel que le numéro de la colonne et ainsi vous pouvez faire un test simple pour savoir si on parle bien de la première colonne.
__________________
Vous souhaitez participer à la section Jeux ? Contactez-moi
La rubrique a aussi un blog !

Ma page sur DVP
Mon Portfolio

Qui connaît l'erreur, connaît la solution.
LittleWhite est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2011, 00h20   #4
Modérateur
 
Homme
Ingénieur développement logiciels
Inscription : mai 2009
Messages : 572
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 23
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mai 2009
Messages : 572
Points : 914
Points : 914
Lorsque ce signal arrive, c'est déjà trop tard, l'item a été édité. Avec commitData(), tant que je n'appelle pas QTableWidget::commitData ( editor ), l'item n'est pas modifié, donc si l'utilisateur ferme l'application, les données seront sauvegardées sans erreur (recopie du tableau dans un fichier, dans le destructeur). Après s'il n'y a que ça à faire... Je reste sur mon interdiction d'édition de cette colonne. Mais je trouve vraiment cette histoire de QWidget * editor mal foutue...
Troudhyl est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/12/2011, 20h29   #5
Responsable 2D/3D/Jeux

 
Avatar de LittleWhite
 
Homme Alexandre Laurent
Étudiant
Inscription : mai 2008
Messages : 6 560
Détails du profil
Informations personnelles :
Nom : Homme Alexandre Laurent
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mai 2008
Messages : 6 560
Points : 14 057
Points : 14 057
Il est changé dans la vue, mais pas dans le modèle, si ?
__________________
Vous souhaitez participer à la section Jeux ? Contactez-moi
La rubrique a aussi un blog !

Ma page sur DVP
Mon Portfolio

Qui connaît l'erreur, connaît la solution.
LittleWhite est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h38.


 
 
 
 
Partenaires

Hébergement Web