2009-05-12 7 views
3

私はモデル/ビュー/コントローラのパラダイムに従った。モデルとビューが正しいとはかなり確信していますが、私はデリゲートでいくつかのことを間違っていると思います。コントロールを最初にクリックしただけでコントロールを点灯させ、2番目のコントロールをクリックするだけで、すべてが機能します。これは代表者が通常実装される方法ですか?私の実装は多くの構築と破壊(scoped_ptrによって隠されている)を必要とするので、それに関するヒントも役立ちます。Qtでは、どのようにしてデリゲートを適切に実装しますか?

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

おそらくModel-View-Controllerを意味します。モデル/ビュー/デリゲートのパラダイムというものはありません。 – shoosh

+0

固定.......... –

答えて

4

カスタムエディタが表示される条件の変更については、QAbstractItemView::setEditTriggers()を使用してください。デリゲートは、カスタムエディタとの間で情報をやり取りする責任がありますが、ビューはエディタの起動時期を決定します。

ドキュメントリファレンス:http://doc.qt.digia.com/4.5/qabstractitemview.html#editTriggers-prop

+0

私はそれを試みましたが、最初のクリックの編集トリガはありません。 SelectedClickedとDoubleClickedだけがあるので、私はeditorEventを使って最初のクリックで編集を強制すると思いました。進入禁止? –

+1

CurrentChangedを試してください。これは、セルの選択が変更されたときに編集を開始します。 – swongu

+0

うわー、選択が無効になっていても動作します。素晴らしいです、それは、editorEventメソッドを取り除きます。上記のコードでも削除します。 –