这是Model/View中的最后一篇了,Qt官方显然弱化了Controller在MVC中的作用,提供了一个简化版的Delegate;甚至在Model/View框架的使用中,提供了默认的委托,让这个控制器愈加淡出开发者的实现。

实际上,Qt Model/View框架中的MVC概念是有误的,显而易见的就是Controller的作用,控制器应该只对交互进行控制,渲染方面的工作应该仅由View完成,但Delegate的接口中却包含了这一块。不过这都不是这篇文章的重点,我们只关注Delegate本身。

1. 实现一个自定义Delegate

这里我们也来实现一个自定义Delegate,怀着了解Delegate的目的,主要实现以下几个功能:

  1. 以不同颜色绘制View。
  2. 双击View方格区域弹出行编辑器,默认覆盖这个区域,显示字母。
  3. 输入行编辑器内的内容会被保存,下次点开显示。
  4. 鼠标停留,显示提示框。

2. 继承QAbstractItemDelegate

Qt提供了几个标准的委托:

  1. QItemDelegate:Qt**曾经**默认使用的委托。
  2. QStyledItemDelegate。:**现在**默认使用的委托,官方推荐我们使用这个。(自从Qt 4.4)

为了熟悉委托借口,我们继承虚基类QAbstractItemDelegate来实现我们的自定义委托。

3. 实现虚函数

出去虚析构函数,QAbstractItemDelegate总共有9个虚函数,下面分别介绍。

paint()函数用来重绘view。我们这里选择用随机颜色填充背景:

void CustomeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid() || option.state == QStyle::State_None || !index.isValid())
return; painter->fillRect(option.rect, QColor(m_randomColor(m_generator)));
}

createEditor()destroyEditor()的用途非常明显,双击View的时候会弹出一个行编辑器:

QWidget* CustomeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return new QLineEdit(parent);
} void CustomeDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const
{
Q_ASSERT(dynamic_cast<QLineEdit*>(editor) != 0); delete dynamic_cast<QLineEdit*>(editor);
}

helpEvent()表示帮助事件,当发生QEvent::ToolTip或者QEvent::WhatsThis事件的时候,就会调用这个函数,我们这里根据事件不同显示不同内容的Tool Tip:

bool CustomeDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
{
if (event->type() == QEvent::ToolTip) {
QToolTip::showText(QCursor::pos(), QString("CustomeDelegate Tooltip"), reinterpret_cast<QWidget*>(view), option.rect, 1000);
} else if (event->type() == QEvent::WhatsThis) {
QToolTip::showText(QCursor::pos(), QString("CustomeDelegate Whatsthis"), reinterpret_cast<QWidget*>(view), option.rect, 1000);
}
return true;
}

当Editor显示的时候,会调用setEditorData()这个函数来显示默认的文字:

void CustomeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
dynamic_cast<QLineEdit*>(editor)->setText(index.data(Qt::DisplayRole).toString());
}

setModelData()这个函数用来更新Model中的数据:

void CustomeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
model->setData(index, dynamic_cast<QLineEdit*>(editor)->text(), Qt::DisplayRole);
}

updateEditorGeometry()这个函数也会在Editor显示的时候被调用,双击不同方格时,我们用它来更新编辑器的位置和大小:

void CustomeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
dynamic_cast<QLineEdit*>(editor)->setFixedSize(option.rect.width(), option.rect.height());
dynamic_cast<QLineEdit*>(editor)->move(option.rect.topLeft());
}

4. 运行结果

完整代码见此处

