Qt模型视图中的委托

1 初探QT模型视图中的委托

首先来看一个问题:模型负责组织数据,视图负责显示数据,如何编辑数据呢?

我们先来看一下传统的MVC设计模式:
在这里插入图片描述
Qt中的模型视图设计模型如何处理用户输入呢?

  • 视图中集成了处理用户输入的功能。
  • 视图将用户输入作为内部独立的子功能而实现。

在这里插入图片描述
模型视图中的委托:

  • 委托(Delegate)是视图中处理用户输入的部件。
  • 视图可以设置委托对象用于处理用户输入。
  • 委托对象负责创建和显示用户输入上下文。
    • 如:编辑框的创建和显示。
      在这里插入图片描述

委托中的编辑器:

  • 委托能够提供编辑时需要的上下文环境(编辑器)。
  • 不同委托提供的编辑器类型不同(文本框、单选框,等)。
  • 编辑器从模型获取数据,并将编辑结果返回模型。

在这里插入图片描述
委托中的关键函数:

  • createEditor:需要编辑数据时,创建编辑器组件。
  • updateEditorGeometry:更新编辑器组件的大小。
  • setEditorData:通过索引从模型中获取数据。
  • setModelData:将编辑后的新数据返回模型。

委托中的关键信号:

  • void closeEditor(QWidget* editor):编辑器组件关闭信号。
  • void commitData(QWidget* editor):新数据提交信号。

对模型中的委托进行一下简单的总结:

  • 委托是视图中处理用户输入的部件。
  • 视图可以设置委托对象用于处理用户输入。
  • 委托能够提供编辑时需要的上下文环境(编辑器)。
  • 不同委托提供的编辑器类型不同(文本框、单选框等)。
  • 编辑器从模型中获取数据,并将编辑结果返回模型。

如下为测试代码:

SubStyledItemDelegate.h:

#ifndef SUBSTYLEDITEMDELEGATE_H
#define SUBSTYLEDITEMDELEGATE_H

#include <QStyledItemDelegate>

class SubStyledItemDelegate : public QStyledItemDelegate
{
   
   
    Q_OBJECT
protected slots:
    void onCloseEditor(QWidget* editor);
    void onCommitData(QWidget* editor);
public:
    explicit SubStyledItemDelegate(QObject* parent = 0);
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
};

#endif // SUBSTYLEDITEMDELEGATE_H

SubStyledItemDelegate.cpp:

#include "SubStyledItemDelegate.h"
#include <QDebug>

SubStyledItemDelegate::SubStyledItemDelegate(QObject *parent) :
    QStyledItemDelegate(parent)
{
   
   
    connect(this, SIGNAL(closeEditor(QWidget*)), this, SLOT(onCloseEditor(QWidget*)));
    connect(this, SIGNAL(commitData(QWidget*)), this, SLOT(onCommitData(QWidget*)));
}

QWidget* SubStyledItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   
   
    qDebug() << "SubStyledItemDelegate::createEditor";

    return QStyledItemDelegate::createEditor(parent, option, index);
}

void SubStyledItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   
   
    qDebug() << "SubStyledItemDelegate::updateEditorGeometry";

    QStyledItemDelegate::updateEditorGeometry(editor, option, index);
}

void SubStyledItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
   
   
    qDebug() << "SubStyledItemDelegate::setEditorData";

    QStyledItemDelegate::setEditorData(editor, index);
}

void SubStyledItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
   
   
    qDebug() << "SubStyledItemDelegate::setModelData";

    return QStyledItemDelegate::setModelData(editor, model, index);
}

void SubStyledItemDelegate::onCloseEditor(QWidget* editor)
{
   
   
    qDebug() << "SubStyledItemDelegate::onCloseEditor";
}

void SubStyledItemDelegate::onCommitData(QWidget* editor)
{
   
   
    qDebug() << "SubStyledItemDelegate::onCommitData";
}

Widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QtGui/QWidget>
#include <QTableView>
#include <QStandardItemModel>
#include <QPushButton>
#include "SubStyledItemDelegate.h"

class Widget : public QWidget
{
   
   
    Q_OBJECT
    
    QTableView m_view;
    QStandardItemModel m_model;
    QPushButton m_testBtn;
    SubStyledItemDelegate m_delegate;

    void initView();
    void initModel();

private slots:
    void onTestBtnClicked();
public:
    Widget(QWidget* parent = 0);
    ~Widget();
};

#endif // WIDGET_H

Widget.cpp:

#include "Widget.h"
#include <QModelIndex>
#include <QDebug>

Widget::Widget(QWidget* parent) : QWidget(parent)
{
   
   
    initView();
    initModel();

    m_view.setModel(&m_model);

    m_testBtn.setParent(this);
    m_testBtn.move(10, 120);
    m_testBtn.resize(300, 30);
    m_testBtn.setText("Test");

    connect(&m_testBtn, SIGNAL(clicked()), this, SLOT(onTestBtnClicked()));
}

void Widget::initView()
{
   
   
    m_view.setParent(this);
    m_view.move(10, 10);
    m_view.resize(300, 100);
    m_view.setItemDelegate(&m_delegate);
}

void Widget::initModel()
{
   
   
    QStandardItem* root = m_model.invisibleRootItem();
    QStandardItem* itemA = new QStandardItem();
    QStandardItem* itemB = new QStandardItem();
    QStandardItem* itemC = new QStandardItem();
    QStandardItem* itemD = new QStandardItem();

    itemA->setData("A", Qt::DisplayRole);
    itemB->setData("B", Qt::DisplayRole);
    itemC->setData("C", Qt::DisplayRole);
    itemD->setData("D", Qt::DisplayRole);

    root->setChild(0, 0, itemA);
    root->setChild(0, 1, itemB);
    root->setChild(1, 0, itemC);
    root->setChild(1, 1, itemD);
}

void Widget::onTestBtnClicked()
{
   
   
    qDebug() << "Model Data:";

    for(int i=0; i<m_model.rowCount(); i++)
    {
   
   
        qDebug() << "Row: " << i;
        for(int j=0; j<m_model.columnCount(); j++)
        {
   
   
            QModelIndex index = m_model.index(i, j, QModelIndex());
            QString text = index.data(Qt::DisplayRole).toString();

            qDebug() << text;
        }
        qDebug() << endl;
    }

    qDebug() << "
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值