c++ - 在 Qt 中,如何正确实现委托(delegate)?

标签 c++ qt qt4

我遵循模型/ View / Controller 范式。我很确定模型和 View 是正确的,但我认为我在委托(delegate)中做错了一些事情。一切都“有效”,除了第一次单击控件只是“点亮控件”并且第二次单击控件与之交互。这就是委托(delegate)的通常执行方式吗?我的实现需要大量的构造和破坏(隐藏在 scoped_ptr 中),因此任何相关提示也很有帮助。

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);
}

最佳答案

如果您有兴趣更改显示自定义编辑器的条件,请使用 QAbstractItemView::setEditTriggers()。虽然您的委托(delegate)负责将信息传入和传出自定义编辑器,但 View 决定编辑器何时启动。

文档引用:http://doc.qt.digia.com/4.5/qabstractitemview.html#editTriggers-prop .

关于c++ - 在 Qt 中,如何正确实现委托(delegate)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/851031/

相关文章:

c++ - 如何使用 Nsight 调试 (GLSL) 着色器?

c++ - 如何向 QFileSystemModel 添加自定义角色

image - 设置从磁盘加载的背景图像

c++ - Windows 消息循环而不是 QApplication::exec()/QApplication::processEvents()

c++ - QT 将文本翻译成特定的语言环境

c++ - 在派生类中实现插槽 - qt4/c++

c++ - unordered_set 非 const 迭代器

qt - 在Mac中安装QJson

c++ - 使用不同的源文件操作 QT Ui

c++ - 如何在 Google Test 中使用不同模板测试多个模板化类的相同行为?