视图代理(转帖)

代理就是一个中间人的意思,也就是model和view之间的一个中间件,它协调两者之间的数据处理,以保证数据在显示层和model层的一致性。

在qt中实现自己的一个代理,一般继承自QItemDelegate类,当然也可以是QAbstractItemDelegate。

在做代理的时候,我们首先要明确一些问题,我们的编辑控件是什么,设置它的值,修改怎么影响model,编辑控件的样式什么样,大小位置是否考虑。在qt中这些需要实现自己代理的方面都以虚函数的形式给出,在实现自己代理的时候,重新实现这些虚函数就行,而调用是自动的,这就是利用C++多态,实现了开闭。

下面给出一个例子

[cpp] view plaincopyprint?

  1. #ifndef SPINBOXDELEGATE_H
  2. #define SPINBOXDELEGATE_H
  3. #include <QItemDelegate>
  4. #include <QModelIndex>
  5. #include <QObject>
  6. #include <QSize>
  7. #include <QSpinBox>
  8. #define logger()  qDebug() << __FILE__ << __LINE__ << __func__
  9. class SpinBoxDelegate : public QItemDelegate
  10. {
  11. Q_OBJECT
  12. public:
  13. SpinBoxDelegate(QObject *parent = 0);
  14. /**
  15. * @brief createEditor 进入可编辑的状态时,产生的编辑控件
  16. * @param parent 这个控件的上层控件
  17. * @param option 一些控件样式选择
  18. * @param index 所在的索引位置
  19. * @return 编辑控件的指针
  20. */
  21. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
  22. const QModelIndex &index) const;
  23. /**
  24. * @brief setEditorData 进入和推出编辑模式调用,修改view的值
  25. * @param editor 与改变想对应的editor指针
  26. * @param index model中的那个索引改变了值
  27. */
  28. void setEditorData(QWidget *editor, const QModelIndex &index) const;
  29. /**
  30. * @brief setModelData 退出编辑模式,修改model
  31. * @param editor 那个editor改变了
  32. * @param model 想对应的model
  33. * @param index 对应的索引
  34. */
  35. void setModelData(QWidget *editor, QAbstractItemModel *model,
  36. const QModelIndex &index) const;
  37. /**
  38. * @brief updateEditorGeometry 更新位置
  39. * @param editor
  40. * @param option
  41. * @param index
  42. */
  43. void updateEditorGeometry(QWidget *editor,
  44. const QStyleOptionViewItem &option, const QModelIndex &index) const;
  45. };
  46. /**
  47. 这些虚函数是自动调用的,我们重新实现这些虚函数来达到控制的效果,可以重新实现的虚函数还有好几个,但是意义都是一样的
  48. */
  49. #endif // SPINBOXDELEGATE_H
  50. #include "spinBoxDelegate.h"
  51. #include <QtGui>
  52. #include <QDebug>
  53. SpinBoxDelegate::SpinBoxDelegate(QObject *parent)
  54. : QItemDelegate(parent)
  55. {
  56. }
  57. QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
  58. const QStyleOptionViewItem &/* option */,
  59. const QModelIndex &/* index */) const
  60. {
  61. logger();
  62. QSpinBox *editor = new QSpinBox(parent);//产生一个QSpinBox控件
  63. editor->setMinimum(0);
  64. editor->setMaximum(100);
  65. return editor;
  66. }
  67. void SpinBoxDelegate::setEditorData(QWidget *editor,
  68. const QModelIndex &index) const
  69. {
  70. logger();
  71. int value = index.model()->data(index, Qt::EditRole).toInt();//根据index获得model的值
  72. QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
  73. spinBox->setValue(value);
  74. }
  75. void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
  76. const QModelIndex &index) const
  77. {
  78. logger();
  79. QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
  80. spinBox->interpretText();
  81. int value = spinBox->value();
  82. model->setData(index, value, Qt::EditRole);
  83. }
  84. void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
  85. const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
  86. {
  87. logger();
  88. editor->setGeometry(option.rect);
  89. }
  90. #include <QApplication>
  91. #include <QHeaderView>
  92. #include <QItemSelectionModel>
  93. #include <QStandardItemModel>
  94. #include <QTableView>
  95. #include "spinBoxDelegate.h"
  96. int main(int argc, char *argv[])
  97. {
  98. QApplication app(argc, argv);
  99. QStandardItemModel model(4, 2);
  100. QTableView tableView;
  101. tableView.setModel(&model);
  102. SpinBoxDelegate delegate;
  103. tableView.setItemDelegate(&delegate);
  104. tableView.horizontalHeader()->setStretchLastSection(true);
  105. tableView.verticalHeader()->setStretchLastSection(true);
  106. for (int row = 0; row < 4; ++row) {
  107. for (int column = 0; column < 2; ++column) {
  108. QModelIndex index = model.index(row, column, QModelIndex());
  109. model.setData(index, QVariant((row+1) * (column+1)));
  110. }
  111. }
  112. tableView.setWindowTitle(QObject::tr("Spin Box Delegate"));
  113. tableView.show();
  114. return app.exec();
  115. }

