Qt——QTableWidget 与 QTableView开发实践【不负此行!】

流程图

继承
环境
QTableWidget
QTableView
区别

环境

开发环境
Windows7操作系统
Qt 5.8C++GUI框架
MinGW 5.3.0 32bit编译器
Qt Creator 4.2.1编辑器

QTableWidget

实现基本功能

参考:
Qt QTableWidget的用法详解
Qt QTableWidget用法总结

设置不可编辑

整个表格不可编辑

函数原型:void setEditTriggers(EditTriggers triggers);
头文件:qabstractitemview.h
说明:参数一表示填入EditTrigger枚举

ui->aTabWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

在这里插入图片描述

若你没有ui界面,想用代码实现,也是可以的:替代这段“ui->aTabWidget->”伪代码即可
在这里插入图片描述

    QTableWidget *t = new QTableWidget(this);
    t->setEditTriggers(QAbstractItemView::NoEditTriggers);

PS:

  • 定义的QTableWidget对象一定要是“指针变量”
  • new的时候,把this作为父窗口,表格才会出现在窗口中

隐藏表头

其实就是:设置是否 可见 或者 设置 隐藏
PS:

在这里插入图片描述

隐藏列表头

horizontal Header水平的 头部——列表头

函数原型 头文件
QHeaderView *horizontalHeader() const; qtableview.h
void setVisible(bool v) Q_DECL_OVERRIDE; qheaderview.h
void hide(); qwidget.h
void setHidden(bool hidden); qwidget.h
ui->aTabWidget->horizontalHeader()->setVisible(false);

或

ui->aTabWidget->horizontalHeader()->hide();

或

ui->aTabWidget->horizontalHeader()->setHidden(true);

隐藏行表头

vertical Header垂直的 头部——行表头

函数原型:QHeaderView *verticalHeader() const;
头文件:qtableview.h

ui->aTabWidget->verticalHeader()->setVisible(false);

或

ui->aTabWidget->verticalHeader()->hide();

PS:隐藏行表头与隐藏列表头差不多,大同小异。

设置列宽、行高

没有列高、行宽的概念(即使有,也是不对的,请准守规范),也没有这样的函数;
所以是设置列宽行高

在这里插入图片描述

设置列宽

函数原型:void setColumnWidth(int column, int width);
头文件:(居然是在这里?请看PS:解释)qtableview.h
说明:参数一表示列的 下标,参数二表示 设置指定列的宽度(单位应该是像素)。

ui->aTabWidget->setColumnWidth(3, 140);

或

ui->aTabWidget->QTableWidget::setColumnWidth(3, 140);
[自动找QTableView::setColumnWidth( , )函数]

PS:

实际上
setColumnWidth函数用的不是QTableWidget里的而是QTableView里的!
在官方文档中
可知,QTableWidget类里并没有该函数,还有这个setRowHeight函数,它也没有!!!
为什么会这样?
因为QTableWidget继承了QTableView,可以理所当然地使用父类的函数!

设置行高

函数原型:void setRowHeight(int row, int height);
头文件:qtableview.h
说明:参数一表示行的 下标,参数二表示 设置指定行的高度。

    ui->aTabWidget->setRowHeight(0,35);

设置表头字体居中

其实,表头字体默认(水平或垂直方向的)居中!
AlignmentFlag枚举的属性定义,如图所示:

在这里插入图片描述

PS:
最后一个属性:
AlignCenter = AlignVCenter | AlignHCenter
表示:水平及垂直方向都居中

设置列表头字体居中

列表头字体默认水平方向居中,只能设置:AlignLeft、AlignRight、AlignHCenter等属性。若执意设置垂直方向的属性,显示情况:相当于文本设置AlignLeft

    ui->aTabWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);

设置行表头字体居中

行表头字体默认垂直方向居中,只能设置:AlignTop、AlignBottom、AlignVCenter等属性。若执意设置水平方向的属性,显示情况:相当于文本设置AlignTop

