2009-05-12 6 views
3

J'ai suivi le paradigme modèle/vue/contrôleur. Je suis assez sûr que le modèle et la vue sont bons, mais je pense que je fais des choses mal dans mon délégué. Tout "fonctionne", sauf le premier clic sur un contrôle "allume le contrôle" et le second interagit avec lui. Est-ce ainsi que les délégués sont généralement mis en œuvre? Ma mise en œuvre nécessite beaucoup de construction et de destruction (caché par scoped_ptr) donc toutes les astuces sont utiles.En Qt, comment implémentez-vous correctement les délégués?

QWidget *ParmDelegate::createWidget(const QModelIndex &index) const { 
    if (!index.isValid()) 
     return NULL; 
    const Parm *p = static_cast<const Parm*>(index.internalPointer()); 
    QWidget *w = p->createControl(); 
    w->setAutoFillBackground(true); 
    w->setBackgroundRole(QPalette::Base); // white background instead of grey 
    return w; 
} 

QWidget* 
ParmDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { 
    QWidget *retval = createWidget(index); 
    if (dynamic_cast<QComboBox*>(retval)) 
     connect(retval, SIGNAL(activated(int)), this, SLOT(commitAndCloseEditor())); 
    else if (dynamic_cast<QSlider*>(retval)) 
     connect(retval, SIGNAL(sliderReleased()), this, SLOT(commitAndCloseEditor())); 
    else if (dynamic_cast<QAbstractButton*>(retval)) 
     connect(retval, SIGNAL(clicked()), this, SLOT(commitAndCloseEditor())); 
    else 
     connect(retval, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); 
    retval->setFocusPolicy(Qt::StrongFocus); 
    retval->setParent(parent); 
    return retval; 
} 

void 
ParmDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { 
    const Parm *p = static_cast<const Parm*>(index.internalPointer()); 
    p->setEditorData(editor); 
} 

void 
ParmDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { 
    ParmControl::Base* base = dynamic_cast<ParmControl::Base*>(editor); 
    model->setData(index, base->toQVariant()); 
} 

void 
ParmDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { 
    editor->setGeometry(option.rect); 
} 

void 
ParmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { 
    scoped_ptr<QWidget> w(createWidget(index)); 
    if (!w) 
     return; 
    const Parm *p = static_cast<const Parm*>(index.internalPointer()); 
    setEditorData(w.get(), index); 
    w->setGeometry(option.rect); 
    w->render(painter, option.rect.topLeft()); 
} 

QSize 
ParmDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { 
    scoped_ptr<QWidget> w(createWidget(index)); 
    if (!w) 
     return QSize(0,0); 
    return w->sizeHint(); 
} 

void 
ParmDelegate::commitAndCloseEditor() { 
    QWidget *editor = static_cast<QWidget *>(sender()); 
    ParmControl::Base* base = dynamic_cast<ParmControl::Base*>(editor); 
    emit commitData(editor); 
    emit closeEditor(editor, QAbstractItemDelegate::EditNextItem); 
} 
+0

vous voulez probablement dire Model-View-Controller. il n'y a pas de paradigme modèle/vue/délégué. – shoosh

+0

Correction .......... –

Répondre

4

Si vous êtes intéressé à changer les conditions que votre éditeur personnalisé est affiché, utilisez QAbstractItemView::setEditTriggers(). Bien que votre délégué soit responsable de la transmission des informations depuis et vers l'éditeur personnalisé, la vue détermine quand l'éditeur est lancé.

Référence de la documentation: http://doc.qt.digia.com/4.5/qabstractitemview.html#editTriggers-prop.

+0

J'ai essayé, mais il n'y a pas de déclencheur d'édition pour le premier clic. Il n'y a que SelectedClicked et DoubleClicked, j'ai donc décidé de forcer l'édition au premier clic en utilisant editorEvent. Fausse route? –

+1

Essayez CurrentChanged. Cela commencera à être modifié lorsque la sélection de cellule changera. – swongu

+0

Wow, ça marche même si la sélection est désactivée. Génial, cela supprime la méthode editorEvent. Je vais le supprimer dans le code ci-dessus aussi. –

Questions connexes