可以根据打印的logger知道这些虚函数是怎么调用的,加深对整个框架运行机制的理解

时间: 2024-08-27 05:21:37

视图代理(转帖)的相关文章

Qt 学习之路 :视图代理

与 Qt model/view 架构类似,在自定义用户界面中,代理扮演着重要的角色.模型中的每一个数据项都要通过一个代理向用户展示,事实上,用户看到的可视部分就是代理. 每一个代理都可以访问一系列属性和附加属性.这些属性及附加属性中,有些来自于数据模型,有些则来自于视图.前者为代理提供了每一个数据项的数据信息:后者则是有关视图的状态信息. 代理中最常用到的是来自于视图的附加属性ListView.isCurrentItem和ListView.view.前者是一个布尔值,用于表示代理所代表的数据项是

iOS基础之CollectionView(集合视图)

在iOS6.0之后,苹果推出了?个新的继承于UIScrolleriew的一个视 图,UICollectionView,也被称之为集合视图.和UITableView共同作为 在开发中常常用的两个视图,常常作为项目的主界面出现. 代码演示: #import "YourCollectionViewCell.h" @implementation YourCollectionViewCell -(instancetype)initWithFrame:(CGRect)frame{ self = [

iOS 如何改变表视图分割线在iOS7中的默认偏移

- (void)viewDidLoad { [super viewDidLoad]; self.automaticallyAdjustsScrollViewInsets = NO; if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) { [self.tableView setSeparatorInset:UIEdgeInsetsZero]; } if ([self.tableView respondsToS

iOS UI-QQ聊天布局

一.Model BWMessage.h #import <Foundation/Foundation.h> typedef enum{ BWMessageMe = 0,//表示自己 BWMessageOther = 1 //表示对方 }BWMessageType; @interface BWMessage : NSObject //消息正文 @property(nonatomic, copy) NSString *text; //消息时间 @property(nonatomic, copy)

IOS_地图_定位_天气预报_Block回调_单例

H:/1021/00_block回调.h /* 通过block回调 定义block代码块,目的是解析完成之后调用 返回值是 void 参数是 数组,里面的每个成员是一个NSString*/ typedef void(^WeatherFinishedBlock)(NSArray *dataList); @interface WeatherXMLPaser : NSObject // 解析器解析数据,参数1是要解析的数据,参数2是解析完毕回调的代码块 - (void)parserWeatherDat

QtQml 应用程序的性能考虑与建议(来自小V的翻译)

QtQml 应用程序的性能考虑与建议 原文:csdn aidear_evo QtQml应用程序的性能考虑与建议 本文翻译自Qt官网文档:http://doc.qt.io/qt-5/qtquick-performance.html 时间考虑 作为一名程序开发者,应该努力使渲染引擎的刷新率维持在60fps,也就是说在每帧之间大约有16ms,这段时间包括了基本图元在图形硬件上的描画.具体内容如下: 尽可能的使用异步事件驱动来编程. 使用工作者线程来处理重要的事情,比如说QML的WorkerScript

IOS开发系列--无限循环的图片浏览器

--UIKit之UIScrollView 概述 UIKit框架中有大量的控件供开发者使用,在iOS开发中不仅可以直接使用这些控件还可以在这些控件的基础上进行扩展打造自己的控件.在这个系列中如果每个控件都介绍一遍确实没有必要,所谓授人以鱼不如授人以渔,这里会尽可能让大家明白其中的原理,找一些典型的控件进行说明,这样一来大家就可以触类旁通.今天我们主要来看一下UIScrollView的内容: UIView UIScrollView 实战--图片浏览器 UIView 在熟悉UIScrollView之前

tableView用法----博客状态案例

小烨子这两天课比较紧,晚上回来网又打不开网页,苦逼啊,趁现在可以用赶紧写 好了不瞎扯了 自定义微博步骤:1.观察应用,分析功能,了解答题流程2.加载plist取出数据,同时建立模型储存到数组中,因为这是个自定义cell,每个cell的高度都是由cell里面内容确定的,但是要设置cell的高度就要的hi用代理的的这个方法:-  (CGFloat)tableVIew:(UITableView *) heightForRowAtIndexPath:(NSIndexPath *)IndexPath问题来

ios开发系统地图知识

现在很多社交.电商.团购应用都引入了地图和定位功能,地图功能不再是地图应用和导航应用所特有的.目前地图和定位功能已经大量引入到应用开发中.今天就和大家一起看一下iOS如何进行地图开发. 一.Core Location定位使用 在iOS中通过Core Location框架进行定位操作.Core Location自身可以单独使用,和地图开发框架MapKit完全是独立的,但是往往地图开发要配合定位框架使用.在Core Location中主要包含了定位.地理编码(包括反编码)功能. 定位是一个很常用的功