Qt--自定义Delegate的更多相关文章

  1. paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制

    源地址:http://blog.csdn.net/attilax/article/details/12343625 paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制 效果图: ...

  2. QSet使用及Qt自定义类型使用QHash等算法

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSet使用及Qt自定义类型使用QHash等算法     本文地址:http://techie ...

  3. Qt自定义插件编程小结

    qt自定义组件开发步骤演示.以下所有步骤的前提是自己先编译Qtcreator源码,最好生成release版的QtCreator,否则自定义的插件嵌入QtCreator会失败!!!(这个网上教程很多) ...

  4. Qt自定义标题栏

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt自定义标题栏     本文地址:http://techieliang.com/2017/1 ...

  5. Qt 自定义事件(三种方法:继承QEvent,然后Send Post就都可以了,也可以覆盖customEvent函数,也可覆盖event()函数)

    Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...

  6. Qt 自定义事件

    Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...

  7. Qt自定义事件的实现(转)

    原文:http://blog.csdn.net/michealtx/article/details/6866094 初学Qt,用了Qt自带的事件,然后想怎么才能定义自己的事件呢?又如何使用自定义事件呢 ...

  8. Qt 自定义 滚动条 样式

    今天是时候把软件中的进度条给美化美化了,最初的想法就是仿照QQ. 先前的进度条是这样,默认的总是很难受欢迎的:美化之后的是这样,怎么样?稍微好看一点点了吧,最后告诉你实现这个简单的效果在Qt只需要加几 ...

  9. QT自定义精美换肤界面

    陆陆续续用QT开发过很多项目,也用QT写过不少私活项目,也写过N个工具,一直梦寐以求能像VC一样可以很方便的有个自定义的界面,QSS的强大让我看到了很好的希望,辗转百度谷歌无数次,一直搜索QT相关的换 ...

  10. Qt自定义model

    前面我们说了Qt提供的几个预定义model.但是,面对变化万千的需求,那几个model是远远不能满足我们的需要的.另外,对于Qt这种框架来说,model的选择首先要能满足绝大多数功能的需要,这就是说, ...

随机推荐

  1. 《用Java写一个通用的服务器程序》03 处理新socket

    在讲监听器时说过处理的新的socket要尽快返回,监听器调用的是ClientFactory的createPhysicalConnection方法,那么就来看这个方法: public boolean c ...

  2. 通用Adapter设计,SparseArray+泛型+回调的使用

    看到题目,我相信聪明的各位已经有一定想法了. 一个Adapter,最简单的优化就是使用泛型,他可以省去非常多的代码,不过在此之上,我们还可以继续优化,优化他的好基友是:ViewHolder. 在过去, ...

  3. spark2.2 DataFrame的一些算子操作

    Spark Session中的DataFrame类似于一张关系型数据表.在关系型数据库中对单表或进行的查询操作,在DataFrame中都可以通过调用其API接口来实现.可以参考,Scala提供的Dat ...

  4. redis 梳理笔记(一)

    一 redis 数据格式 短连接 长连接pconnect tcp协议 交互数据格式 交互采用特殊的格式 \r\n 1."+"号开头表示单行字符串的回复      set aa aa ...

  5. svn up出现类似svn: Error converting entry in directory '.' to UTF-8问题解决

    执行svn up命令报错如下 # svn up svn: Error converting entry svn: Valid UTF- data (hex:) followed by invalid ...

  6. 小白的Python之路 day1 用户输入

    1 2 3 4 5 6 7 8 #!/usr/bin/env python #_*_coding:utf-8_*_   username =input("username:") p ...

  7. Abp扩展之【配置功能】

    Abp的扩展功能非常强大,配合持久化可以很方便的配置系统.租户.用户的配置,关于ABP的配置请参考: http://www.cnblogs.com/farb/p/ABPSettingManagemen ...

  8. C++ list forward_list

    list,forward_list list:双向链表 forward_list:单向链表 在任何位置添加元素,删除元素都很快,但随机访问元素则很慢 声明和初始化 list<T> l; l ...

  9. 树莓派学习笔记——USB wifi配置指南

    0 前言     树莓派既能够使用有线网络又能够无线网络,假设使用有线网络不方便的话能够借助USB wifi无线网卡让树莓派也插上无线"翅膀". 可是和使用有线网络即插即用的方式不 ...

  10. webAPP踩坑记录

    最近公司突然给我们下了一个任务  一个星期要做出一个系统网站 外加手机app   2个同事负责 web开发  我负责手机app 的开发 今天终于初级版本做完了,记录一下手机app踩过的坑与优化之路 用 ...