【qt】QTableWidget 表格组件

QTableWidget 表格组件

一.应用场景

顾名思义,就是我们日常使用的一些表格,可以进行增删改查的功能。

我们还是来跟着一个项目来边做边学。

目标图:

话不多说,直接开肝!

二.初始化表格

1.界面拖放

记得先添加资源哦,需要的可以dd我。

OK,界面我就拖好了,如果不会的,可以跟我说,这个前面一直有讲,应该都会了把,不会的可以看看前面的。

2.设置列数

cpp 复制代码
void MainWindow::initUI()
{
    QStringList headList={"姓名","性别","出生日期","职位","是否已婚"};
    ui->tableWidget->setColumnCount(headList.count());

}

运行结果:

3.表头的处理

①:表头装的是啥

里面是装的QTableWidgetItem,可以理解为一个单元格,可以用我们刚刚的列表来初始化单元格的内容

cpp 复制代码
for(int i=0;i<ui->tableWidget->columnCount();i++)
    {
        QTableWidgetItem*item=new QTableWidgetItem(headList[i]);
    }

②:设置为标头

cpp 复制代码
 for(int i=0;i<ui->tableWidget->columnCount();i++)
    {
        QTableWidgetItem*item=new QTableWidgetItem(headList[i]);       
        ui->tableWidget->setHorizontalHeaderItem(i,item);
        
    }

运行结果:

③:设置列宽的模式

但是现在表头非常的丑陋,不能自适应我们的窗口。

解决方法通过表头视图来设置列宽模式。

cpp 复制代码
QHeaderView*headView= ui->tableWidget->horizontalHeader();//返回表头的视图
    headView->setSectionResizeMode(QHeaderView::Stretch);//可伸展

运行结果:

现在还有个问题,我们明明是表头,肯定要设置一点特殊的字体了

cpp 复制代码
for(int i=0;i<ui->tableWidget->columnCount();i++)
    {
        QTableWidgetItem*item=new QTableWidgetItem(headList[i]);
        ui->tableWidget->setHorizontalHeaderItem(i,item);
        QFont font=item->font();
        font.setPointSize(12);//设置字体大小
        font.setBold(true);//设置字体为粗体
        font.setFamily("微软雅黑");//设置字体样式
        item->setFont(font);
        item->setForeground(Qt::red);//设置字体颜色
    }

运行结果:

nice,有那个味道了。

还可以教大家一个玩法,可以设置表头的固定宽度。

但是在设置的时候,要先将刚刚的扩展模式改正固定的模式。

cpp 复制代码
headView->setSectionResizeMode(1,QHeaderView::Fixed);

这些参赛都可以通过帮助文档来找,前面的1参数就是对第一列有效,也就是性别项。

现在我们就可以来固定大小了

cpp 复制代码
ui->tableWidget->setColumnWidth(1,100);

运行结果:

是不是非常的优雅?

4.设置行数

一个表,有列就当然有行了,接下来,我们来添加行。

cpp 复制代码
 int rows=100;
 ui->tableWidget->setRowCount(rows);

5.添加每个单元格

①:设置单元格信息

我们可以来创建一个函数来实现我们行信息的初始化,这里使用了随机数来模拟我们的数据。

cpp 复制代码
QStringList jobs={"开发商","高级工程师","架构师","程序员","牛马"};
for(int i=0;i<rows;i++)
    {
        MaxNo++;//每创建一行,我就计数加1
        creatRows(i,QString::asprintf("员工%d",MaxNo),MaxNo,rand()%2?"男":"女",
                  QDate(rand()%2000+10,rand()%12+1,rand()%30+1),jobs[rand()%5],rand()%2);
    }

在mainwindow.cpp中添加一个成员函数和一个计数的MaxNo,记得对于时间参数姚家一个头文件。

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDate>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    void initUI();
    int MaxNo;
    void creatRows(int rowNumber,QString name,int number,QString gender,QDate birthday,QString job,bool married);
};
#endif // MAINWINDOW_H

②:添加单元格

基本逻辑就是先创建一个单元格,然后用setItem来加到表格中。

