第61课 模型视图中的委托(上)

1. Qt模型视图对用户输入的处理

(1)传统的MVC设计模式

(2)Qt中的模型视图设计模式如何处理用户输入?

  ①视图中集成了处理用户输入的功能(即委托)

  ②视图将用户输入作为内部独立的子功能来实现

  ③模型负责组织数据视图负责显示数据委托则用于编辑修改数据

2. 模型视图中的委托

(1)委托(Delegate)是视图中处理用户输入的部件(如编辑框、单选按钮等)

(2)视图可以设置委托对象用于处理用户输入

(3)委托对象负责创建和显示用户输入的上下文(内容),如编辑框的创建和显示。

(4)委托类的继承图

3. 委托中的编辑器

(1)委托能够提供编辑时需要的上下文环境(编辑器)

(2)不同委托提供的编辑器类型不同(如文本框、单选框等)

(3)编辑器从模型获取数据,并将编辑结果返回模型

(4)委托中的关键函数

  ①createEditor:需要编辑数据时,创建编辑器组件

  ②updateEditorGeometry:更新编辑器组件的大小

  ③setEditorData:通过索引从模型中获取数据,并将数据显示到编辑器中

  ④setModelData:编辑后的新数据写入模型

(5)委托中的关键信号

  ①void closeEditor(QWidget* editor):编辑器组件关闭信号

  ②void commitData(QWidget* editor):新数据提交信号

【编程实验】视图中的委托以及委托的关键函数与信号

//main.cpp

#include "Widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

//Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <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_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.setModel(&m_model);
    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() << "Current View Delegate: " << m_view.itemDelegate();
}

Widget::~Widget()
{

}

//SubStyleItemDelegate.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

//SubStyleItemDelegate.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";
    return 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)
{
    Q_UNUSED(editor);
    qDebug() <<"SubStyledItemDelegate::onCloseEditor" ;
}

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

输出结果:

/*
SubStyledItemDelegate::createEditor
SubStyledItemDelegate::updateEditorGeometry
SubStyledItemDelegate::setEditorData
SubStyledItemDelegate::onCommitData
SubStyledItemDelegate::setModelData
SubStyledItemDelegate::setEditorData
SubStyledItemDelegate::onCloseEditor
Model Data:
Row: 0
"A"
"C"

Row: 1
"C"
"D"

Current View Delegate:  SubStyledItemDelegate(0x23fe40)
*/

4. 小结

(1)委托(Delegate)是视图中处理用户输入的部件

(2)视图可以设置委托对象,用于处理用户输入

(3)委托能够提供编辑时需要的上下文环境(编辑器)

(4)不同委托提供的编辑器类型不同(文本框、单选框等)

(5)编辑器从模型中获取数据,并将编辑结果返回模型

时间: 2024-12-11 13:22:37

第61课 模型视图中的委托(上)的相关文章

第62课 模型视图中的委托(下)

1. 委托的本质 (1)为视图提供数据编辑的上下文环境 (2)产生界面元素的工厂类 (3)能够使用和设置模型中的数据 2. 自定义委托类 (1)自定义委托类的继承关系 (2)自定义委托时需要重写的函数 ①createEditor ②updateEditorGeometry ③setEditorData ④setModelData ⑤paint(可选) (3)自定义委托时重写的函数由谁调用? 由于模型视图设计模式,视图中组合了委托对象,既然委托存在于视图内部,就应该由视图来调用(可从上图的函数调用

Qt模型/视图中的data和headerData

QAbstractItemModel QAbstractItemModel是一个抽象类,该抽象类未实现的纯虚方法有 QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex & parent = QModelIndex()) const [pure virtual] QModelIndex QAbstractItemModel::parent(const QModelIndex & index)

第55课 模型视图设计模式

1. 模型视图模式 (1)模型视图设计模式的核心思想 ①模型(数据)与视图(显示)相分离 ②模型对外提供标准接口存取数据(不关心数据如何显示) ③视图自定义数据的显示方式(不关心数据如何组织存储) (2)模型视图模式的直观理解 (3)模型视图模式的工作机制 ①当数据发生改变时,模型发出信号通知视图 ②当用户与视图进行交互时,视图发出信号提供交互信息 2. Qt中的模型-视图类层次结构 (1)Qt中的模型类的层次结构 (2)Qt中的视图类的层次结构 3. 关键技术问题 (1)模型如何为数据提供统一

第57课 模型视图设计模式(下)

1. Qt中标准模型定义 (1)预期的模型逻辑结构 (2)代码实现 //main.cpp #include "Widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); } //Widget.h #ifndef WIDGET_H #define WIDGET_H #in

eclipse 在Navigator视图中查看资源

随着不断使用Eclipse,Navigator视图中的实体数目会增加.通过在某一项目或文件夹上右击,并在所出现的快捷菜单中选择Go Into命令,你就可以查看该项目或文件夹中的资源了.此时Navigator视图目录将被所选择的项目或文件夹中的资源目录所代替.点击Navigator视图中的Up后,项目或文件夹的资源目录又将被Navigator视图目录所代替.而Forward和Back的功能和Web浏览器中的前进和后退图标的功能相同. 点击Navigator视图中标题栏上的下拉菜单,并在所出现的下拉

QML中的模型/视图 十二

QML中对于数据的存储和显示使用模型/视图框架. 1. QML数据模型 视图项目(如ListView.GridView和Repeater等)需要使用数据模型来为其提供数据进行显示.这些项目通常也需要一个委托(delegate)组件来为模型中的每一个条目创建一个实例.模型可以是静态的,也可以进行动态的修改.插入.移除或者移动项目.Qt帮助参考QML Data Models关键字. Item{ width:200; height:250 ListModel{ id:myModel ListEleme

【GISER&amp;&amp;Painter】Chapter02:WebGL中的模型视图变换

上一节我们提到了如何在一张画布上画一个简单几何图形,通过创建画布,获取WebGLRendering上下文,创建一个简单的着色器,然后将一些顶点数据绑定到gl的Buffer中,最后通过绑定buffer数据,提供buffer中顶点数据的情况,执行渲染绘制方法,将数据结果从buffer中刷新到帧缓存中.整个流程十分清晰明了,可是通过对比原来OpenGL中的整个流程,我们会发现其中还缺少了一些很重要的处理步骤,虽然我们创建了属于自己的着色器,可并没有对顶点数据进行类似于顶点处理管线中的模型视图变换.透视

Uploadify在MVC中使用方法案例(一个视图多次上传单张图片)

Controller 中代码和 上一节文章(http://www.cnblogs.com/yechangzhong-826217795/p/3785842.html )一样 视图中代码如下: <script type="text/javascript"> $(function () { $(".uploadpic").each(function (i) { $('#uploadify' + i).uploadify({ 'buttonText': '上传

知识点3-5:在视图中显示视图模型数据

通常为了在视图中显示信息,可能会使用HtmlHelper(HTML辅助器)对象,以协助获取视图模型来生成HTML.考虑以下清单,它渲染完整的留言本条目. 在这个留言本条目详情屏幕中,我们显示了在模型中传递的留言本详细信息.接下来,用Razor的多行代码语句,以接受ViewData中的“hasPermission”值.Razor的多行代码语句是一个@{}代码块.最后,使用了一个Razor的if语句,有条件地显示编辑链接. 在登录页面中,我们使用了一个视图模型对象来表示整个表单,如清单3.6所示.