ui->aTabWidget->verticalHeader()->setDefaultAlignment(Qt::AlignVCenter);

其他

参考:

  1. QT任意组件的(文字)对齐方式——alignment 属性setAlignment()
  2. enum Qt::AlignmentFlag——Qt文档

e.g:
若设置水平居右 或 垂直底部,换属性即可:

ui->aTabWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignRight);
ui->aTabWidget->verticalHeader()->setDefaultAlignment(Qt::AlignBottom);

合并单元格

函数原型:void setSpan(int row, int column, int rowSpan, int columnSpan);
头文件:qtableview.h
说明:参数一与参数二都填入 下标;参数一表示单元格的行,参数二表示单元格的列,参数三表示合并行数,参数表示合并列数。

ui->aTabWidget->setSpan(0,1,2,1);
ui->aTabWidget->setSpan(0,2,2,1);

在这里插入图片描述

参考:
QTableWidget表格合并若干问题及解决方法

延伸:合并表头

因为没有这方面需求,并没有测试,在找合并单元格时不小心看到的文章:

QT QTableView QTableWidget 复杂表头(多行表头) 、(冻结、固定特定的行)
QT+qtablewidget自定义表头【合并单元格】

清空表格内容

函数原型:void clearContents();
头文件:qtablewidget.h

ui->aTabWidget->clearContents();

QTableWidgetItem

将值写入表格指定单元格中

函数原型:void setItem(int row, int column, QTableWidgetItem *item);
头文件:qtablewidget.h
说明:参数一与参数二都填入 下标;参数一表示单元格的行,参数二表示单元格的列,参数三表示传入指定Value的QTableWidgetItem 指针变量。

QTableWidgetItem *item = new QTableWidgetItem(value);
ui->aTabWidget->setItem(0,0,item);

设置值居中(水平、垂直)

函数原型:inline void setTextAlignment(int alignment)
{ setData(Qt::TextAlignmentRole, alignment); }
头文件:qtablewidget.h

有了上面水平方向垂直方向 居中代码基础,在此,容易看得懂这里的代码:

QTableWidgetItem *item = new QTableWidgetItem(value);
item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
ui->aTabWidget->setItem(0,0,item);

设置字体颜色

函数原型:inline void setForeground(const QBrush &brush)
{ setData(Qt::ForegroundRole, brush); }
头文件:qtablewidget.h

QTableWidgetItem *item = new QTableWidgetItem(value);
//把表格的item的文字颜色设置为红色
item->setForeground(QBrush(QColor(255, 0, 0)));
ui->aTabWidget->setItem(0,0,item);

参考:QT控制选中item的文字颜色(Highlighted Text)

获取单元格内容

函数原型:QTableWidgetItem *item(int row, int column) const;
头文件:qtablewidget.h
说明:参数一与参数二都填入 下标;参数一表示单元格的行,参数二表示单元格的列。
函数原型:inline QString text() const
{ return data(Qt::DisplayRole).toString(); }
头文件:qtablewidget.h

QString value = ui->aTabWidget->item(row,column)->text();

单元格设置复选框

参考:

  1. Qt — tableWidget插入复选框
  2. QTableWidget中添加checkbox,并相应触发函数

函数原型: inline void setCheckState(Qt::CheckState state)
{ setData(Qt::CheckStateRole, state); }
头文件:qtablewidget.h
说明:参数一表示填入CheckState枚举的属性。

在这里插入图片描述

QTableWidgetItem *check=new QTableWidgetItem;
check->setCheckState (Qt::Checked);//或Unchecked
ui->aTabWidget->setItem(0,2,check); //插入复选框

QTableView

  • QTableView Class
    你会发现,与QTableWidget有些出入,因此,重复的说明我就不多说了,没有提到的,我再附上说明,若还有不懂的地方,请在评论区告诉我 或者 私聊我

前提:创建了xxxUI界面,在里面设置了aTabView

实现基本功能

