QTableWidget使用总结
QTableWidget说明
1、QTableWidget 是 Qt 中的表格组件类;
2、QTableWidget是QTableView的子类,主要的区别是QTableView可以使用自定义的数据模型来显示内容(也就是先要通过setModel来绑定数据源);
3、而QTableWidget则只能使用标准的数据模型,并且其单元格数据是QTableWidgetItem的对象来实现的(也就是不需要数据源,将逐个单元格内的信息填好即可)。
4、主要体现在QTableView类中有setModel成员函数,而到了QTableWidget类中,该成员函数变成了私有。使用QTableWidget就离不开QTableWidgetItem。QTableWidgetItem用来表示表格中的一个单元格,正个表格都需要用逐个单元格构建起来。
表格组件样式如下
一、设置表格行列数
ui->tableWidget->setRowCount(25); // 设置表格行数
ui->tableWidget->setColumnCount(9); // 设置表格列数
二、设置表头
QStringList labelList;
labelList.append(QString("设备MAC"));
labelList.append(QString("流水号-年"));
labelList.append(QString("流水号-月"));
labelList.append(QString("流水号-批次"));
labelList.append(QString("流水号-编号"));
ui->tableWidget->setHorizontalHeaderLabels(labelList); // 设置表头
三、设置列宽行宽
ui->tableWidget->setColumnWidth(0,135); // 设置第一列 列宽135
ui->tableWidget->setRowHeight(0,20); // 设置第一行 行高20
四、设置表格内容是否可被编辑
1、可选属性
属性 | 说明 |
---|---|
QAbstractItemView::NoEditTriggers | 不能对表格内容进行修改 |
QAbstractItemView::CurrentChanged | 任何时候都能对单元格修改 |
QAbstractItemView::DoubleClicked | 双击单元格可修改 |
QAbstractItemView::SelectedClicked | 单击已选中的内容修改 |
QAbstractItemView::EditKeyPressed | 编辑键放在单元格时修改 |
QAbstractItemView::AnyKeyPressed | 按下任意键修改 |
QAbstractItemView::AllEditTriggers | 以上全部 |
2、整个表格进行设置
ui->tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked); // 设置表格内容双击可编辑
3、设置部分单元格编辑模式
/* ---------- 列表给定一个初值(否则ui设计师界面创建的表格使用部分函数会崩溃!!!) ---------- */
for(int i = 0; i < ui->tableWidget->rowCount(); i++)
{
for(int j = 0; j < ui->tableWidget->columnCount(); j++)
{
QTableWidgetItem *item1 = new QTableWidgetItem(" "); // 新建一个项,写入一个空格
item1->setFlags(item1->flags() & (~Qt::ItemIsEditable)); // 设置可选不可改,当单元格被编辑后要重新设置
ui->tableWidget->setItem(i, j, item1); // 更新到列表对应位置
}
}
五、获取/写入单元格数据
1、获取单元格数据
QString str = ui->tableWidget->item(0,0)->text(); // 取出字符串 列表第1行 第1列
2、写入单元格数据
QTableWidgetItem *itemStatus = new QTableWidgetItem("待测试"); // 新建一个项
itemStatus->setFlags(itemStatus->flags() & (~Qt::ItemIsEditable)); // 设置可选不可改
ui->tableWidget->setItem(0, 0, itemStatus); // 更新到列表第1行 第1列
六、单元格添加控件-按钮
1、添加控件
QPushButton *linkBtn = new QPushButton; // 创建按钮
linkBtn->setText(QString("连接设备")); // 设置按钮名称
ui->tableWidget->setCellWidget(0, 0, linkBtn); // 更新到列表 第1行 第1列
2、控件信号槽使用
/* --------------- 对应按钮的槽函数 --------------- */
connect(linkBtn, &QPushButton::clicked, this, [=]()
{
qDebug() << "点击按键连接";
// 获取按钮所在行 列
QModelIndex qIndex = ui->tableWidget->indexAt(QPoint(linkBtn->frameGeometry().x(), linkBtn->frameGeometry().y()));
// 获取当前按钮所在的行和列
int row = qIndex.row();
int column = qIndex.column();
qDebug() << "行:" << row << "列:" << column;
});
3、删除控件
注意同一个单元格不能重复添加,不然会崩溃
ui->tableWidget->removeCellWidget(0, 0); // 删除控件 第1行 第1列
七、设置单元格输入内容样式
1、设置字体颜色
ui->tableWidget->item(0, 5)->setTextColor(QColor(220,200,50)); // 设置字体颜色
2、设置字体、大小、粗细
ui->tableWidget->item(itemH, 5)->setFont( QFont( "宋体", 11, QFont::Black )); // 设置宋体、11号、加粗
3、设置单元格背景色
ui->tableWidget->item(itemH, 5)->setBackgroundColor(QColor(0,60,10)); //设置单元格背景颜色
八、限制表格输入内容
该方式是在网上查找的方法,可以不添加控件使用正则表达式,使用时需要新建一个c++类,c文件和h文件如下
1、添加c++文件
#include "customitemdelegrate.h"
CustomItemDelegrate::CustomItemDelegrate(const QRegExp& regExp,QObject* parent) : QStyledItemDelegate(parent)
{
m_regExp = regExp;
}
QWidget* CustomItemDelegrate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
//创建带有正则表达式的输入框
Q_UNUSED(option);
Q_UNUSED(index);
QLineEdit* editor = new QLineEdit(parent);
editor->setValidator(new QRegExpValidator(m_regExp, parent));
return editor;
}
void CustomItemDelegrate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
QString text = index.model()->data(index, Qt::EditRole).toString();
QLineEdit* lineEdit = qobject_cast <QLineEdit*>(editor);
lineEdit->setText(text);
}
void CustomItemDelegrate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(editor);
QString text = lineEdit->text();
model->setData(index, text, Qt::EditRole);
}
2、添加头文件
#ifndef CUSTOMITEMDELEGRATE_H
#define CUSTOMITEMDELEGRATE_H
#include <QWidget>
#include <QStyledItemDelegate>
#include <QLineEdit>
#include <QRegExp>
class CustomItemDelegrate : public QStyledItemDelegate
{
Q_OBJECT
public:
CustomItemDelegrate(const QRegExp& regExp, QObject* parent = nullptr);
~CustomItemDelegrate(void);
QWidget *createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
void setEditorData(QWidget* editor, const QModelIndex& index ) const;
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;
private:
QRegExp m_regExp;
};
#endif // CUSTOMITEMDELEGRATE_H
3、函数调用示例:限制输入1-999
QRegExp regExpNumh("^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$"); // 批次正则表达式
ui->tableWidget->setItemDelegateForColumn(3, new CustomItemDelegrate(regExpNumh)); // 设置第4列限制输入
九、cellChanged信号使用说明
当单元格内容更新时触发该信号,但是任何对单元格的操作都会触发,因此使用时需要注意,设置信号阻塞或是在必要时断开信号槽
/* ---------- 每个列表数据有更新时触发,更新数据格式 ---------- */
connect(ui->tableWidget, &QTableWidget::cellChanged, this, [=]()
{
ui->tableWidget->blockSignals(true); // 进入阻塞模式,必须要加,否则槽函数中对单元格进行设置会出错
for(int i = 0; i < ui->tableWidget->rowCount(); i++)
{
for(int j = 0; j < ui->tableWidget->columnCount(); j++)
{
ui->tableWidget->item(i,j)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); // 设置单元格数据居中
}
/* ---------- 设置批号固定为3位 ---------- */
QString str2 = ui->tableWidget->item(i,3)->text(); // 取出字符串
if(str > "0")
{
QString str3 = QString("%1").arg(str2, 3, QLatin1Char('0')); // 字符串前面补零到3位数
ui->tableWidget->item(i,3)->setText(str3); // 更新到列表
}
}
ui->tableWidget->blockSignals(false); // 退出阻塞模式,必须要加,否则槽函数中对单元格进行设置会出错
});
必要时断开信号槽(可能有更好的办法避免崩溃,这是目前我掌握的一种最无脑的方法)
ui->tableWidget->disconnect(SIGNAL(QTableWidget::cellChanged())); // 断开信号槽
十、其他常用操作
1、设置选择模式
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式
属性 | 说明 |
---|---|
QAbstractItemView::SelectItems | 选中单个单元格 |
QAbstractItemView::SelectRows | 选中一行 |
QAbstractItemView::SelectColumns | 选中一列 |
2、单选、多选设置
主要功能是正常情况下是单选,但按下Ctrl或Shift键后,可以多选
ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //设置为可以选中多个目标
属性 | 说明 |
---|---|
QAbstractItemView::SingleSelection | 只能单个选择 |
QAbstractItemView::ContiguousSelection | 点选或按shift多选 |
QAbstractItemView::ExtendedSelection | 点选或按shift多选,同时可以ctrl点选添加或取消选择 |
QAbstractItemView::MultiSelection | 鼠标点击拖拽方式多选 |
QAbstractItemView::NoSelection | 不可被选中 |
3、表头显示/隐藏
// 对于水平或垂直方法的表头,可以用以下方式进行 隐藏/显示 的设置:
ui->tableWidget->verticalHeader()->setVisible(false); //隐藏列表头
ui->tableWidget->horizontalHeader()->setVisible(false); //隐藏行表头
// 注意:需要 #include <QHeaderView>
4、合并单元格
ui->tableWidget->setSpan(0, 0, 3, 1) // 其参数为: 要改变单元格的 1行数 2列数 要合并的 3行数 4列数
5、 排序
ui->tableWidget->setSortingEnabled(true); // 运行排序
ui->tableWidget->sortItems(0, Qt::DescendingOrder); // 对 0 列排序, 默认升序,注意是对数值排序还是字符串排序
ui->tableWidget->setSortingEnabled(false); // 关闭排序
// 写入数值
int8_t rssi = -60;
ui->tableWidget->item(0,0)->setData(Qt::DisplayRole,rssi);
6、 设置某行高亮
//设定选择行为,按行选择
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
//设置选中行的背景色,必须要显示设置,即代码设置或者在ui文件的控件中设置,用系统默认的是无法代码选中高亮某行
ui->tableWidget->setStyleSheet("selection-background-color:rgb(220,20,60)");
//设置要选中高亮的行,这里会触发QTableWidget::itemClicked的信号
ui->tableWidget->selectRow(1); //具体行号
7、设置隔行换色
ui.tableWidget->setAlternatingRowColors(true);
ui.tableWidget->setStyleSheet("QTableView{background-color: rgb(250, 250, 115);""alternate-background-color: rgb(50, 110, 255);}");
十一、参考链接
链接1: QT(7)_数据表格 QTableWidget 新手学习总结
链接2: QTableWidget使用数据改变信号量cellChange发生死循环
链接3: QTableWidget可编辑设置,设置部分可编辑