(四十一)视图中的委托
来源:互联网 发布:linux sigpipe 编辑:程序博客网 时间:2024/06/06 11:42
视图与委托
1、 委托是视图的一部分,需要承担数据显示的部分工作
2、 视图负责确定数据的显示方式(列表、表格、树形)
3、 委托负责具体数据项的显示和编辑(数据项值、编辑器)
4、 视图和委托共同完成数据显示功能和数据编辑功能
/*
1、在视图setItemDelegate()时,将参数设置为NULL,即取消视图的委托,运行时,仍能看出视图是以怎样的方式显示数据的(能分别是列表、表格、还是树形),甚至能显示出模型的HeaderLabel,但是不能显示具体的数据项,双击也不会出现编辑框,也就是不能编辑数据项。
2、注释掉委托的paint()成员函数的函数体,运行时,现象与1类似,不同的地方在于,虽不能显示具体数据项,但能显示数据项的外围线条,双击也会出现编辑框,并能编辑数据项
*/
改变视图中数据项的显示方式
自定义委托的默认数据项显示方式
1、 重写paint ()成员函数
2、 在paint ()中自定义数据项显示方式
3、 重写editorEvent()成员函数
4、 在editorEvent()中处理交互事件
定义数据项显示方式
//伪代码
void CustomizedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)const{ if( /* 数据项满足自定义显示条件 */) { //1. 根据索引参数获取模型中的数据 //2. 定义绘制参数对象 QStyleOptionXXXX xxxxOption; //3. 设置具体参数到xxxxOption对象 //4. 根据参数对象xxxxOption绘制数据显示方式 QApplication::style()->drawControl(QStyle::CE_XXXX, &xxxxOption, painter); } else { QItemDelegate::paint(painter, option,index); }}
处理交互事件
//伪代码
boolCustomizedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,const QStyleOptionViewItem &option, const QModelIndex &index) { bool ret = true; if( /* 数据项满足自定义显示条件 */) { //1.转换事件event类型 if( /* 发生事件的具体类型满足并在option内*/) { //2.根据index去模型中取数据 //3.修改数据并返回模型 } } else { ret = QItemDelegate::editorEvent(event, model, option, index); } return ret; //表明已经处理}
一、
//CustomizedItemDelegate.h
#ifndef CUSTOMIZEDITEMDELEGATE_H#define CUSTOMIZEDITEMDELEGATE_H #include <QItemDelegate>#include <QModelIndex> class CustomizedItemDelegate : publicQItemDelegate{ Q_OBJECT public: explicit CustomizedItemDelegate(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, constQModelIndex &index) const; void paint(QPainter *painter, const QStyleOptionViewItem &option,const QModelIndex &index) const; bool editorEvent(QEvent *event, QAbstractItemModel *model, constQStyleOptionViewItem &option, const QModelIndex &index);}; #endif // CUSTOMIZEDITEMDELEGATE_H
// CustomizedItemDelegate.cpp
#include"CustomizedItemDelegate.h"#include <QComboBox>#include <QMouseEvent>#include <QApplication>#include <QDebug> CustomizedItemDelegate::CustomizedItemDelegate(QObject*parent) : QItemDelegate(parent){ } QWidget*CustomizedItemDelegate::createEditor(QWidget *parent, constQStyleOptionViewItem &option, const QModelIndex &index) const{ QWidget* ret = NULL; //要修数据类型为BOOL类型的数据项编辑器的默认显示方式,因此此处就不创建对应的编辑器,而是在重写的paint()函数处理BOOL if( index.data().type() == QVariant::Char ) { QComboBox* cb = new QComboBox(parent); cb->addItem("A"); cb->addItem("B"); cb->addItem("C"); cb->addItem("D"); ret = cb; } else { ret = QItemDelegate::createEditor(parent, option, index); } return ret;} voidCustomizedItemDelegate::updateEditorGeometry(QWidget *editor, constQStyleOptionViewItem &option, const QModelIndex &index) const{ editor->setGeometry(option.rect);} voidCustomizedItemDelegate::setEditorData(QWidget *editor, const QModelIndex&index) const{ if( index.data().type() == QVariant::Char ) { QComboBox* cb = dynamic_cast<QComboBox*>(editor); if( cb != NULL ) { for(int i=0; i<cb->count(); i++) { if( cb->itemText(i) ==index.data().toString() ) { cb->setCurrentIndex(i); break; } } } } else { QItemDelegate::setEditorData(editor, index); }} voidCustomizedItemDelegate::setModelData(QWidget *editor, QAbstractItemModel*model, const QModelIndex &index) const{ if( index.data().type() == QVariant::Char ) { QComboBox* cb = dynamic_cast<QComboBox*>(editor); if( cb != NULL ) { model->setData(index, cb->currentText().at(0), Qt::DisplayRole); } } else { QItemDelegate::setModelData(editor, model, index); }}//自定义数据显示方式void CustomizedItemDelegate::paint(QPainter*painter, const QStyleOptionViewItem &option, const QModelIndex &index)const{ if( index.data().type() == QVariant::Bool ) { bool data = index.data(Qt::DisplayRole).toBool(); QStyleOptionButton checkBoxStyle; //QStyleOptionButton类对象用于描述button的属性信息 checkBoxStyle.state = data ? QStyle::State_On : QStyle::State_Off; //根据data值设置是否选中 checkBoxStyle.state |= QStyle::State_Enabled; //可操作属性 checkBoxStyle.rect = option.rect; //option保存当前数据项在视图中的外观信息,这里是使用数据项大小 checkBoxStyle.rect.setX(option.rect.x() + option.rect.width() / 2 - 6); //设置rect的x坐标 QApplication::style()->drawControl(QStyle::CE_CheckBox,&checkBoxStyle, painter); //调用构造函数style()得到保存有跟操作系统风格相关的对象,再绘制控件,绘制对象时CheckBox } else { QItemDelegate::paint(painter, option, index); }}//处理交互事件bool CustomizedItemDelegate::editorEvent(QEvent*event, QAbstractItemModel *model, const QStyleOptionViewItem &option,const QModelIndex &index) { bool ret = true; //index就是代表的正在被操作的数据项的 if( index.data().type() == QVariant::Bool ) { QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event); if( (event->type() == QEvent::MouseButtonPress) &&option.rect.contains(mouseEvent->pos()) ) { bool data = index.data(Qt::DisplayRole).toBool(); //去模型中的数据 qDebug() << "set model data: " << !data; qDebug() << model->setData(index, !data, Qt::DisplayRole); //取反后存入模型 } } else //默认处理,一定要有默认处理的分支,否则其他数据类型的值将不会显示 { ret = QItemDelegate::editorEvent(event, model, option, index); } return ret; //表明已经被处理}
//Widget.h
#ifndef WIDGET_H#define WIDGET_H #include <QtGui/QWidget>#include <QTableView>#include <QStandardItemModel>#include"CustomizedItemDelegate.h" class Widget : public QWidget{ Q_OBJECT QTableView m_view; QStandardItemModel m_model; CustomizedItemDelegate m_delegate; void initView(); void initModel(); public: Widget(QWidget* parent = 0); ~Widget();}; #endif // WIDGET_H
//Widget,cpp
#include "Widget.h"#include <QStandardItem>#include <QModelIndex>#include <QStringList>#include <QDebug> Widget::Widget(QWidget* parent) :QWidget(parent){ initView(); initModel(); m_view.setModel(&m_model); //关联视图模型 for(int i=0; i<m_model.columnCount(); i++) { m_view.setColumnWidth(i, 125); }} void Widget::initView(){ m_view.setParent(this); m_view.move(10, 10); m_view.resize(500, 200); m_view.setItemDelegate(&m_delegate); //设置委托} void Widget::initModel(){ QStandardItem* root = m_model.invisibleRootItem(); QStringList hl; QStandardItem* itemA1 = new QStandardItem(); QStandardItem* itemB1 = new QStandardItem(); QStandardItem* itemC1 = new QStandardItem(); QStandardItem* itemA2 = new QStandardItem(); QStandardItem* itemB2 = new QStandardItem(); QStandardItem* itemC2 = new QStandardItem(); hl.append("Language"); hl.append("Level"); hl.append("Script"); m_model.setHorizontalHeaderLabels(hl); itemA1->setData("Delphi", Qt::DisplayRole); itemB1->setData(QChar('A'), Qt::DisplayRole); itemC1->setData(false, Qt::DisplayRole); itemA2->setData("Perl", Qt::DisplayRole); itemB2->setData(QChar('B'), Qt::DisplayRole); itemC2->setData(true, Qt::DisplayRole); root->setChild(0, 0, itemA1); root->setChild(0, 1, itemB1); root->setChild(0, 2, itemC1); root->setChild(1, 0, itemA2); root->setChild(1, 1, itemB2); root->setChild(1, 2, itemC2);} Widget::~Widget(){ }
二、
//main.cpp
#include <QtGui/QApplication>#include "Widget.h" 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 <QtGui/QWidget>#include <QTableView>#include <QStandardItemModel>#include <QTimer>#include"CustomizedItemDelegate.h" class Widget : public QWidget{ Q_OBJECT QTableView m_view; QStandardItemModel m_model; CustomizedItemDelegate m_delegate; QTimer m_timer;//通过定时器模拟任务进度 void initView(); void initModel();private slots: void timerTimeout();public: Widget(QWidget* parent = 0); ~Widget();}; #endif // WIDGET_H
//Widget.cpp
#include "Widget.h"#include <QStandardItem>#include <QModelIndex>#include <QStringList>#include <QModelIndex>#include <QDebug> Widget::Widget(QWidget* parent) :QWidget(parent){ initView(); initModel(); m_view.setModel(&m_model); //关联视图模型 for(int i=0; i<m_model.columnCount(); i++) { m_view.setColumnWidth(i, 200); } connect(&m_timer, SIGNAL(timeout()), this, SLOT(timerTimeout())); m_timer.setParent(this); //父子关系 m_timer.start(500); //每隔500秒发送一次timeout} void Widget::initView(){ m_view.setParent(this); m_view.move(10, 10); m_view.resize(500, 200); m_view.setItemDelegate(&m_delegate); //设置委托} void Widget::initModel(){ QStandardItem* root = m_model.invisibleRootItem(); QStringList hl; QStandardItem* itemA1 = new QStandardItem(); QStandardItem* itemB1 = new QStandardItem(); QStandardItem* itemA2 = new QStandardItem(); QStandardItem* itemB2 = new QStandardItem(); hl.append("Task"); hl.append("Progress"); m_model.setHorizontalHeaderLabels(hl); itemA1->setData("Delphi", Qt::DisplayRole); itemB1->setData(70, Qt::DisplayRole); itemA2->setData("Perl", Qt::DisplayRole); itemB2->setData(60, Qt::DisplayRole); root->setChild(0, 0, itemA1); root->setChild(0, 1, itemB1); root->setChild(1, 0, itemA2); root->setChild(1, 1, itemB2);} void Widget::timerTimeout(){ QModelIndex i1 = m_model.index(0, 1, QModelIndex()); //首先获取模型索引 QModelIndex i2 = m_model.index(1, 1, QModelIndex()); QVariant v1 = (i1.data().toInt() + 1) % 100; //控制值的范围 QVariant v2 = (i2.data().toInt() + 3) % 100; m_model.setData(i1, v1, Qt::DisplayRole); //将值设置会模型 m_model.setData(i2, v2, Qt::DisplayRole);} Widget::~Widget(){ }
//CustomizedItemDelegate.h
#ifndef CUSTOMIZEDITEMDELEGATE_H#define CUSTOMIZEDITEMDELEGATE_H #include <QItemDelegate> class CustomizedItemDelegate : publicQItemDelegate{ Q_OBJECTpublic: explicit CustomizedItemDelegate(QObject *parent = 0); void paint(QPainter *painter, const QStyleOptionViewItem &option,const QModelIndex &index) const; bool editorEvent(QEvent *event, QAbstractItemModel *model, constQStyleOptionViewItem &option, const QModelIndex &index);}; #endif // CUSTOMIZEDITEMDELEGATE_H
//CustomizedItemDelegate.cpp
#include"CustomizedItemDelegate.h"#include <QApplication>#include <QEvent> CustomizedItemDelegate::CustomizedItemDelegate(QObject*parent) : QItemDelegate(parent){} void CustomizedItemDelegate::paint(QPainter*painter, const QStyleOptionViewItem &option, const QModelIndex &index)const{ if( index.data().type() == QVariant::Int ) { const int DELTA = 4; int progress = index.data().toInt(); QStyleOptionProgressBar progressBarOption; int top = option.rect.top() + DELTA; //调整进度条大小 int left = option.rect.left() + DELTA; int width = option.rect.width() -2 * DELTA; int height = option.rect.height() - 2 * DELTA; progressBarOption.rect = QRect(left, top, width, height); progressBarOption.minimum = 0; progressBarOption.maximum = 100; progressBarOption.progress = progress; //设置进度值 progressBarOption.textVisible = true; //绘制进度条同时绘制文本信息 progressBarOption.text = QString().sprintf("%d", progress) +"%"; //设置绘制的文本的内容 progressBarOption.textAlignment = Qt::AlignCenter; //设置文本居中显示 QApplication::style()->drawControl(QStyle::CE_ProgressBar,&progressBarOption, painter); } else { QItemDelegate::paint(painter, option, index); }} boolCustomizedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,const QStyleOptionViewItem &option, const QModelIndex &index){ bool ret = true; if( event->type() != QEvent::MouseButtonDblClick ) //禁止编辑操作 { ret = QItemDelegate::editorEvent(event, model, option, index); } return ret;}
在实际工程项目中,可以使用后台线程根据实际的任务情况更新模型中的数据,从而更新数据的界面显示。
0 0
- (四十一)视图中的委托
- 模型视图中的委托
- (四十)模型视图中的委托
- 视图和委托
- 视图上的委托
- 视图与委托
- VS2010/MFC编程入门之四十一(文档、视图和框架:分割窗口)
- VS2010/MFC编程入门之四十一(文档、视图和框架:分割窗口)
- C#中的委托
- J# 中的委托类型
- C#中的委托
- C#中的委托
- C#中的委托
- C#中的委托
- C#中的委托
- C# 中的委托
- C#中的委托
- C#中的委托
- CSS 页面重绘和回流
- 51nod 1258 FFT 多项式求逆 伯努利数
- spring中@autowired和@resource的区别
- 意甲官网在中国地区被假网劫持,竟声称赞助?
- Hive统计新增,日活和留存率, 使用sqoop导出到MYSql
- (四十一)视图中的委托
- 【Java每日一题】20170303
- Hugetable数据库如何导出数据?
- android SQL
- HDUOJ
- μC/OS中的中断处理
- 获取连接到wifi热点的手机信息。
- sqlAlchemy的sql语句查询
- BIT2010年上机第二题