目录

1、Qt中MVD说明

1.1 View

1.2 Delegate

1.3 Model/View的基本原理

2、代码是现实示例

2.1 设置样式文件

2.2 set base attribute

2.3 设置model

2.4 设置表头

2.5 设置数据

2.6 添加代理控件

2.6.1 添加 QSpinBox 代理

2.6.2 添加 QComboBox 代理

2.6.3 添加 QPushButton 代理

2.6.4 添加 CheckBox 代理

2.6.5 添加 Pixmap 代理

2.6.6 添加 LineEdit 代理

2.6.7 添加 ReadOnly 代理

2.6.8 添加 Text 代理

2.6.9 添加 QProcessBar 代理

2.6.10 添加 DateEdit 代理

2.6.11 添加 添加自定义窗口 代理

2.6.12 添加 DoubleProcessBar 代理

2.7 获取某一单元格数据



开发过程中进程使用MVD模型,添加各种代理控件,本文在此基础上整理一些数据模型代理,包括:QPushbutton、QLineEdit、QPixmap、QChecledBox、QComboBox、QSpinBox、QProcessBar、只读列、自定义窗口等共13种代理方式,如图所示:

在此之前,先来说明一下对MVD做一简单说明:

1、Qt中MVD说明

在传统的MVC模型中,view用于向用户展示model数据。但是,Qt提供的并不是MVC架构,而是一个model/view的设计(也就是说,没有包含一个完整而独立的组件用于管理用户的交互)。一般来说,view仅仅是作用于model数据的展示和用户输入的处理,而不应该去做其他的工作。在这种结构中,为了获得对用户输入控制的灵活性,就将这种交互工作交给了delegate完成(也就是“委托”)。简单来说,就是view将用户输入委托给delegate处理,而不自己去处理。这些组件提供一种输入能力,并且能够在某些view中提供这种交互情形下的渲染,比如在table中双击某单元格进行编辑等。

1.1 View

QListView、QTreeView、QTableView

1.2 Delegate

Delegate可以用于渲染内容,这是通过paint() 和sizeHint()函数来完成的。但是对于一些简单的基于组件的delegate,可以通过继承QItemdelegate或者QStyledItemDelegate 来实现,而不需要重写虚函数。

Qt提供的标准组件中使用QItemDelegate提供编辑功能的支持。这种默认的实现被用在QListView,QTableView和QTreeView中。View实用的delegate可以通过itemDelegate()函数获得,其中,setItemDelegate()函数则可以为一个标准组件设置自定义的delegate.

在Qt4.4之后提供QItemDelegate/QStyledItemDelegate ,可以把控件设置成只读、表格的某一列制定自己需要的控件。默认的委托是QStyledItemDelegate。这两个类可以被相互替代,给view组件提供绘制和编辑功能。主要区别在于,QStyledItemDelegate使用当前的风格(style)去绘制组件,所以当需要设置 qt style sheet时建议使用QStyleItemDelegaet作为父类。使用这两个类的代码是一样的,除了需要使用style进行绘制的部分。

注意:绘制和向视图提供编辑器的方式,但使用起来感觉区别不是很大,之前使用过代理第一时间想到的是重写代理,实现虚函数,在虚函数中创建自己想要的控件并返回就OK了,但是运行程序时发现并没有默认显示出来,只有在编辑的时候显示(也就是双击的时候),这种方式用在输入限制的时候感觉比较合适(对此,官方文档是这样解释的:The QStyledItemDelegate class provides display and editing facilities for data items from a model.)。也就是说,如果想要在load的时候就显示出来控件,必须写在void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;里;如果控件需要有相应的动作,就需要写在editorEvent

如果delegate没有支持为你的数据类型进行绘制,或者你希望自己绘制item,那么就可以继承QStyleItemDelegate类,并且重写paint()或者还需要重写sizeHit()函数。paint()函数会被每一个item独立调用,而sizeHint()函数则可以定义每一个item的大小。在重写paint()函数的时候,通常需要用if语句找到你需要进行渲染的诗句类型并进行绘制,其他的数据类型需要调用父类的实现进行绘制。

继承QStyledItemDelegate需要实现以下函数:

class MyDelegate: public QStyledItemDelegate
{//创建你编辑时候的控件,返回修改数据的组件QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const  QModelIndex &index) const;//编辑的时候设置数据到上面创建的editor中。void setEditorData(QWidget *editor, const QModelIndex &index) const; //编辑完成,保存数据到model中void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;//设置编辑控件的位置和大小、样式等(保证editor显示在item view的合适位置以及大小)void updateEditorGeometry ( QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
}

例如,添加一个进度条控件:

void WidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{if (index.column() == 1) {int progress = index.data().toInt();QStyleOptionProgressBar progressBarOption;progressBarOption.rect = option.rect;progressBarOption.minimum = 0;progressBarOption.maximum = 100;progressBarOption.progress = progress;progressBarOption.text = QString::number(progress) + "%";progressBarOption.textVisible = true;QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);} elseQStyledItemDelegate::paint(painter, option, index);
}

1.3 Model/View的基本原理

1、数据(Data)是实际的数据,如数据库的一个数据表或 SQL查询结果,内存中的一个StringList,或磁盘文件结构等。

2、视图或视图组件(View)是屏幕上的界面组件,视图从数据模型获得每个数据项的模型索引(model index),通过模型索引获取数据,然后为界面组件提供显示数据,Qt提供一些现成的数据视图组件,如QListView、QTreeView 和QTableView等。

3、模型或数据模型(Model)与实际数据通信,并为视图组件提供数据接口。它从原始数据提取需要的内容,用于视图组件进行显示和编辑。Qt中有一些预定义的数据模型,如QStringListModel
可作为StringList的数据模型,QSqlTableModel 可以作为数据库中一个数据表的数据模型。

模型(Model)与数据源(Data)通信;视图(View)从模型(Model)中获取模型索引;在标准视图中,代理(delegate)渲染数据项。编辑项时,代理将直接使用模型索引(model index)与模型通信。模型、视图和代理之间使用信号和槽通信。当源数据发生变化时,数据模型发射信号通知视图组件:当用户在界面上操作数据时,视图组件发射信号表示这些操作信息;当编辑数据时,代理发射信号告知数据模型和视图组件编辑器的状态。

所有的基于项数据(item data)的数据模型(Model)都基于QAbstractltemModel类,此类定义了视图和代理访问数据的接口。数据本身不必存储在模型中;它可以保存在由单独的类、文件、数据库或其他应用程序组件提供的数据结构或存储库中。QabstracteModel提供了一个数据接口,该接口足够灵活,可以处理以table、list和tree的形式表示数据的视图。

Qt提供了一些现成的模型,可用于处理数据项:

  • QStringListModel 用于处理QString列表的数据模型类
  • QStandardItemModel 标准的基于项数据的数据模型类,管理更复杂的树结构,每个项数据内都可以包含任意类型的数据
  • QFileSystemModel 提供有关本地文件系统中的文件和目录的信息,文件系统模型类
  • QSqlQueryModel 用于数据库sql查询结果的数据模型类
  • QSqlTableModel 用于数据库中一个数据表的数据模型类
  • QSqlRelationalTableModel 用于关系型数据表的数据模型类
  • QSortFilterProxyModel 与其他数据模型结合,提供排序和过滤功能的数据模型类

如果这些标准模型不符合您的要求,您可以将QAbstractItemModel、QAbstractListModel或QAbstractTableModel子类化,以创建自己的自定义模型。

一般需要实现的子类为:

//获得模型的行数
int rowCount(const QModelIndex &parent) const;
//获得模型的列数
int columnCount(const QModelIndex &parent) const;
//向模型中设置数据
bool setData(const QModelIndex &index, const QVariant &value, int role );
//获得模型的数据
QVariant data(const QModelIndex &index, int role) const;
//设置模型的标题
QVariant headerData(int section, Qt::Orientation orientation, int role ) const;

2、代码是现实示例

2.1 设置样式文件

QString qssData = nullptr;
QFile fileqss(":/qss/QSSUITableView");
if(fileqss.open(QFile::ReadOnly))
{qssData = fileqss.readAll();fileqss.close();
}
ui->tableView->setStyleSheet(qssData);

2.2 set base attribute

    ui->tableView->verticalHeader()->hide();                                                   // 隐藏垂直头ui->tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);                       // 隐藏水平头//ui->tableView->horizontalHeader()->setStretchLastSection(true);                          // 设置随后一列拉伸ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);         // 设置列平均分配//ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);  // 设置TreeWidget水平滚动和自适应宽度//ui->tableView->setColumnWidth(headersList.count() - 1, TITLE_FIXED_HEIGHT);              // 设置最后一列固定//ui->tableView->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);      // 行单选ui->tableView->setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);         // 行多选 (单选QAbstractItemView::SingleSelection 多选:QAbstractItemView::MultiSelection)ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);                         // 不可编辑ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);                        // 设置选中模式为整行ui->tableView->setShowGrid(false);                                                         // 显示/隐藏网格线setFocusPolicy(Qt::FocusPolicy::NoFocus);                                                  // 设置选中之后无虚线焦点//horizontalHeader()->setMinimumSectionSize(100);                                          // 设置最小列宽//horizontalHeader()->setMaximumSectionSize(100);                                          // 设置最大列宽ui->tableView->verticalHeader()->setDefaultSectionSize(25);                                 // 可以设置tableview所有列的默认行高为15。//horizontalHeader()->setDefaultSectionSize(15);                                            // 可以设置tableview所有行的默认列宽为15。ui->tableView->setWordWrap(false);                                                         // 设置不自动换行setMouseTracking(true);                                                                     // 设置鼠标追踪// 设置第0列固定宽度/*ui->tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);ui->tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);ui->tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);ui->tableView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);ui->tableView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Fixed);ui->tableView->horizontalHeader()->setSectionResizeMode(5, QHeaderView::Fixed);ui->tableView->setColumnWidth(0, 50);ui->tableView->setColumnWidth(2, 150);ui->tableView->setColumnWidth(3, 150);ui->tableView->setColumnWidth(4, 150);ui->tableView->setColumnWidth(5, 150);*/

2.3 设置model

    model = new QStandardItemModel;ui->tableView->setModel(model);

2.4 设置表头

    QStringList headerList;headerList<<"姓名"<<"QSpinBox"<<"QComboBox"<<"QPushButton"<<"CheckBox"<<"QPixmap"<<"QLineEdit"<<"ReadOnly"<<"Text"<<"ProcessBar"<<"DateEdit"<<"CustomWidget"<<"pDoubleProcessBar";model->setHorizontalHeaderLabels(headerList);

2.5 设置数据

    model->setItem(0,0,new QStandardItem("张三"));model->setItem(1,0,new QStandardItem("李四"));model->setItem(2,0,new QStandardItem("王二"));model->setItem(3,0,new QStandardItem("小明同学"));model->setItem(0,1,new QStandardItem("1"));model->setItem(1,1,new QStandardItem("2"));model->setItem(2,1,new QStandardItem("3"));ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);         // 选择一行

2.6 添加代理控件

2.6.1 添加 QSpinBox 代理

    CUISpinBoxDelegate *pSpinBox = new CUISpinBoxDelegate(this);ui->tableView->setItemDelegateForColumn(1, pSpinBox);

2.6.2 添加 QComboBox 代理

    CUIComboBoxDelegate *pComboBox = new CUIComboBoxDelegate(this);ui->tableView->setItemDelegateForColumn(2, pComboBox);

2.6.3 添加 QPushButton 代理

    CUIMutipleButtonDeleagate *pMutipleBtn = new CUIMutipleButtonDeleagate(QStringList() << "修改" << "删除", this);ui->tableView->setItemDelegateForColumn(3, pMutipleBtn);connect(pMutipleBtn, &CUIMutipleButtonDeleagate::editData, [&](){QMessageBox::information(this, "提示", "这是一个编辑按钮");});connect(pMutipleBtn, &CUIMutipleButtonDeleagate::deleteData, [&](){QMessageBox::information(this, "提示", "这是一个删除按钮");});

2.6.4 添加 CheckBox 代理

    /*CUITableHeaderView **/pTableHeaderView = new CUITableHeaderView(Qt::Horizontal, ui->tableView);connect(pTableHeaderView, &CUITableHeaderView::stateChanged, this, &MainWindow::headerStateChangedSlot);connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(itemChangedSlot(QStandardItem*)));ui->tableView->setHorizontalHeader(pTableHeaderView);CUICheckBoxDelegate *pCheckedBox = new CUICheckBoxDelegate(this);ui->tableView->setItemDelegateForColumn(4, pCheckedBox);

2.6.5 添加 Pixmap 代理

    CUIPixmapDelegate *pPixmap = new CUIPixmapDelegate(this);ui->tableView->setItemDelegateForColumn(5, pPixmap);

2.6.6 添加 LineEdit 代理

CUILineEditDelegate *pLineEdit = new CUILineEditDelegate(this);

2.6.7 添加 ReadOnly 代理

    CUIOnlyReadDelegate *pReadOnly = new CUIOnlyReadDelegate(this);ui->tableView->setItemDelegateForColumn(7, pReadOnly);

2.6.8 添加 Text 代理

    CUITextDelegate *pLabel = new CUITextDelegate(this);ui->tableView->setItemDelegateForColumn(8, pLabel);

2.6.9 添加 QProcessBar 代理

    CUIProcessBarDelegate *pProcessBar = new CUIProcessBarDelegate();ui->tableView->setItemDelegateForColumn(9, pProcessBar);QModelIndex index = model->index(0, 9, QModelIndex());model->setData(index,29);

2.6.10 添加 DateEdit 代理

    CUIDateEditDelegate *pDateEdit = new CUIDateEditDelegate();ui->tableView->setItemDelegateForColumn(10, pDateEdit);

2.6.11 添加 添加自定义窗口 代理

    CUICustomDelegate *pCustomWidget = new CUICustomDelegate(this);ui->tableView->setItemDelegateForColumn(11, pCustomWidget);

2.6.12 添加 DoubleProcessBar 代理

    CUIDoubleProcessBarDelegate *pDoubleProcessBar = new CUIDoubleProcessBarDelegate(this);ui->tableView->setItemDelegateForColumn(12, pDoubleProcessBar);

2.7 获取某一单元格数据

    //model->index(0, 1).data();

详细代码下载