参考:Qt GUI图形图像开发之Qt表格控件QTableView简单使用方法及QTableView与QTableWidget区别

设置不可编辑

整个表格不可编辑

ui->aTabView->setEditTriggers(QAbstractItemView::NoEditTriggers);

某行或某列只读

网上查到的代码1,还真管用!

因为qt库中没有设置指定列或行只读的函数,需要继承QItemDelegate自定义一个只读委托类,实现“指定列或行只读

在已有的头文件lookoverpartdata.h中加上这些代码:【然后可以在其他类的cpp或者lookoverpartdata.cpp中定义并使用】

#include <QItemDelegate>

class ReadOnlyDelegate: public QItemDelegate
{

public:
    ReadOnlyDelegate(QWidget *parent = NULL):QItemDelegate(parent){}

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override //final
    {
        Q_UNUSED(parent)
        Q_UNUSED(option)
        Q_UNUSED(index)
        return NULL;
    }
};

在这里插入图片描述

某列不可编辑

函数原型:void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate);
头文件:qabstractitemview.h
说明:参数一表示列的 下标,参数二表示 QAbstractItemDelegate 指针变量。

ReadOnlyDelegate* readOnlyDelegate = new ReadOnlyDelegate();
ui->aTabView->setItemDelegateForColumn(2, readOnlyDelegate); //设置某列只读
某行不可编辑

函数原型:void setItemDelegateForRow(int row, QAbstractItemDelegate *delegate);
头文件:qabstractitemview.h
说明:参数一表示行的 下标,参数二表示 QAbstractItemDelegate 指针变量。

ReadOnlyDelegate* readOnlyDelegate = new ReadOnlyDelegate();
ui->aTabView->setItemDelegateForRow(0, readOnlyDelegate);    //设置某行只读

隐藏表头

隐藏列表头

ui->aTabView->horizontalHeader()->setVisible(false);

或

ui->aTabView->horizontalHeader()->hide();

或

ui->aTabView->horizontalHeader()->setHidden(true);

隐藏行表头

ui->aTabView->verticalHeader()->setVisible(false);

或

ui->aTabView->verticalHeader()->hide();

固定、自适应宽度或高度

枚举常量 描述
QHeaderView::Interactive 0 用户可以重新调整表头的大小,也可以使用resizeSection()重新调整表头的大小。目前我的TabView默认这个常量。
QHeaderView::Stretch 1 表头将会调整单元格到可得的空间。用户或者程序员通过代码都不能改变它的大小
QHeaderView::Fixed 2 用户不可以重新调整表头的大小,只可以使用resizeSection()重新调整表头的大小
QHeaderView::ResizeToContents 3 表头将自动根据整个行或者列的内容去调整表头单元格到最佳的大小。用户或者程序员通过代码都不能改变它的大小

在这里插入图片描述

固定或自适应宽度

函数原型:void setSectionResizeMode(ResizeMode2 mode);
头文件:qheaderview.h
说明:horizontalHeader()->指向该函数,表示 水平表头/列表头不可伸缩宽度。

固定宽度:

#include <QHeaderView>

ui->aTabView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

PS:
固定宽度,在列表头,就不会出现“伸缩”指针/光标(如图所示)了。

在这里插入图片描述

自适应宽度:

#include <QHeaderView>

ui->aTabView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

执行后的模样:

在这里插入图片描述

填值后:

在这里插入图片描述

看得出,起到了 自适应 作用。

PS:

  • 当写入单元格的内容出现过长时会自适应列宽加大,因此会出现底部滚动条。
  • 宽度根据内容变化,高度可以自己鼠标移动“伸缩”指针/光标来调整

固定或自适应高度

函数原型:void setSectionResizeMode(ResizeMode2 mode);
头文件:qheaderview.h
说明:verticalHeader()->指向该函数,表示 垂直表头/行表头不可伸缩高度。

固定高度:

#include <QHeaderView>

ui->aTabView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);

PS:
固定高度,在行表头,就不会出现“伸缩”指针/光标了。

自适应高度:

#include <QHeaderView>

ui->aTabView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

执行后的模样:

在这里插入图片描述

填值后:

在这里插入图片描述

看得出,起到了 自适应 作用,但要包含中文的内容,才可以自动将多余的值换行

PS:

  • 高度根据内容变化,宽度可以自己鼠标“伸缩”指针/光标来调整。
  • 若写了该代码,还写了自适应宽度代码,效果:只能自适应宽度,不能自适应高度,而且宽度与高度都不能自己鼠标“伸缩”指针/光标来调整。

设置表格背景网格线

参考:Qt之QTableView的使用

函数原型:void setShowGrid(bool show);
头文件:qtableview.h
说明:参数一表示背景网格线是否设置,true为显示,false为取消。
函数原型:void setGridStyle(Qt::PenStyle style);
头文件:qtableview.h
说明:参数一表示网格背景画笔设置,填入Qt::PenStyle枚举中的值

在这里插入图片描述

常量 描述
Qt::NoPen 0 无线
Qt::SolidLine 1 实线(默认)
Qt::DashLine 2 虚线
Qt::DotLine 3 点线
Qt::DashDotLine 4 虚点线
Qt::DashDotDotLine 5 虚点点线
Qt::CustomDashLine 6 自定义虚线
ui->aTabView->setShowGrid(true);
ui->aTabView->setGridStyle(Qt::DotLine);

DotLine点线:

在这里插入图片描述

SolidLine实线:

在这里插入图片描述

DashDotDotLine虚点点线:

在这里插入图片描述

QStandardItemModel

自定义列表头内容

默认的表头都是按数字顺序自增的"1 2 3";若想设置表头为自己指定的格式,这时要用上QStandardItemModel了;表头内容位置默认居中。

在这里插入图片描述

函数原型:void setHorizontalHeaderLabels(const QStringList &labels);
头文件:qstandarditemmodel.h
说明:参数一表示传入QStringList对象变量。

#include <QStandardItem>

QStandardItemModel* model = new QStandardItemModel();
QStringList labels = QObject::trUtf8("频率,功率,误差").simplified().split(",");
model->setHorizontalHeaderLabels(labels);//设置自定义表头

在这里插入图片描述

设置单元格内容

函数原型:void setItem(int row, int column, QStandardItem *item);
头文件:qstandarditemmodel.h
说明:参数一与参数二都填入 下标;参数一表示单元格的行,参数二表示单元格的列,参数三表示有值的QStandardItem 指针变量。
函数原型:void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE;
头文件:qtableview.h
说明:参数一表示填入QStandardItemModel结构建模对象,进行数据源绑定,将模式加入TabView表中。
函数原型:void show();
头文件:qwidget.h

#include <QStandardItem>
QStandardItemModel* model = new QStandardItemModel();
QStandardItem* item = new QStandardItem(QString("%1").arg("好"));
model->setItem(0,0,item);

//该行,使用一次即可(进行表与模型的绑定),若后续更改了item,
//可在model->setItem(0,0,item);处作结尾,并且程序不会停止更新更改过的表格内容。
ui->aTabView->setModel(model);
//可以注释,因为在我的UI中已存在该表格,若用代码创建TabView则必须加上该行代码,使用一次即可。
ui->aTabView->show();

设置值居中(水平、垂直)

函数原型:inline void QStandardItem::setTextAlignment(Qt::Alignment atextAlignment)
{ setData(int(atextAlignment), Qt::TextAlignmentRole); }
头文件:qstandarditemmodel.h

有了上面水平方向垂直方向 居中代码基础,在此,容易看得懂这里的代码:

QStandardItemModel* model = new QStandardItemModel();
QStandardItem* item = new QStandardItem(QString("%1").arg("好"));
item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
model->setItem(0,0,item);
ui->aTabView->setModel(model);

设置行、列数量

函数原型:void setRowCount(int rows);
头文件:qstandarditemmodel.h
说明:参数一表示行数量。
函数原型:void setColumnCount(int columns);
头文件:qstandarditemmodel.h
说明:参数一表示列数量。

#include <QStandardItem>.h中定义:QStandardItemModel* model;.cpp中使用:
model = new QStandardItemModel();
model->setColumnCount(3);
model->setRowCount(6);

获取单元格内容

函数原型:QStandardItem *item(int row, int column = 0) const;
头文件:qstandarditemmodel.h
说明:参数一表示行的 下标,参数二表示列的 下标
函数原型:inline QString text() const {
return qvariant_cast(data(Qt::DisplayRole));
}
头文件:qstandarditemmodel.h

#include <QStandardItem>.h中定义:QStandardItemModel* model;.cpp中使用:
model = new QStandardItemModel();
QStandardItem* item = model->item(row,column);
QString value = item->text();

清空表格内容

前提1:
在UI界面的menu中加了“清除”功能,并在相应构造函数,绑定了“信号与槽”:

connect(ui->clearAction,SIGNAL(triggered()),this,SLOT(clearXxx()));

在这里插入图片描述

问:
在clearXxx()槽函数中,怎么写代码呢?————说白了,怎么清空内容呢?
答:
有两种方法:一种是使用QStandardItemModel的removeColumns或removeRows函数;一种是将单元格进行初始化。

前提2:【原来的模样】

在这里插入图片描述

使用QStandardItemModel
  1. 保住行表头
    函数原型:bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE;
    头文件:qstandarditemmodel.h
    说明:参数一表示列的 下标,参数二表示 移除指定数量的列数,连(无论是水平方向还是垂直方向)滚动条都会移除。
#include <QStandardItem>.h中定义:QStandardItemModel* model;.cpp中使用:
model->removeColumns(0,model->columnCount());

在这里插入图片描述

  1. 保住列表头
    函数原型:bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE;
    头文件:qstandarditemmodel.h
    说明:参数一表示行的 下标,参数二表示 移除指定数量的行数,连(无论是水平方向还是垂直方向)滚动条都会移除。
#include <QStandardItem>.h中定义:QStandardItemModel* model;.cpp中使用:
model->removeRows(0,model->rowCount());

在这里插入图片描述

model->removeColumns(0,2);//从0开始,移除2列

在这里插入图片描述

参考:
Qt QTableView 如何清理列表里的数据

初始化

填值后的模样:

在这里插入图片描述

初始化后:【变回原样】

在这里插入图片描述

启用列排序

函数原型:void setSortingEnabled(bool enable);
头文件:qtableview.h
说明:参数一表示传入bool值,若为true,就会开启列排序功能,当前列的数字从高到低 ;默认不排序为false,不启用排序功能。

ui->aTabView->setSortingEnabled(true);

原来的排序(用for输入值,看起来是由低至高,其实并没有排序):
在这里插入图片描述
加入代码后,启用排序功能:
在这里插入图片描述

PS:
必须放在ui->aTabView->setModel(model);后面!!!
否则无效果!!!
【但我印象中,小Demo测试时,无论前后都是有效的。不知道为何现在,项目写好了,放开该代码,必须放入其后面,才起到作用!】

设置列宽、行高

前提:
必须放在ui->aTabView->setModel(model);后面!!!
否则无效果!!!

参考:QT - QTableView表格视图的列宽设置

设置列宽
ui->aTabView->setColumnWidth(3, 140);
设置行高
    ui->aTabView->setRowHeight(0,35);

隐藏某一列

前提:
必须放在ui->aTabView->setModel(model);后面!!!
否则无效果!!!

函数原型:void setSectionHidden(int logicalIndex, bool hide);
头文件:qheaderview.h
说明:参数一表示列的 下标,参数二表示是否隐藏,true为是,false为否。

ui->aTabView->horizontalHeader()->setSectionHidden(1,true);