cpp 复制代码
void MainWindow::creatRows(int rowNumber,QString name,int number,QString gender,QDate birthday,QString job,bool married)
{
    QTableWidgetItem*item=new QTableWidgetItem(name);
    item->setData(Qt::UserRole,QVariant(number));//添加附加值
    ui->tableWidget->setItem(rowNumber,0,item);//设置单元格信息

    item=new QTableWidgetItem(gender);
    QIcon icon;
    if(gender=="男")
    {
        icon.addFile(":/image/boy.png");
    }
    else
    {
        icon.addFile(":/image/girl.png");
    }
    item->setIcon(icon);//这个是显示图片的,下面的截图忘记添加了
    ui->tableWidget->setItem(rowNumber,1,item);

    item=new QTableWidgetItem(birthday.toString("yyyy-MM-dd"));
    ui->tableWidget->setItem(rowNumber,2,item);

    item=new QTableWidgetItem(job);
    ui->tableWidget->setItem(rowNumber,3,item);

    item=new QTableWidgetItem(married?"已婚":"未混");
    if(married)
    {
        item->setBackground(Qt::gray);//还可以设置背景色
    }
    ui->tableWidget->setItem(rowNumber,4,item);

}

③:单元格附加值

cpp 复制代码
item->setData(Qt::UserRole,QVariant(number));//添加附加值

④:单元格文本对其方式

现在的运行结果:

我们可以发现我们单元格的信息没有居中,我们可以通过setTextAlignment接口来设置

cpp 复制代码
item->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);

参数可以在F1文档中去查找:

运行结果:

哈哈,我们的表格就生成好了,是不是很完美哈哈,接下来我们要来添加功能了,让表格动起来!

三.编辑功能

1.编辑逻辑

就是有一个接口可以设置表格编辑的触发器,来使我们可以控制表格是否可以被编辑。

2.设置编辑触发器

默认状态下表格是可以进行编辑的

现在我们来设置不能对其进行编辑。

在mianWindow的构造函数里添加

cpp 复制代码
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

参数还是可以通过F1在线文档去找。

现在就不可以编辑了。

3.实现编辑action

根据是否打开复选框acyion来设置编辑触发器的模式来控制是否能编辑。

cpp 复制代码
void MainWindow::on_actionEdit_triggered(bool checked)
{
    if(checked)
    {
        //双击和选中单击都可以进行编辑
        ui->tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::SelectedClicked);
    }
    else
    {
        //禁止编辑
        ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    }
}

运行结果:

四.插入功能

1.插入逻辑

我们要获取我们鼠标的位置来确定我们要插入的位置,其次插入有一个接口可以实现插入一行,但是是空行,所以首先需要我们先创建一行。

2.获取当前行

cpp 复制代码
int currentRow=ui->tableWidget->currentRow();

3.插入行

通过我们刚刚的函数来创建行信息

cpp 复制代码
    MaxNo++;//插一行计算加1
    ui->tableWidget->insertRow(currentRow);
    creatRows(currentRow,"未知",MaxNo,"男",QDate(2000,1,1),"未知",false);

4.选择新行

现在有个问题就是当我插入新行时,他会选择刚刚插入的那个位置,而不是我们新插入的位置。

解决办法:

cpp 复制代码
 ui->tableWidget->selectRow(currentRow);

5.能否编辑

现在还有一个问题,我们新插入的数据居然不能编辑,这不就插了更没有插入一样的嘛。

cpp 复制代码
void MainWindow::on_actionInsert_triggered()
{
    int currentRow=ui->tableWidget->currentRow();
    //对当前行添加信息

    MaxNo++;
    ui->tableWidget->insertRow(currentRow);
    ui->tableWidget->selectRow(currentRow);
    creatRows(currentRow,"未知",MaxNo,"男",QDate(2000,1,1),"未知",false);
    on_actionEdit_triggered(true);//插入的时候,可以将编辑功能打开
}

现在就可以进行编辑了。

但是又出现一个小问题

就是我们肯定只希望只能编辑插入的数据,结果这样一开,所有的行都能编辑了。

解决方案:我们可以通过表格的信号来判断,我当前的光标位置是不是在我刚刚插入的位置,是就打开编辑,不是就关闭编辑。

如果默认打开编辑功能,那这种情况不存在。

选择这个信号:

在插入功能函数中记录插入的位置

cpp 复制代码
insertRow=currentRow;
cpp 复制代码
void MainWindow::on_tableWidget_itemSelectionChanged()
{
    if(ui->actionEdit->isChecked()) return;

    if(insertRow==ui->tableWidget->currentRow())
    {
        on_actionEdit_triggered(true);
    }
    else
    {
        on_actionEdit_triggered(false);
    }
}

运行结果:

五.删除功能

1.删除逻辑

通过获取当前光标在的单元格位置,来删除单元格所在的行。

2.获取当前选中的单元格

cpp 复制代码
void MainWindow::on_actionDel_triggered()
{
    auto item=ui->tableWidget->currentItem();        
    ui->tableWidget->removeRow(item->row());
}

运行结果:

这样有个问题就是,当我们删除后,没有进行选择,但是还是可以删除,所以我们要进行是否被选中的判断。

3.判断单元格是否被选中

cpp 复制代码
void MainWindow::on_actionDel_triggered()
{
    auto item=ui->tableWidget->currentItem();
    if(item->isSelected())
    {
       ui->tableWidget->removeRow(item->row());
    }
    
}

问题就被完美的解决了。

4.删除行

cpp 复制代码
ui->tableWidget->removeRow(item->row());

六.查找功能

1.查找逻辑

我们是在行编辑器中去输入字符串,通过按钮来关联槽函数来进行包含查找,查找到就进行选中,同时来搞一个高亮显示。

2.查找字符

因为我们打算是在状态栏加lineeditpushbutton所以我们只能用代码来进行添加。

cpp 复制代码
    lineFind=new QLineEdit;
    button=new QPushButton;
    label=new QLabel;
    
    statusBar()->addWidget(lineFind);
    statusBar()->addWidget(button);
    statusBar()->addWidget(label);
    
    lineFind->setMaximumWidth(200);
    button->setText("查找");
    connect(button,SIGNAL(clicked()),this,SLOT(onButtonFind()));//对按钮进行自己定义的槽函数关联

运行结果:

cpp 复制代码
void MainWindow::onButtonFind()
{
    QString ret=lineFind->text().trimmed();//去除开头和结尾的空白符
    if(ret.length()>0)
    {
        //包含模式查找,返回的是一个容器链表
        auto items=ui->tableWidget->findItems(ret,Qt::MatchContains);
        //遍历所有查找到的结果将其设置为选中
        for(auto it=items.begin();it!=items.end();it++)
        {
            (*it)->setSelected(true);
        }
    }
}

3.设置选中

cpp 复制代码
 //遍历所有查找到的结果将其设置为选中
        for(auto it=items.begin();it!=items.end();it++)
        {
            (*it)->setSelected(true);
        }

4.设置样式表

可以看成查到了牛马,但是这个颜色太浅了,我们可以来设置选中的样式表来高亮显示。

cpp 复制代码
ui->tableWidget->setStyleSheet("selection-background-color:rgb(255,128,0)");

运行结果;

这就很清晰了,但是有个问题就是我们下次查询的时候,这些高亮还是在,所有我们要进行清除选中。

5.清除高亮

cpp 复制代码
ui->tableWidget->clearSelection();//清除选中

这就很爽了,你们可以试试。

七.显示信息

1.显示逻辑

当我们随便选择一个单元格的时候,我们就在标签上,显示该单元格所在的一行信息。

2.信号

3.读出单元格的信息

cpp 复制代码
void MainWindow::on_tableWidget_cellClicked(int row, int column)
{
    QString ret;
    for(int i=0;i<ui->tableWidget->columnCount();i++)
    {
        ret+=ui->tableWidget->item(row,i)->text()+"/";
    }
    label->setText(ret);
}

运行结果:

八.总结

表格的构建先列(表头)后行,每一个数据都是通过单元格进行设置。

其次就是对增删改查功能的设计的掌握。

人的一切痛苦,本质上都是对自己无能的愤怒。

相关推荐
健康的猪1 分钟前
golang的cgo的一点小心得
开发语言·后端·golang
冰茶_6 分钟前
.NET MAUI 发展历程:从 Xamarin 到现代跨平台应用开发框架
学习·microsoft·微软·c#·.net·xamarin
夜夜敲码22 分钟前
C语言教程(十六): C 语言字符串详解
c语言·开发语言
cooldream200924 分钟前
深入理解MVP架构:让UI层与业务逻辑完美分离的设计模式
ui·设计模式·架构·系统架构师
帅云毅24 分钟前
Web3.0的认知补充(去中心化)
笔记·学习·web3·去中心化·区块链
豆豆25 分钟前
day32 学习笔记
图像处理·笔记·opencv·学习·计算机视觉
拖孩27 分钟前
【Nova UI】十一、组件库中 Icon 组件的测试、使用与全局注册全攻略
前端·javascript·vue.js·ui·sass
宋康29 分钟前
C语言结构体和union内存对齐
c语言·开发语言
꧁坚持很酷꧂35 分钟前
Linux Ubuntu18.04下安装Qt Craeator 5.12.9(图文详解)
linux·运维·qt
居然是阿宋39 分钟前
Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
android·开发语言·kotlin