IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

MyQItemDelegate::createEditor n'est jamais appelé


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Par défaut MyQItemDelegate::createEditor n'est jamais appelé
    Salut

    J'affiche des données dans une QTableView à laquelle j'ai associée un modèle.

    je voudrais maintenant lui associer un QItemDelegate pour modifier les valeurs d'une colonne en particulier
    j'ai donc défini ma classe FsComboDelegate héritant de QItemDelegate.
    Je l'ai associée à ma QTableView ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    this->_tableViewSignals->setModel(new MessageTableModel(this->_tableViewSignals, /*...*/));	
    this->_tableViewSignals->setItemDelegate(new FsComboDelegate(this->_tableViewSignals));
    Je colle un point d'arret sur les fonctions de MyQItemDelegate. Seule la méthode paint est appelée. Les autres ne sont jamais invoquées.

    A quoi ca peut être du?

    Merci d'avance

    les codes du model et du delegate:

    delegate :
    Code : 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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #include "fscombodelegate.h"
    #include <QComboBox>
    #include <QItemDelegate>
     
    FsComboDelegate::FsComboDelegate(QObject *parent)
    	: QItemDelegate(parent)
    {
     
    }
     
    FsComboDelegate::~FsComboDelegate()
    {
     
    }
    void FsComboDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
    							const QModelIndex &index) const{
    								QItemDelegate::paint(painter, option,index);
    }
     
     
     QWidget *FsComboDelegate::createEditor(QWidget *parent,
         const QStyleOptionViewItem &/* option */,
         const QModelIndex &/* index */) const
     {
         QComboBox *editor = new QComboBox(parent);
         editor->addItem("ND", (QVariant)0x00);
         editor->addItem("NO", (QVariant)0x03);
         editor->addItem("FT", (QVariant)0x0C);
         editor->addItem("NCD", (QVariant)0x30);
     
         return editor;
     }
     
     void FsComboDelegate::setEditorData(QWidget *editor,
                                         const QModelIndex &index) const
     {
    	 //if(index.column() == 5) {
    		 int value = index.model()->data(index, Qt::EditRole).toInt();
    	// }
     
    	 QComboBox *lComboBox = static_cast<QComboBox*>(editor);
     
         //TODO restore here
    	 //lComboBox->setValue(value);
     }
     
     
      void FsComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                        const QModelIndex &index) const
     {
         QComboBox *lComboBox = static_cast<QComboBox*>(editor);
         //lComboBox->interpretText();
    	 int value = lComboBox->currentText().toInt();
     
         model->setData(index, value, Qt::EditRole);
     }
     
     
      void FsComboDelegate::updateEditorGeometry(QWidget *editor,
         const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
     {
         editor->setGeometry(option.rect);
     }

    model
    Code : 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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    #include "MessageTableModel.h"
    #include <QtGui/QBrush>
     
    #include "hmi_facade.h"
     
    extern IcdGetBusListType IcdParserDllGetBusList;
    extern IcdParseType IcdParserDllParse;				
    extern IcdInitType IcdParserDllInit;		
    extern IcdGetBusNumberType IcdParserDllGetBusNumber;
    extern IcdGetSignalNumberOnBusType IcdParserDllGetSignalNumberOnbus;
    extern IcdGetSignalListType IcdParserDllGetSignalList;		
     
     
    MessageTableModel::MessageTableModel(QObject *parent, QString aVlName, int aPortId)
    {
    	_vlName = aVlName;
    	_portId = aPortId;
     
    	_nbSignals = IcdParserDllGetSignalNumberOnbus((char*)aVlName.toStdString().c_str(), aPortId);
    	if(_nbSignals > 0) {
     
    		_signals = new S_SignalDescription[_nbSignals];
     
    		IcdParserDllGetSignalList((char*)aVlName.toStdString().c_str(), aPortId, _signals);
    	} else {
    		_signals = NULL;
    		//TODO warn user in this case
    	}
     
    }
     
    MessageTableModel::~MessageTableModel()
    {
     
    }
     
     
     
    int	MessageTableModel::columnCount ( const QModelIndex & parent) const {
    	return 6;
    }
     
     
     
    QVariant MessageTableModel::headerData (int section, Qt::Orientation orientation, int role) const {
    	if (role == Qt::SizeHintRole) {
    			//The size hint for the item that will be supplied to views. (QSize) 
    		return QSize(10,20);
    	} 
    	else if(role == Qt::DisplayRole) {
    		if (orientation == Qt::Horizontal) {
    			switch (section) {
    				case 0:
    					return QString("Signal Name");
    				case 1:
    					return QString("Signal Type");
    				case 2:
    					return QString("Min value");
    				case 3:
    					return QString("Max value");
    				case 4:
    					return QString("Default Value");
    				case 5:
    					return QString("Default Validity");
    				default:
    					return QString("");
    			}//switch
    		}//horizontal
    		else {
    			return QVariant();
    		}
    	}
    	else {
    		return QVariant();
    	}
    }
     
     
     
    QVariant MessageTableModel::data ( const QModelIndex & index, int role ) const  {
    	if ((role == Qt::BackgroundRole)) {
    		QBrush lBrush;
    		lBrush.setColor(Qt::blue);
            return lBrush;
    	}
    	else if (role == Qt::DisplayRole) {
    		switch(index.column()) {
    			case 0 : //signal Name (icd input)
    				return (QVariant) QString(_signals[index.row()].Signalname);
    			case 1: //signal type (icd input)
    				return (QVariant) QString(_signals[index.row()].Signaltype);
    			case 2: //signal min value (icd input)
    				if (QString(_signals[index.row()].Signaltype).compare(QString("float"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString::number(_signals[index.row()].FloatOperationalmin);
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("integer"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString::number(_signals[index.row()].IntegerOperationalmin);
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("boolean"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString("false");
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("opaque"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString("N/A");
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("string"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString("N/A");
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("enumerate"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString("N/A");
    				}
    				else {
    					return QVariant();
    				}
    			case 3: //signal max value (icd input)
    						if (QString(_signals[index.row()].Signaltype).compare(QString("float"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString::number(_signals[index.row()].FloatOperationalmax);
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("integer"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString::number(_signals[index.row()].IntegerOperationalmax);
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("boolean"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString("true");
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("opaque"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString("N/A");
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("string"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString("N/A");
    				}
    				else if (QString(_signals[index.row()].Signaltype).compare(QString("enumerate"), Qt::CaseInsensitive) == 0){
    					return (QVariant) QString("N/A");
    				}
    				else {
    					return QVariant();
    				}
    			case 4: //signal default value (user input)
    				return (QVariant) "todod";
    			case 5: //validity default value (user input)
    				return QVariant();
    			default:
    				return (QVariant) "?";
    		}
    	}  
    	else if (role == Qt::DecorationRole) {
    		//The data to be rendered as a decoration in the form of an icon. (QColor, QIcon or QPixmap) 
    		return QVariant();
    	}
    	else if (role == Qt::FontRole){
    			//The font used for items rendered with the default delegate. (QFont)  
    		return QVariant();
    	}
    else if (role == Qt::TextAlignmentRole){
    			//The alignment of the text for items rendered with the default delegate. (Qt::AlignmentFlag)  
    		return QVariant();
    	}
    else if (role == Qt::ForegroundRole){
    			//The foreground brush (text color, typically) used for items rendered with the default delegate. (QBrush)  
    		return QVariant();
    	}
    else if (role == Qt::CheckStateRole){
    			//This role is used to obtain the checked state of an item. (Qt::CheckState)  
    	return QVariant();
    	}
     
    return QVariant();
     
    }
     
     
    QModelIndex	MessageTableModel::index ( int row, int column, const QModelIndex & parent ) const  {
     
    	return createIndex(row, column);
    }
     
    QModelIndex	MessageTableModel::parent ( const QModelIndex & index ) const  {
    	QModelIndex lOut;
    	return lOut;
    }
     
    int	MessageTableModel::rowCount ( const QModelIndex & parent) const  {
    	return _nbSignals;
    }

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour traiangueul

    J'ai testé ta classe FsComboDelegate, elle fonctionne correctement et toute les fonctions sont appelées (paint lors du démarrage et les autres lors d'un double clic sur une cellule). J'ai bien une liste de choix qui s'affiche avec les 4 choix (ND, NO, FT, NCD)

    Quelques remarques :

    - il est préférable d'utiliser QStyledItemDelegate au lieu de QItemDelegate (cf QStyledItemDelegate vs. QItemDelegate)

    - dans setModelData, le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int value = lComboBox->currentText().toInt();
    ne retourne pas l'index de la sélection dans la liste mais essaie de convertir le texte (par exemple "ND") en nombre, ce qui retourne tout le temps 0

    PS : ubuntu 10.10 64b, Qt 4.7.0
    J'ai testé avec la vue suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    MainWindow::MainWindow(QWidget *parent)
        : QTableView(parent)
    {
        QStandardItemModel* model = new QStandardItemModel(this);
        model->setHorizontalHeaderLabels(QStringList() << "toto1" << "toto2" << "toto3");
        for (int i=0; i<12; ++i)
        {
            QList<QStandardItem*> list;
            for (int j=0; j<3; ++j)
                list << new QStandardItem(QString("value_%1_%2").arg(i).arg(j));
            model->appendRow(list);
        }
        setModel(model);
        setItemDelegate(new FsComboDelegate(this));
    }

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Par défaut
    arf

    En effet le deleguate semble bien fonctionner (hormis la remarque que tu as faite). En tous cas, toutes les fonctions sont bien appelées lorsque je double clique.

    J'ai réutilisé ton exemple de modèle pour m'en rendre compte.


    En revanche, impossible d'y parvenir avec mon propre modèle.
    Est ce que j'y ferais qq chose qui est incompatible avec l'utilisation des deleguate? ou ai-je oublié d’implémenter qq chose? Des rôles mal gérés dans les différentes fonctions du modèle?

    PS: Quant à moi je suis en Qt 4.6

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    J'ai voulu implémenter ton code pour le tester mais il y a un problème

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MessageTableModel::MessageTableModel(
          QObject *parent, QString aVlName, int aPortId)
    {
       ...
    Je suppose que MessageTableModel hérite de QAbstractItemModel (ou une classe dérivée) pour pouvoir compiler mais tu n'appelles pas le constructeur du parent.

    Une erreur ou un oubli ?

    EDIT : au fait, pour appliquer un delegate sur une colonne en particulier, tu peux utiliser setItemDelegateForColumn

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Par défaut
    bien vu.
    C'est effectivement un oubli

    Malheureusement, ca ne résout pas mon problème.

    J'ai pourtant mis les editTriggers de ma tableView à AllEditTriggers mais ca fait comme ci, je ne passais jamais dans le mode d'edition de mes cellules.


    Désespérant cette histoire!

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 98
    Par défaut


    Bon bah!!
    C'est comme le port salut; c'est marqué dessus:


    QAbstractTableModel Class Reference
    (...)
    Subclassing

    When subclassing QAbstractTableModel, you must implement rowCount(), columnCount(), and data(). Default implementations of the index() and parent() functions are provided by QAbstractTableModel. Well behaved models will also implement headerData().

    Editable models need to implement setData(), and implement flags() to return a value containing Qt::ItemIsEditable.

    puis
    Qt::ItemFlags QAbstractItemModel::flags ( const QModelIndex & index ) const [virtual]
    Returns the item flags for the given index.

    The base class implementation returns a combination of flags that enables the item (ItemIsEnabled) and allows it to be selected (ItemIsSelectable).
    Par défaut l'édition n'est pas autorisée.

    modification apportée pour autoriser l'edition sur les cellules qui m'interressent.
    Dorénavant, ca marche. Cool


    Merci gbdivers pour ton aide!

  7. #7
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour traiangueul

    Je n'ai pas regardé le reste, en attendant la réponse au problème d'héritage (j'ai vu après coup que tu utilisais la fonction setHorizontalHeaderLabels donc tu hérites de la classe QStandardItemModel). Comme tu utilises des fonctions d'un lib externe, je dois modifier le code et je préférer attendre pour savoir.

    Quelques remarques (tapée en même temps que je modifie ton code pour qu'il fonctionne chez moi) :

    - tes variables membres (_vlName et _portId) ne sont pas utilisées dans le reste de ta classe. Oubli ? Code modifier pour montrer l'essentiel ?

    - tu utilises un tableau dynamique pour stocker la liste des tes signaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _signals = new S_SignalDescription[_nbSignals];
    En plus, tu n'appelles pas delete[] dans le destructeur (ou tu n'a pas fournit le code du destructeur)

    Utilise plutôt un conteneur : std::vector, QVector, QList, etc.

    - A la place de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (char*)aVlName.toStdString().c_str()
    tu peux utiliser qPrintable :

    J'ai ajouté une structure S_SignalDescription pour tester ton modèle, que je remplis à la main :

    Code : 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
    struct S_SignalDescription
    {
        S_SignalDescription() {}
        S_SignalDescription(QString name, QString type, float min)
            : Signalname(name),
            Signaltype(type),
            FloatOperationalmin(min)
        {}
     
        QString Signalname;
        QString Signaltype;
        float FloatOperationalmin;
        int IntegerOperationalmin;
        float FloatOperationalmax;
        int IntegerOperationalmax;
    };
     
    MessageTableModel::MessageTableModel(QObject *parent, QString aVlName, int aPortId) :
            QStandardItemModel(parent)
    {
        for (int i=0; i<5; ++i)
        {
            _signals.append(S_SignalDescription(
                QString("name %1").arg(i),
                QString("integer"),
                1.0 * i));
        }
    }
    Et le modèle fonctionne : je vois une table avec 6 colonnes et 5 lignes, avec les infos que je donne et quand je double clic, j'ai la liste de choix. Par contre, je n'ai pas l'impression que ton modèle soit éditable (regarde du côté des rôles ou des flags)

    Pur finir, dans headerData, tu ne définis par Qt::Vertical donc les en-tête verticaux sont vides. Il vaut mieux écrire quelques chose (l'index de la ligne ?) ou ne pas les afficher.

    Sinon, ajouter des qDebug() pour visualiser les données entrée dans ton modèle.

    Bon courage

    EDIT : arf, tu as résolu ton problème pendant que j'éditais le mien

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 04/11/2009, 10h57
  2. [EasyMock] Vérifier qu'une méthode n'est jamais appelée
    Par proner dans le forum Tests et Performance
    Réponses: 1
    Dernier message: 26/03/2009, 17h13
  3. Spécialisation template qui n'est jamais appelée
    Par coyotte507 dans le forum Langage
    Réponses: 4
    Dernier message: 02/05/2008, 12h39
  4. [ Struts ] Erreur : l'action n'est jamais appelé
    Par romain3395 dans le forum Struts 1
    Réponses: 3
    Dernier message: 25/06/2004, 14h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo