Qt深入浅出(十五)QTableView
转载:吓人的猿
TableView
表格视图控件QTableView,需要和QStandardItemModel, 配套使用,这套框架是基于MVC设计模式设计的,M(Model)是QStandardItemModel数据模型,
不能单独显示出来。V(view)是指QTableView视图,要来显示数据模型,C(controllor)控制在Qt中被弱化,与View合并到一起。
1 QTableView简单应用
QStandardItmeModel表格的数据模型,那么这个模型需要填上每一行每一列的数据,就像execl表格一样。
widget.h
#ifndef WIDGET_H
#define WIDGET_H #include <QTableView>
class Widget : public QTableView //继承至QTableView
{
Q_OBJECT
public:
Widget(QWidget *parent = );
~Widget();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QStandardItemModel>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QTableView(parent)
{
QStandardItemModel* model = new QStandardItemModel(this);
model->setItem(, , new QStandardItem("张三"));
model->setItem(, , new QStandardItem(""));
model->setItem(, , new QStandardItem("男"));
this->setModel(model);
} Widget::~Widget()
{ }
以上代码实现了在model中添加一条数据,然后通过setModel函数设置view的数据模型为model,显示出来,如图:

2 修改行列字段名
修改字段名可以使用QStandardItemModel::setHeaderData,但是在这之前你需要调用QStandardItemModel::setColumnCount和QStandardItemModel::setRowCount,例如:
Widget::Widget(QWidget *parent)
: QTableView(parent)
{
QStandardItemModel* model = new QStandardItemModel(this);
/*设置列字段名*/
model->setColumnCount();
model->setHeaderData(,Qt::Horizontal, "姓名");
model->setHeaderData(,Qt::Horizontal, "年龄");
model->setHeaderData(,Qt::Horizontal, "性别");
/*设置行字段名*/
model->setRowCount();
model->setHeaderData(,Qt::Vertical, "记录一");
model->setHeaderData(,Qt::Vertical, "记录二");
model->setHeaderData(,Qt::Vertical, "记录三"); /*设置一条数据*/
model->setItem(, , new QStandardItem("张三"));
model->setItem(, , new QStandardItem(""));
model->setItem(, , new QStandardItem("男"));
this->setModel(model);
}
把1中的构造函数换为以上代码,运行即可得出下图:

3 移除数据
移除数据的常用函数有:
/*移除某行数据*/
bool QAbstractItemModel::removeRow(int row, const QModelIndex &parent = QModelIndex())
/*移除某列数据*/
bool QAbstractItemModel::removeColumn(int column, const QModelIndex &parent = QModelIndex())
例如:
model->removeRow();//移除第0行数据
model->removeColumn();//移除第0列数据
4 插入数据
插入一行数据:
void QStandardItemModel::insertRow(int row, const QList<QStandardItem *> &items)
/*
* row 表示从第几行插入数据
* items 表示要插入的数据QStandardItem对象
*/
例如:
QList<QStandardItem*> list;
list << new QStandardItem("王五") << new QStandardItem("") << new QStandardItem("男");
model->insertRow(, list); //在第0行插入一条记录
5 数据变更信号处理
当QStandardModel中的数据被更改的时候,会发射出dataChanged信号:
[signal] void QAbstractItemModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int> ());
/*
*topLeft bottomRight这两索引指的是表格中被更改数据的区域,如果只有一个数据被更改,那么topLeft等于bottomRight
*/
例如:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QTableView>
class QStandardItemModel;
class Widget : public QTableView
{
Q_OBJECT
public slots:
void dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight,
const QVector<int> &roles = QVector<int> ());
public:
Widget(QWidget *parent = );
QStandardItemModel* model;
~Widget();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QStandardItemModel>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QTableView(parent)
{
model = new QStandardItemModel(this);
model->setColumnCount();
model->setHeaderData(,Qt::Horizontal, "姓名");
model->setHeaderData(,Qt::Horizontal, "年龄");
model->setHeaderData(,Qt::Horizontal, "性别");
model->setRowCount();
model->setHeaderData(,Qt::Vertical, "记录一");
model->setHeaderData(,Qt::Vertical, "记录二");
model->setHeaderData(,Qt::Vertical, "记录三");
model->setItem(, , new QStandardItem("张三"));
model->setItem(, , new QStandardItem(""));
model->setItem(, , new QStandardItem("男"));
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this, SLOT(dataChangedSlot(QModelIndex,QModelIndex,QVector<int>)));
this->setModel(model);
}
void Widget::dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
qDebug() << model->data(topLeft).toString() << endl;
}
Widget::~Widget()
{
}
需要知道的是函数data可以获取想要的QStandardItem对象的索引:
[pure virtual] QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
返回的QVariant对象是一种泛型变量,可以转换成QString、int、double等数据类型。
6 常用函数
//默认显示行头,如果你觉得不美观的话,我们可以将隐藏
tableview->verticalHeader()->hide();
//设置选中时为整行选中
tableview->setSelectionBehavior(QAbstractItemView::SelectRows); //设置表格的单元为只读属性,即不能编辑
tableview->setEditTriggers(QAbstractItemView::NoEditTriggers);
//返回一个被选中的所有Item的索引,一般是去遍历这个链表进行处理
[virtual protected] QModelIndexList QTableView::selectedIndexes() const
7 QStandardItem被点选信号
当QStandardItemModel中的某个QStandardItem被点选后,QStandardItemModel对象会发出一个信号:
void QAbstractItemView::clicked(const QModelIndex &index);
/*
*返回被点选的Item的索引
*/
8 QItemDelegate代理
QTableView在处理信息显示编辑的时候比较单调,类似行编辑器,为了获得更多的灵性性,交互通过QItemDelegate执行。
下面通过派生一个SpinDelegate来实现一个整数旋转框的代理器。
一般我们要重写函数createEditor:
[virtual] QWidget *QItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
/*
*QWidget *parent一般是指哪个窗口使用了这个代理,一般用来托管内存
* QStyleOptionViewItem &option 样式风格
* const QModelIndex &index 需要更改的Item索引
*/
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QTableView> class QStandardItemModel; class Widget : public QTableView
{
Q_OBJECT
public slots:
void dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight,
const QVector<int> &roles = QVector<int> ());
public:
Widget(QWidget *parent = );
QStandardItemModel* model;
~Widget();
}; #endif
widget.cpp
#include "widget.h"
#include "spindelegate.h"
#include <QStandardItemModel>
#include <QDebug> Widget::Widget(QWidget *parent)
: QTableView(parent)
{
model = new QStandardItemModel(this);
//设置列字段名
model->setColumnCount();
model->setHeaderData(,Qt::Horizontal,"姓名");
model->setHeaderData(,Qt::Horizontal,"年龄");
model->setHeaderData(,Qt::Horizontal,"性别");
//设置行字段名
model->setRowCount();
model->setHeaderData(,Qt::Vertical, "记录一");
model->setHeaderData(,Qt::Vertical, "记录二");
model->setHeaderData(,Qt::Vertical, "记录三");
//设置一条数据
model->setItem(, , new QStandardItem("张三"));
model->setItem(, , new QStandardItem(""));
model->setItem(, , new QStandardItem("男"));
this->setModel(model);
//设置代理
this->setItemDelegate(new SpinDelegate(this));
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
this,SLOT(dataChangedSlot(QModelIndex,QModelIndex,QVector<int>)));
this->setModel(model); } void Widget::dataChangedSlot(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
qDebug() << model->data(topLeft).toString() << endl;
}
Widget::~Widget()
{
}
spinDelegate.h
#ifndef SPINDELEGATE_H
#define SPINDELEGATE_H
#include <QItemDelegate> class SpinDelegate : public QItemDelegate
{
public:
SpinDelegate(QObject *parent = Q_NULLPTR);
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
}; #endif // SPINDELEGATE_H
spinDelegate.cpp
#include "spindelegate.h"
#include <QSpinBox>
SpinDelegate::SpinDelegate(QObject *parent): QItemDelegate(parent)
{ }
QWidget* SpinDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if(index.column() == ) // 返回下拉框
{
QSpinBox* box = new QSpinBox(parent);
box->setMinimum();
box->setMaximum();
return box;
}
return QItemDelegate::createEditor(parent, option, index);
}