基于QTableView中的MVD代理添加总结相关推荐

  1. js php通讯录,基于aotu.js实现微信自动添加通讯录中的联系人功能

    什么是Auto.JS? Auto.JS是Android平台上的JavaScript自动化工具. 它的本质是可执行自己编写的简易Javascript脚本的,尤其可以在开启"无障碍模式" ...

  2. 基于列表框的简单选课窗体开发。编写Windows应用程序,设计实现一个简单选课系统,要求:(1)点击“添加”按钮,将把在第一文本框中的输入的课程名称添加到左边的列表框中,且所添加的课程不能为空,不能

    基于列表框的简单选课窗体开发.编写Windows应用程序,设计实现一个简单选课系统,要求: (1)点击"添加"按钮,将把在第一文本框中的输入的课程名称添加到左边的列表框中,且所添加 ...

  3. 如何在 Windows Server 2003、Windows 2000 和 Windows XP 中备份恢复代理的加密文件系统 (EFS) 私钥...

    本 文介绍了如何在运行 Microsoft Windows Server 2003.Microsoft Windows 2000 或 Microsoft Windows XP 的计算机上备份恢复代理加 ...

  4. 部署haproxy代理,搭建基于nginx的高性能反向代理群集

    目录 一.Haproxy概述.简介 (1)Haproxy简介 (2)Haproxy和LVS.Nginx的比较 (3)Haproxy的代理模式 二.利用Haproxy+nginx搭建web群集 实验环境 ...

  5. 基于qt中QCalendarWidget的双日历时间范围选择控件(自定义)

    控件预览: 控件基于QT设计,单击日历设置时间范围起点,再次单击日历设置时间范围终点: 当起止时间为同一天时,所选日期右上角显示"单"字样: 控件设计说明: 控件基于QT中QDia ...

  6. 基于Springboot的休闲娱乐代理售票系统

    摘要 网络的广泛应用给生活带来了十分的便利.所以把休闲娱乐代理售票管理与现在网络相结合,利用java技术建设休闲娱乐代理售票系统,实现休闲娱乐代理售票的信息化.则对于进一步提高休闲娱乐代理售票管理发展 ...

  7. 吃透Java中的动态代理

    动态代理在Java中是很重要的一部分,在很多框架中都会用到,如Spring中的AOP.Hadoop中的RPC等.为此在这把我对Java中的动态代理的理解分享给大家,同时写了一个模拟AOP编程的实例.( ...

  8. 转载:QTableView中嵌入可视化组件

    出处:http://qimo601.iteye.com/blog/1538364 QTableView中嵌入可视化组件方法有四种: 第一种不能之前显示,必须双击/选中后才能显示,不适用. 第二种比较简 ...

  9. Spring中的动态代理

    动态代理:指的就是通过一个代理对象来创建需要的业务对象,然后在这个代理对象中统一进行各种需求的处理. 学习完Spring后会发现,Spring中的AOP(面向方面编程:Aspect Oriented ...

最新文章

  1. GitLab成立中国合资公司极狐,强调“独立运营”
  2. Unity 类似FingerGestures 的相机跟随功能
  3. 大数据对于我们的生活有哪些便利(图)
  4. 关于java中::语法的理解
  5. boost::multi_array模块实现打印数组相关的测试程序
  6. 为多孔介质的当量直径_新型纳米多孔碳材料在催化剂载体方面的应用
  7. Invalid argument: Key: label. Data types don't match. Data type: int64 but expected type: float
  8. Taro+react开发(72):Taro.createSelectorQuery
  9. 作者:蓝梦微, 女, 中国人民大学信息学院博士生,CCF学生会员。
  10. websocket 初识
  11. java广告投放系统_广告投放系统
  12. 利用公共手机获取短信验证码
  13. 如何使用WPS更换证件照底色
  14. 史上最全最详细的Anaconda安装教程
  15. Adaptive AUTOSAR----Adaptive studio
  16. 移动端产品设计(02)-移动APP产品结构
  17. html用来注释的标记,互联网常识:html的注释标记是什么
  18. Oracle 的next_day函数详解
  19. 微信小程序开发笔记 进阶篇⑤——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之前)
  20. 【PHPWord】如何解决PHPWord的输出checkbox复选框并设置checked已勾选

热门文章

  1. 你的GitHub项目被封存到北极了吗?
  2. css 跳跃动画,如何使用纯CSS实现方块跳跃的动画(附源码)
  3. android 9.0 Launcher3修改workspace字体颜色
  4. 奔跑吧!中国芯,北京迅为龙芯处理器平台
  5. [转载]中国3大移动公司(电信,联通,移动)频率分配大全
  6. MR直播实例(混合现实直播)高品质企业直播
  7. 消息中间件(一)分布式系统事务一致性解决方案大对比,谁最好使?(转)...
  8. 海康摄像机rtsp地址格式(官方最新版)
  9. 绝缘监测系统设备解决方案在工厂的研究应用-船舶电力系统
  10. wave文件格式详解