文章目录
- 1 属性和方法
- 1.1 行列数目和行表头和列表头
- 1.2 单元格
- 1.3 隔行交替背景色
- 1.4 选择模式和选择行为
- 1.5 设置样式表
- 2 实例
- 2.1 布局
- 2.2 代码实现
QTableWidget
是Qt中的表格控件。
1 属性和方法
QTableWidget
有很多属性和方法,完整的可查看帮助文档。
在窗口上放置一个QTableWidget
控件后,既可以在设计师UI界面来编辑属性和添加数据,也可以在代码中动态地设置
这里列出常用的属性和方法
1.1 行列数目和行表头和列表头
表格控件的第一行称为行表头,用于设置每一列的标题,
表格控件的第一列称为列表头,用于设置每一行的标题,通常缺省则默认显示行号
设置和获取行列的数目
// 获取和设置行的数目
int rowCount() const;
void setRowCount(int rows);
// 获取和设置列的数目
int columnCount() const;
void setColumnCount(int columns);
设置行列表头
// 设置行表头
void setHorizontalHeaderLabels(const QStringList &labels);
// 设置列表头 - 通常不设置,则默认为行号
void setVerticalHeaderLabels(const QStringList &labels)
设置列的宽度
// 获取行表头
QHeaderView *horizontalHeader() const;
// 设置列的宽度
void QHeaderView::setSectionResizeMode(QHeaderView::ResizeMode mode);
其中ResizeMode
是一个枚举,取值如下:
QHeaderView::Interactive
0 用户可拖动改变列宽QHeaderView::Fixed
2 固定列宽QHeaderView::Stretch
1 拉伸自适应列宽大小QHeaderView::ResizeToContents
3 根据内容设置列宽
通常,先整体设置为QHeaderView::Stretch
,然后根据需要对单独的列进行设置,如下:
// 1.先设置自适应宽度,再单独设置某一列的宽度规则
ui->twStudent->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 先自适应宽度
// 2. 然后,单独设置某一列根据内容调整宽度,或者单独设置某一列为固定宽度
// ui->twStudent->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
ui->twStudent->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
ui->twStudent->setColumnWidth(0, 80);
1.2 单元格
每个网格单元称为一个单元格。每个单元格有一个行号、列号。
在QTableWidget
表格控件中,每一个单元格是一个QTableWidgetlitem
对象,可以设置其文字内容等。
获取和设置单元格
// 获取和设置指定行列位置的单元格
QTableWidgetItem *item(int row, int column) const;
void setItem(int row, int column, QTableWidget *item);
// 构造 QTableWidgetItem
QTableWidgetItem(const QIcon &icon, const QString &text, int type = type);
QTableWidgetItem(const QString &text, int type = Type);
单元格文本对齐方式
// 获取和设置单元格文本的对齐方式
int textAlignment() const;
void setTextAlignment(int alignment);
参数alignment
是一个枚举类型,常用取值如下:
Qt::AlignLeft
(0x0001) 水平方向-左对齐Qt::AlignRight
(0x0002) 水平方向-右对齐Qt::AlignHCenter
(0x0004) 水平方向-居中对齐Qt::AlignTop
(0x0020) 垂直方向-上对齐Qt::AlignBottom
(0x0040) 垂直方向-下对齐Qt::AlignVCenter
(0x0080) 垂直方向-居中对齐Qt::AlignCenter
(AlignVCenter|AlignHCenter)
垂直方向和水平方向-居中对齐
上面的每一个宏,都代表16进制中的一位,可以进行或(1)操作,来同时设置多个对齐方式。
单元格是否可编辑
// 获取和设置单元格是否可编辑
QAbstractItemView::EditTriggers editTriggers() const;
void setEditTriggers(QAbstractItemView::EditTriggers triggers);
这是继承自其父类QAbstractItemView
中的方法
其中,QAbstractItemView::EditTriggers
是一个枚举,常用取值如下:
QAbstractItemView::NoEditTriggers
0 不可编辑QAbstractItemView::CurrentChanged
1 当切换单元格时QAbstractItemView::DoubleClicked
2 当双击单元格时QAbstractItemView::SelectedClicked
4 当单击一个已选中的单元格时QAbstractItemView::EditKeyPressed
8 当一个单元格获取焦点,按编辑按键时(F2)QAbstractItemView::AnyKeyPressed
16 当一个单元格获取焦点,按任意键时QAbstractItemView::AllEditTriggers
31 以上所有条件的组合。(31=1|2|4|8|16)
1.3 隔行交替背景色
如下的奇数行和偶数行,它们的背景色不同,便于用户浏览
// 获取和设置是否允许隔行交替背景色
bool alternatingRowColors() const;
void setAlternattingRowColors(bool enable);
这是继承自其父类QAbstractItemView
中的方法
1.4 选择模式和选择行为
所谓选择行为,是指当点击一个单元格时,是选中该单元格,还是选中一整行
// 获取和设置选择行为
QAbstractItemView::SelectionBehavior selectionBehavior() const;
void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior);
这是继承自其父类QAbstractItemView
中的方法
其中QAbstractItemView::SelectionBehavior
是一个枚举,取值为:
QAbstractItemView::SelectItems
0 选中单元格QAbstractItemView::SelectRows
1 选中单元格所在行QAbstractItemView::SelectColumns
2 选中单元格所在列
所谓选择模式,是指设置表格控件只可选择单行、可选择多行等。
// 获取和设置选择模式
QAbstractItemView::SelectionMode selectionMode() const;
void setSelectionMOde(QAbstractItemView::SelectionMode mode);
这是继承自其父类QAbstractItemView
中的方法
- QAbstractItemView::NoSelection 0 不可选择
- QAbstractItemView::SingleSelection 1 单行选择,一次只允许选择一行
- QAbstractItemView::MultiSelection 2 多行选择,鼠标单击就可以选择多行
- QAbstractItemView::ExtendedSelection 3 扩展选择,按shift键选中一个范围内的行,ctrl键可以选中不相邻的行
- QAbstractItemView::ContiguousSelection 4 相邻选择,按shift键或ctrl键都可以选中一个范围内的行
1.5 设置样式表
通过设置样式表,可以使的表格控件更加美观
void Widget::on_btnStyleSheet_clicked() {
QString cellStyle = R"(
QTableView
{
text-align:center;
background-color: rgba(255, 255, 255, 0);
alternate-background-color:#e3edf9;
font:14px "微软雅黑";
color:#677483;
gridline-color: #ccddf0;
}
)";
const QString horizontalHeaderStyle = R"(
QHeaderView::section {
color: black;
font:bold 14px "微软雅黑";
text-align:center;
height:32px;
background-color: #d1dff0;
border:1px solid #8faac9;
border-left:none;
}
)";
const QString verticalHeaderStyle = R"(
QHeaderView::section {
color: black;
font:bold 14px "微软雅黑";
width:60px;
text-align:center;
background-color: #d1dff0;
border:1px solid #8faac9;
border-left:none;
}
)";
ui->twStudent->setStyleSheet(cellStyle);
ui->twStudent->horizontalHeader()->setStyleSheet(horizontalHeaderStyle);
ui->twStudent->verticalHeader()->setStyleSheet(verticalHeaderStyle);
}
以上R包裹的字符串,就是C++中的原始字符串
原始字符串,就是所见即所得,不用写难以理解的转义字符。
2 实例
本实例展示表格控件的以下操作:
- 行表头的设置
- 列表头的设置
- 交替显示背景色
- 单元格可编辑
- 设置样式表
- 选择行为:单元格选择或行选择
- 数据的增删改查
2.1 布局
在U设计师界面,拖拽对应的控件,修改显示的文字、控件的name,然后完成布局
2.2 代码实现
// 在Widget.h 中
#ifndef WIDGET_H
#define WIDGET_H
#include <QButtonGroup>
#include <QString>
#include <QStringList>
#include <QTableWidgetItem>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
void appendOneRow(QString name, QString gender, int age, QString province);
void onSelectionRadioButtonClicked();
void onItemClicked(QTableWidgetItem *);
void insertOneRow(int, QString, QString, int, QString);
~Widget();
private slots:
void on_btnAppend_clicked();
void on_btnInsert_clicked();
void on_btnDelete_clicked();
void on_btnModify_clicked();
void on_btnStyleSheet_clicked();
private:
Ui::Widget *ui;
QButtonGroup *mButtonGroupSelect;
};
#endif // WIDGET_H
// 在Widget.cpp 中
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {
ui->setupUi(this);
// 1. 初始化列表
// 1.1 添加4 列
ui->twStudent->setColumnCount(4);
QStringList horizontalList;
horizontalList << "姓名"
<< "性别"
<< "年龄"
<< "籍贯";
ui->twStudent->setHorizontalHeaderLabels(horizontalList);
// 1.2 设置列的宽度先 获取行表头 填充满
ui->twStudent->horizontalHeader()->setSectionResizeMode(
QHeaderView::Stretch);
// 1.3 添加几行初始化数据
appendOneRow("李磊", "男", 15, "江西");
appendOneRow("李安安", "女", 16, "代西");
appendOneRow("李发放", "男", 18, "广西");
appendOneRow("李呃呃", "女", 19, "单西");
appendOneRow("李单独", "男", 13, "得西");
// 2. 设置行表头是否显示
// 初始化
// if 用来判断行表头是否隐藏 隐藏返回true
if (ui->twStudent->horizontalHeader()->isHidden()) {
// 隐藏 设置复选框 取消勾选 (false)
ui->cboHHeader->setChecked(false);
} else {
// 行表头显示 设置复选框勾选
ui->cboHHeader->setChecked(true);
}
// 复选框 与 行表头连接
connect(ui->cboHHeader, &QCheckBox::stateChanged, this, [=](int state) {
// 当复选框状态变化 判断复选框是否选中状态
// 当选中状态
if (state == Qt::Checked) {
// 显示行表头
ui->twStudent->horizontalHeader()->show();
} else if (state == Qt::Unchecked) {
// 隐藏行表头
ui->twStudent->horizontalHeader()->hide();
}
});
// 3. 设置列表头是否显示
// 初始化
// if 用来判断列表头是否隐藏 隐藏返回true
if (ui->twStudent->verticalHeader()->isHidden()) {
// 隐藏 设置复选框 取消勾选 (false)
ui->cboVHeader->setChecked(false);
} else {
// 列表头显示 设置复选框勾选
ui->cboVHeader->setChecked(true);
}
// 复选框 与 列表头连接
connect(ui->cboVHeader, &QCheckBox::stateChanged, this, [=](int state) {
// 当复选框状态变化 判断复选框是否选中状态
// 当选中状态
if (state == Qt::Checked) {
// 显示列表头
ui->twStudent->verticalHeader()->show();
} else if (state == Qt::Unchecked) {
// 隐藏列表头
ui->twStudent->verticalHeader()->hide();
}
});
// 4. 设置交替显示背景色
// 初始化
// 如果返回true 背景色是显示的
if (ui->twStudent->alternatingRowColors()) {
// 如果背景色显示,复选框勾选上
ui->cboAlternate->setChecked(true);
} else {
// 如果背景色不显示,复选框不勾选
ui->cboAlternate->setChecked(false);
}
// 进行复选框 连接
connect(ui->cboAlternate, &QCheckBox::stateChanged, this, [=](int state) {
// 判断是否勾选
if (state == Qt::Checked) {
// 勾选 设置交替背景色
ui->twStudent->setAlternatingRowColors(true);
} else if (state == Qt::Unchecked) {
// 没有勾选 设置不交替背景色
ui->twStudent->setAlternatingRowColors(false);
}
});
// 5. 单元格是否可编辑
// 获取可编辑状态
int trigger = ui->twStudent->editTriggers();
// 如果不可编辑 取消复选框勾选
if (trigger == QAbstractItemView::NoEditTriggers) {
ui->cboEditCell->setChecked(false);
} else {
// 否则 可编辑 初始化复选框勾选
ui->cboEditCell->setChecked(true);
}
// 进行复选框 连接
connect(ui->cboEditCell, &QCheckBox::stateChanged, this, [=](int state) {
// 判断是否勾选
if (state == Qt::Checked) {
// 勾选 设置可编辑状态
ui->twStudent->setEditTriggers(QAbstractItemView::DoubleClicked |
QAbstractItemView::SelectedClicked |
QAbstractItemView::EditKeyPressed);
} else if (state == Qt::Unchecked) {
// 没有勾选 设置不可编辑状态
ui->twStudent->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
});
// 6. 设置单元格选择,还是行选择
int selectionBehavior = ui->twStudent->selectionBehavior();
// 判断选择是否是选中的单元格 选择单元格 复选框勾选
if (selectionBehavior == QAbstractItemView::SelectItems) {
ui->rbCell->setChecked(true);
} else if (selectionBehavior == QAbstractItemView::SelectRows) {
// 判断选择是否是选中的行 选择行 复选框勾选
ui->rbRow->setChecked(true);
}
mButtonGroupSelect = new QButtonGroup(this);
mButtonGroupSelect->addButton(ui->rbCell, 0);
mButtonGroupSelect->addButton(ui->rbRow, 1);
connect(ui->rbCell, &QRadioButton::clicked, this,
&Widget::onSelectionRadioButtonClicked);
connect(ui->rbRow, &QRadioButton::clicked, this,
&Widget::onSelectionRadioButtonClicked);
// 7. 点击单元格时,将数据显示到文本框
connect(ui->twStudent, &QTableWidget::itemClicked, this,
&Widget::onItemClicked);
}
void Widget::appendOneRow(QString name, QString gender, int age,
QString province) {
// 获取当前行数
int count = ui->twStudent->rowCount();
// 在表格基础上行数增加一行 ,用来添加数据
ui->twStudent->setRowCount(count + 1);
QTableWidgetItem *nameItem = new QTableWidgetItem(name);
QTableWidgetItem *genderItem = new QTableWidgetItem(gender);
QTableWidgetItem *ageItem = new QTableWidgetItem(QString::number(age));
QTableWidgetItem *provinceItem = new QTableWidgetItem(province);
// 设置居中显示
nameItem->setTextAlignment(Qt::AlignCenter);
genderItem->setTextAlignment(Qt::AlignCenter);
ageItem->setTextAlignment(Qt::AlignCenter);
provinceItem->setTextAlignment(Qt::AlignCenter);
// 第一个参数代表行 第二个代表列
ui->twStudent->setItem(count, 0, nameItem);
ui->twStudent->setItem(count, 1, genderItem);
ui->twStudent->setItem(count, 2, ageItem);
ui->twStudent->setItem(count, 3, provinceItem);
}
void Widget::onSelectionRadioButtonClicked() {
// 获取选中那个单选框按钮
int checkeId = mButtonGroupSelect->checkedId();
if (checkeId == 0) {
// 当选中单元格时
ui->twStudent->setSelectionMode(QAbstractItemView::SingleSelection);
// 设置选中单元格
ui->twStudent->setSelectionBehavior(QAbstractItemView::SelectItems);
} else {
// 当选中单元格时
ui->twStudent->setSelectionMode(QAbstractItemView::SingleSelection);
// 设置选中行
ui->twStudent->setSelectionBehavior(QAbstractItemView::SelectRows);
}
}
void Widget::onItemClicked(QTableWidgetItem *item) {
// 获取当前选中的行
int row = item->row();
// 获取row行的数据
QString name = ui->twStudent->item(row, 0)->text();
QString gender = ui->twStudent->item(row, 1)->text();
QString age = ui->twStudent->item(row, 2)->text();
QString province = ui->twStudent->item(row, 3)->text();
// 设置到文本框中
ui->leName->setText(name);
ui->leGender->setText(gender);
ui->leAge->setText(age);
ui->leProvince->setText(province);
}
void Widget::insertOneRow(int currentRow, QString name, QString gender, int age,
QString province) {
ui->twStudent->insertRow(
currentRow); // 在currentRow行 插入的是一个空行,需要插入数据
QTableWidgetItem *nameItem = new QTableWidgetItem(name);
QTableWidgetItem *genderItem = new QTableWidgetItem(gender);
QTableWidgetItem *ageItem = new QTableWidgetItem(QString::number(age));
QTableWidgetItem *provinceItem = new QTableWidgetItem(province);
// 设置居中显示
nameItem->setTextAlignment(Qt::AlignCenter);
genderItem->setTextAlignment(Qt::AlignCenter);
ageItem->setTextAlignment(Qt::AlignCenter);
provinceItem->setTextAlignment(Qt::AlignCenter);
// 第一个参数代表行 第二个代表列
ui->twStudent->setItem(currentRow, 0, nameItem);
ui->twStudent->setItem(currentRow, 1, genderItem);
ui->twStudent->setItem(currentRow, 2, ageItem);
ui->twStudent->setItem(currentRow, 3, provinceItem);
}
Widget::~Widget() {
delete ui;
}
void Widget::on_btnAppend_clicked() {
// 获取文本框内容
QString name = ui->leName->text();
QString gender = ui->leGender->text();
int age = ui->leAge->text().toInt();
QString province = ui->leProvince->text();
// 添加一行
appendOneRow(name, gender, age, province);
}
void Widget::on_btnInsert_clicked() {
// 获取文本框内容
QString name = ui->leName->text();
QString gender = ui->leGender->text();
int age = ui->leAge->text().toInt();
QString province = ui->leProvince->text();
// 获取当前选中的行
int currentRow = ui->twStudent->currentRow();
// 插入数据
insertOneRow(currentRow, name, gender, age, province);
}
void Widget::on_btnDelete_clicked() {
// 获取当前选中的行
int currentRow = ui->twStudent->currentRow();
ui->twStudent->removeRow(currentRow);
}
void Widget::on_btnModify_clicked() {
// 获取文本框内容
QString name = ui->leName->text();
QString gender = ui->leGender->text();
int age = ui->leAge->text().toInt();
QString province = ui->leProvince->text();
// 获取当前选中的行
int currentRow = ui->twStudent->currentRow();
QTableWidgetItem *nameItem = new QTableWidgetItem(name);
QTableWidgetItem *genderItem = new QTableWidgetItem(gender);
QTableWidgetItem *ageItem = new QTableWidgetItem(QString::number(age));
QTableWidgetItem *provinceItem = new QTableWidgetItem(province);
// 设置居中显示
nameItem->setTextAlignment(Qt::AlignCenter);
genderItem->setTextAlignment(Qt::AlignCenter);
ageItem->setTextAlignment(Qt::AlignCenter);
provinceItem->setTextAlignment(Qt::AlignCenter);
// 第一个参数代表行 第二个代表列
ui->twStudent->setItem(currentRow, 0, nameItem);
ui->twStudent->setItem(currentRow, 1, genderItem);
ui->twStudent->setItem(currentRow, 2, ageItem);
ui->twStudent->setItem(currentRow, 3, provinceItem);
}
void Widget::on_btnStyleSheet_clicked() {
QString cellStyle = R"(
QTableView
{
text-align:center;
background-color: rgba(255, 255, 255, 0);
alternate-background-color:#e3edf9;
font:14px "微软雅黑";
color:#677483;
gridline-color: #ccddf0;
}
)";
const QString horizontalHeaderStyle = R"(
QHeaderView::section {
color: black;
font:bold 14px "微软雅黑";
text-align:center;
height:32px;
background-color: #d1dff0;
border:1px solid #8faac9;
border-left:none;
}
)";
const QString verticalHeaderStyle = R"(
QHeaderView::section {
color: black;
font:bold 14px "微软雅黑";
width:60px;
text-align:center;
background-color: #d1dff0;
border:1px solid #8faac9;
border-left:none;
}
)";
ui->twStudent->setStyleSheet(cellStyle);
ui->twStudent->horizontalHeader()->setStyleSheet(horizontalHeaderStyle);
ui->twStudent->verticalHeader()->setStyleSheet(verticalHeaderStyle);
}