单元格设置复选框

参考:

  1. Qt 之 QTableView 添加复选框(QAbstractTableModel)
  2. qt QTableView中嵌入复选框CheckBox 的四种方法总结

不像QTableWidget,有QTableWidgetItem的 setCheckState函数;
但方法总比困难多,可以通过 QStandardItem的setCheckState函数 或QTableModel类 或 委托 间接实现。
【我没有这方面需求,所以并没有实践,但在此编辑,方便后续操作(回看)】

  • 利用委托重载createEditor(),激活QCheckBox。
  • 自定义模型QAbstractTableModel,通过flags()函数来实现。
  • 自定义委托QAbstractItemDelegate,通过paint()函数来实现。
  • 使用QTableView的setIndexWidget(const QModelIndex &index, QWidget *widget)来实现。
  • 我看到 QStandardItem 有 setCheckState函数。

函数原型:inline void QStandardItem::setCheckState(Qt::CheckState acheckState)
{ setData(acheckState, Qt::CheckStateRole); }
头文件:qstandarditemmodel.h
说明:参数一表示填入CheckState枚举的属性。

在这里插入图片描述

点击单元格,能立马获取或写入值

按以往经验,要么用委托,要么用监视器,要么用过滤器,但网上只提供 过滤器的。
虽然只有过滤器的,但我认为QStandardItemModel的itemChanged事件或许更好些。
因为我不着急这个功能,所以并没有进行实践,测试代码可行度,待我归来,便会落实:

  1. QT事件过滤获取tableView的currentIndex
  2. 当QStandardItemModel itemChanged发出信号时,究竟发生了什么变化

QTableWidget 与 QTableView 的区别

参考:

  1. QTableView与QTableWidget高阶使用积累
  2. QTableWidget与QTableView的区别

区别一

在这里插入图片描述
----------------------------------------And--------------------------------------------
在这里插入图片描述

QTableWidget继承了QTableView,则QTableView是QTableWidget的父类,而QTableWidget是QTableView的子类。

因为继承特性,QTableWidget比QTableView要多样化,除了QTableView私有的宏,QTableWidget大都含有QTableView。

区别二

但是QSqlTableModel能与QTableView绑定,但不能于QTableWidget绑定。

区别三

QTableView可以使用自定义的数据模型来显示内容(也就是先要通过setModel来绑定数据源),
而QTableWidget则只能使用标准的数据模型,并且其单元格数据是QTableWidgetItem的对象来实现的(也就是不需要数据源,将逐个单元格内的信息填好即可)。

在这里插入图片描述

区别四

使用QTableWidget就离不开QTableWidgetItem。QTableWidgetItem用来表示表格中的一个单元格,整个表格都需要用逐个单元格构建起来。

QTableWidgetItem *item = new QTableWidgetItem(strValue);
ui->aTabWidget->setItem(0,1,item);

使用QTableView也离不开QStandardItemModel与QStandardItem。

QStandardItemModel* model = new QStandardItemModel();
QStandardItem* item = new QStandardItem(strValue);
model->setItem(0,0,item);

ui->aTabView->setModel(model);

区别五

在QTableView类中有setModel成员函数,而到了QTableWidget类中,该成员函数变成了私有,不难使用该函数设置数据模型。

在这里插入图片描述
在这里插入图片描述

区别六

QTableView没有函数实现复选框,要通过QStandardItem的setCheckState函数或QTableModel类或委托间接实现,而QTableWidgetItem类中的setCheckState(Qt::Checked);可以直接设置复选框。

QTableWidgetItem *check=new QTableWidgetItem;
check->setCheckState (Qt::Checked);//或Unchecked
ui->aTabWidget->setItem(0,2,check); //插入复选框

  1. QTableview设置某行某列不可编辑(只读,委托) ↩︎

  2. QHeaderView Class——Qt文档 ↩︎ ↩︎

  3. QStandardItemModel使用技巧QStandardItemModel Class——Qt文档 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章