Qt深入浅出(十五)QTableView的更多相关文章
- 【夸QT在十五】ctkPluginFrameWork插件系统Windows编译器
采用ctkPluginFramework作为一个插件系统开发框架确实有很多优点. 有些车站最近收到的一封信,每个人都想用ctkPluginFramework但我不知道如何建立,本教程对谈ctkPlug ...
- 第十五次oo作业
作业十五 测试与正确性论证的效果差异 程序的测试需要通过输入特定数据等方式,检查程序是否和预期相同,因为测试不可能穷举,导致了不穷举的测试不可能验证程序是完全正确的,只能验证程序在测试时没有发生错误, ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- OpenCV开发笔记(六十五):红胖子8分钟带你深入了解ORB特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- 我的MYSQL学习心得(十五) 日志
我的MYSQL学习心得(十五) 日志 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...
- Bootstrap <基础二十五>警告(Alerts)
警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加一个 ...
- Bootstrap<基础十五> 输入框组
Bootstrap 支持的另一个特性,输入框组.输入框组扩展自 表单控件.使用输入框组,可以很容易地向基于文本的输入框添加作为前缀和后缀的文本或按钮. 通过向输入域添加前缀和后缀的内容,您可以向用户输 ...
- 解剖SQLSERVER 第十五篇 SQLSERVER存储过程的源文本存放在哪里?(译)
解剖SQLSERVER 第十五篇 SQLSERVER存储过程的源文本存放在哪里?(译) http://improve.dk/where-does-sql-server-store-the-sourc ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十五):消息加密
前不久,微信的企业号使用了强制的消息加密方式,随后公众号也加入了可选的消息加密选项.目前企业号和公众号的加密方式是一致的(格式会有少许差别). 加密设置 进入公众号后台的“开发者中心”,我们可以看到U ...
- 十五个常用的jquery代码段【转】
好的文章顶一个 回到顶部按钮 通过使用 jQuery 中的 animate 和 scrollTop 方法,你无需插件便可创建一个简单地回到顶部动画: 1 // Back to top 2 $('a.t ...
随机推荐
- url的反向解析
1. url的语法格式: url(regex, views, **kwargs, name) name:为地址起别名,反向解析时使用 2.反向解析 对于Django中的url反向解析,是分模板和视图的 ...
- java.lang.IllegalArgumentException: An invalid domain [.test.com] was specified for this cookie
https://blog.csdn.net/cml_blog/article/details/52135115 当项目中使用单点登录功能时,通常会使用cookie进行信息的保存,这样就可以在多个子域名 ...
- 逍遥大佬分享mysql知识
设计表规则: 0),数据库名字以db_开始,编码UTF8 1),表名都以tb_开始 2),字段都是用小写,比如是否删除is_delete 3),表都是innodb,utf8格式的 4),最重要的,表名 ...
- 从 Godaddy 转移域名到 Namesilo
域名本来是在 Godaddy 上注册的,首付很便宜,但是续费时发现是个坑,续费一年是 102 元,再加上隐私保护 60元/年,总共一年需要 160 元,续费贵而且一点优惠也没. 对比下其他商家一年只要 ...
- 你不知道的JavaScript(下卷) (Kyle Simpson 著)
第一部分 起步上路 第1章 深入编程 1.1 代码 1.2 表达式 1.3 实践 1.3.1 输出 1.3.2 输入 1.4 运算符 1.5 值与类型 1.6 代码注释 1.7 变量 1.8 块 1. ...
- C#中如何实现json转化时只处理部分属性
把对象转化为json字符串,很常用,但如果因为现在大部分项目都是用了ORM映射,导致一个对象的属性特别多,如果前台只需要部分属性如何实现? 当然最简单是所有属性都json化,前台只处理需要的属性,多余 ...
- python之路---07 join() fromkeys() 深浅拷贝
二十四.基本数据类型补充 1.join() "*".join("马虎疼") # 马*虎*疼 把传递进去的参数进行迭代. 获取到的每个元素和前面的*进行拼接. ...
- java对文件操作之实用
创建文件 package com.pre; import java.io.File; public class WJ { public static void main(String[] args) ...
- maven默认本地仓库
本地仓库是远程仓库的一个缓冲和子集,当你构建Maven项目的时候,首先会从本地仓库查找资源,如果没有,那么Maven会从远程仓库下载到你本地仓库.这样在你下次使用的时候就不需要从远程下载了.如果你所需 ...
- C166 结构按字节访问的设置
PACK Compiler Directive Home » Compiling Programs » Directives » Reference » PACK Abbreviation None. ...