目录
2.批量添加QPushButton控件,实现“打开”/“关闭”的切换
3.批量添加QCheckBox控件,实现“选中”/“未选中”的切换
先看效果动图:
表格分页等操作
下面开始实现每个功能。
新建项目很简单,就不具体详述了,不会的自己摸索以下,已经会的可以跳过。我的项目名称是QT_QTableWidget
项目创建完成后,点击左下角的绿色按钮,先运行下是否报错。如图:

没有报错,就可以正常编写代码了。
首先把项目标题和项目图标设置一下。
1.项目标题设置:
在构造函数中敲出下面一行代码。
this->setWindowTitle(tr("QTableWidget批量添加数据、批量添加控件、分页跳转、定位到指定行、添加/插入/删除行的功能实现"));
2.项目图标设置:
设置图标需要将图片放入到项目的资源文件中,否则,无法设置。
(1)创建资源文件操作
鼠标放在项目名上,鼠标右击,在弹出的菜单中选择“Add New.....”,再次弹出一个提示框,依次选择“Qt”和Qt资源文件,之后按着如下截图依次操作。







(2)设置图标
在构造函数中,添加以下代码:
- // 设置图标必须要创建资源文件,并将所需要的图片添加到项目中,复制图片的资源路径
- this->setWindowIcon(QIcon(":/menu/xue.png"));
(3)代码截图和运行效果图


(1)在ui设计界面,拖出一个TableWidget控件,对象名为tableWidget;
(2)再拖出4个PushButton按钮控件,文本为:“首页”、“上一页”、“下一页”、“尾页”,对象名依次为:FirstPageBtn、PrevPageBtn、NextPageBtn、LastPageBtn;
再放入5个Lable控件和1个LineEdit控件(对象名为lineEdit),Lable文本为:“第几页(这个会动态修改掉)”(对象名为CurPageLable)、“/”、“共几页(可动态修改)”(对象名为TotalPageLable)、“跳转到第”、“页”;
(3)放入一个Lable控件,文本为“当前行号:”、放入1个LineEdit控件,对象名为“currentRowLineEdit”;
再放入3个PushButton按钮,文本分别为“添加一行”、“插入一行”、“删除一行”,对象名分别为“addBtn”、“insertBtn”、“delBtn”;
再放入一个Lable控件,文本为“定位到指定行:”、放入1个LineEdit控件,对象名为“input”,设置placeholderText属性值为“请输入要查询的内容”;
(4)为每个按钮添加点击样式

(4)界面设计图如下

在mainwindow.h中声明初始化函数:
- private:
- void setTableWidget(int row,int column); /* QTableWidget的初始化 */

在mainwindow.cpp中添加定义,并设置QTableWidget的相关属性,这些属性都是最常见的必不可少的,可以根据需求更改,如下代码:
- //QTableWidget的初始化
- void MainWindow::setTableWidget(int row,int column)
- {
- ui->tableWidget->resizeRowsToContents();//调整行内容大小
- ui->tableWidget->setColumnCount(column);//设置列数
- ui->tableWidget->setRowCount(row);//设置行数
- ui->tableWidget->horizontalHeader()->setDefaultSectionSize(200);//标题头的大小
- ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);//横向先自适应宽度
- ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);//然后设置要根据内容使用宽度的列
-
- //设置标题头的文字
- QStringList header;
- header<< tr("编号") << tr("静态数据") << tr("LED指示灯") << tr("按钮控件") << tr("Check Box控件") << "单元格改变的信号处理操作" ;
- ui->tableWidget->setHorizontalHeaderLabels(header);
-
- //设置标题头的字体样式
- QFont font = ui->tableWidget->horizontalHeader()->font();
- font.setBold(true);
- ui->tableWidget->horizontalHeader()->setFont(font);
-
- ui->tableWidget->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
- ui->tableWidget->verticalHeader()->setDefaultSectionSize(10); //设置行距
- ui->tableWidget->setFrameShape(QFrame::NoFrame); //设置无边框
- ui->tableWidget->setShowGrid(true); //设置不显示格子线
- ui->tableWidget->verticalHeader()->setVisible(false); //设置行号列,true为显示
- ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
- ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
- ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
- ui->tableWidget->horizontalHeader()->resizeSection(0,100);//设置表头第一列的宽度为100
- ui->tableWidget->horizontalHeader()->setFixedHeight(30); //设置表头的高度
- ui->tableWidget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
- ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:white;}"); //设置表头背景色
-
- //设置水平、垂直滚动条样式,添加头文件 #include <QScrollBar>
- ui->tableWidget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
- "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
- "QScrollBar::handle:hover{background:gray;}"
- "QScrollBar::sub-line{background:transparent;}"
- "QScrollBar::add-line{background:transparent;}");
- ui->tableWidget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
- "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
- "QScrollBar::handle:hover{background:gray;}"
- "QScrollBar::sub-line{background:transparent;}"
- "QScrollBar::add-line{background:transparent;}");
-
- ui->tableWidget->clearContents();//清除表格数据区的所有内容,但是不清除表头
-
- }
设置好后,在构造函数中调用,设置表格为50行,6列:
setTableWidget(50,6);

运行后,效果如下:

在添加数据时,我将每一列的索引值都用一个常量进行标识,是为了方便查询和修改。
在mainwindow.h中声明6个常量:
- private:
- const int sn = 0; /* 序号列 */
- const int static_data = 1; /* 静态数据列 */
- const int led = 2; /* LED列 */
- const int btn = 3; /* 按钮列 */
- const int check = 4; /* checkbox列 */
- const int CellChanged = 5; /* 单元格改变时列 */

现在开始添加数据,核心代码为:
- //设置数据
- for(int i = 0;i < row;i++)
- {
- // (2.2.2)批量添加数据
- //序号列,sn是在头文件中定义的常量
- ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
- //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
- ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- //静态数据列,static_data是在头文件中定义的常量
- ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
- ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- }
把这一段代码,放在 void setTableWidget(int row,int column);函数中,
- //QTableWidget的初始化
- void MainWindow::setTableWidget(int row,int column)
- {
- ui->tableWidget->resizeRowsToContents();//调整行内容大小
- ui->tableWidget->setColumnCount(column);//设置列数
- ui->tableWidget->setRowCount(row);//设置行数
- ui->tableWidget->horizontalHeader()->setDefaultSectionSize(200);//标题头的大小
- ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);//横向先自适应宽度
- ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);//然后设置要根据内容使用宽度的列
-
- //设置标题头的文字
- QStringList header;
- header<< tr("编号") << tr("静态数据") << tr("LED指示灯") << tr("按钮控件") << tr("Check Box控件") << "单元格改变的信号处理操作" ;
- ui->tableWidget->setHorizontalHeaderLabels(header);
-
- //设置标题头的字体样式
- QFont font = ui->tableWidget->horizontalHeader()->font();
- font.setBold(true);
- ui->tableWidget->horizontalHeader()->setFont(font);
-
- ui->tableWidget->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
- ui->tableWidget->verticalHeader()->setDefaultSectionSize(10); //设置行距
- ui->tableWidget->setFrameShape(QFrame::NoFrame); //设置无边框
- ui->tableWidget->setShowGrid(true); //设置不显示格子线
- ui->tableWidget->verticalHeader()->setVisible(false); //设置行号列,true为显示
- ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
- ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
- ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
- ui->tableWidget->horizontalHeader()->resizeSection(0,100);//设置表头第一列的宽度为100
- ui->tableWidget->horizontalHeader()->setFixedHeight(30); //设置表头的高度
- ui->tableWidget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
- ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:white;}"); //设置表头背景色
-
- //设置水平、垂直滚动条样式,添加头文件 #include <QScrollBar>
- ui->tableWidget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
- "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
- "QScrollBar::handle:hover{background:gray;}"
- "QScrollBar::sub-line{background:transparent;}"
- "QScrollBar::add-line{background:transparent;}");
- ui->tableWidget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
- "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
- "QScrollBar::handle:hover{background:gray;}"
- "QScrollBar::sub-line{background:transparent;}"
- "QScrollBar::add-line{background:transparent;}");
-
- ui->tableWidget->clearContents();//清除表格数据区的所有内容,但是不清除表头
-
- //设置数据
- for(int i = 0;i < row;i++)
- {
- // (2.2.2)批量添加数据
- //序号列,sn是在头文件中定义的常量
- ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
- //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
- ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- //静态数据列,static_data是在头文件中定义的常量
- ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
- ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- }
- }
运行后,效果图如下:

只列举3中控件的添加,其他控件与之一样,就不一一列举了。
QTableWidget添加控件需要用到下面方法:

需求:批量添加50个QLable控件,制作LED指示灯,默认是红灯,使用定时器让红绿灯交替执行。
(1)在mainwindow.h中声明添加控件的函数
QWidget *CreateQLable(int flag); /* 指示灯 */

(2) 在mainwindow.cpp中添加定义
因为需要创建50个LED灯,所以需要封装一个函数,然后for循环依次创建出50个即可。
- //添加QLable控件,制作LED灯
- QWidget *MainWindow::CreateQLable(int flag)
- {
- QLabel *lab = new QLabel();
- lab->setFixedSize(QSize(12,12));
-
- switch (flag)
- {
- case 0:
- //绿灯
- lab->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 255, 0, 255), stop:1 rgba(255, 255, 255, 255));\
- border-radius: 6px;");
- break;
- case 1:
- //红灯
- lab->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));\
- border-radius: 6px;");
- break;
- }
-
- QHBoxLayout *vLayout = new QHBoxLayout(); //水平布局
- QWidget *Widget_lab = new QWidget(); //新建Widget
- vLayout->addWidget(lab); //布局中添加了控件
- vLayout->setMargin(0); //水平垂直居中必须使用此属性,不然不是想要的效果
- vLayout->setAlignment(lab,Qt::AlignVCenter); //水平垂直居中
- Widget_lab->setLayout(vLayout); //Widget中添加布局
-
- // ui->tableWidget->setCellWidget(0,2,Widget_lab);//某个单元格中添加1个控件
-
- return Widget_lab;
- }
(3)使用
在 void setTableWidget(int row,int column);函数中调用。
- //QTableWidget的初始化
- void MainWindow::setTableWidget(int row,int column)
- {
- ui->tableWidget->resizeRowsToContents();//调整行内容大小
- ui->tableWidget->setColumnCount(column);//设置列数
- ui->tableWidget->setRowCount(row);//设置行数
- ui->tableWidget->horizontalHeader()->setDefaultSectionSize(200);//标题头的大小
- ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);//横向先自适应宽度
- ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);//然后设置要根据内容使用宽度的列
-
- //设置标题头的文字
- QStringList header;
- header<< tr("编号") << tr("静态数据") << tr("LED指示灯") << tr("按钮控件") << tr("Check Box控件") << "单元格改变的信号处理操作" ;
- ui->tableWidget->setHorizontalHeaderLabels(header);
-
- //设置标题头的字体样式
- QFont font = ui->tableWidget->horizontalHeader()->font();
- font.setBold(true);
- ui->tableWidget->horizontalHeader()->setFont(font);
-
- ui->tableWidget->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
- ui->tableWidget->verticalHeader()->setDefaultSectionSize(10); //设置行距
- ui->tableWidget->setFrameShape(QFrame::NoFrame); //设置无边框
- ui->tableWidget->setShowGrid(true); //设置不显示格子线
- ui->tableWidget->verticalHeader()->setVisible(false); //设置行号列,true为显示
- ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
- ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
- ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
- ui->tableWidget->horizontalHeader()->resizeSection(0,100);//设置表头第一列的宽度为100
- ui->tableWidget->horizontalHeader()->setFixedHeight(30); //设置表头的高度
- ui->tableWidget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
- ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:white;}"); //设置表头背景色
-
- //设置水平、垂直滚动条样式,添加头文件 #include <QScrollBar>
- ui->tableWidget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
- "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
- "QScrollBar::handle:hover{background:gray;}"
- "QScrollBar::sub-line{background:transparent;}"
- "QScrollBar::add-line{background:transparent;}");
- ui->tableWidget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
- "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
- "QScrollBar::handle:hover{background:gray;}"
- "QScrollBar::sub-line{background:transparent;}"
- "QScrollBar::add-line{background:transparent;}");
-
- ui->tableWidget->clearContents();//清除表格数据区的所有内容,但是不清除表头
-
- //设置数据
- for(int i = 0;i < row;i++)
- {
- // (2.2.2)批量添加数据
- //序号列,sn是在头文件中定义的常量
- ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
- //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
- ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- //静态数据列,static_data是在头文件中定义的常量
- ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
- ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
-
- // (2.2.3)批量添加控件
- // 批量添加QLable控件,制作LED指示灯,默认是红灯,使用定时器让红绿灯交替执行
- ui->tableWidget->setCellWidget(i,led,CreateQLable(1));
-
- }
- }
(4)运行效果

(5)使用定时器,让LED红绿交替闪烁(3中闪烁形式)
在mainwindow.h中声明定时器:
QTimer *led_timer;
在mainwindow.cpp中添加定义,添加头文件 #include
led_timer = new QTimer(this);
要实现红绿交换,需要状态标志来表示是红色还是绿色,我这里只列举3个LED的闪烁,剩下的按着这个方法来即可。
核心代码:
头文件:
- private:
- QTimer *led_timer;
- int CurCnt = -1;
- bool flag = false;
-
- //不同指示灯的状态标志位,只举出3个例子,其他都是相同操作,不在赘述
- bool LED0_flag = false;
- bool LED1_flag = false;
- bool LED2_flag = false;
- QVector<bool> LED_flag_vector;
在构造函数中添加以下代码,每隔1s变一次:
- LED_flag_vector << LED0_flag << LED1_flag << LED2_flag ;
- led_timer = new QTimer(this);
- led_timer->start(1000);//1s变一次
- connect(led_timer,&QTimer::timeout,this,&MainWindow::on_led_timer);
定时器信号的槽函数为:
- public slots:
- void on_led_timer();
- void MainWindow::on_led_timer()
- {
- if((CurCnt >= 50) || (CurCnt == -1))
- {
- CurCnt = 0;
- }
- else
- {
- CurCnt++;
- }
-
- // 1)、同一时间只有一个指示灯亮
- for(int j = 0; j < 50; j++)
- {
- if(j == CurCnt)
- {
- ui->tableWidget->removeCellWidget(j,led);//删除控件,防止追加
- ui->tableWidget->setCellWidget(j,led,CreateQLable(0));
- }
- else
- {
- ui->tableWidget->removeCellWidget(j,led);
- ui->tableWidget->setCellWidget(j,led,CreateQLable(1));
- }
- }
-
- // 2)、所有指示灯同时变红变绿,解开以下注释即可查看效果
- // if(flag)
- // {
- // for(int j = 0; j < 50; j++)
- // {
- // //变红
- // ui->tableWidget->removeCellWidget(j,led);
- // ui->tableWidget->setCellWidget(j,led,CreateQLable(1));//表格中添加Widget
- // flag = false;
- // }
- // }
- // else
- // {
- // for(int j = 0; j < 50; j++)
- // {
- // //变绿
- // ui->tableWidget->removeCellWidget(j,led);
- // ui->tableWidget->setCellWidget(j,led,CreateQLable(0));//表格中添加Widget
- // flag = true;
- // }
- // }
-
- // 3)、所有指示灯互不干扰,解开以下注释即可查看效果
- // if(LED_flag_vector.at(0))
- // {
- // //变红
- // ui->tableWidget->removeCellWidget(0,led);//删除之前的控件
- // ui->tableWidget->setCellWidget(0,led,CreateQLable(1));//表格中添加Widget
- // LED_flag_vector.replace(0,false);
- // }
- // else
- // {
- // //变绿
- // ui->tableWidget->removeCellWidget(0,led);
- // ui->tableWidget->setCellWidget(0,led,CreateQLable(0));//表格中添加Widget
- // LED_flag_vector.replace(0,true);
- // }
-
- // if(CurCnt % 3 == 0)
- // {
- // if(LED_flag_vector.at(1))
- // {
- // //变红
- // ui->tableWidget->removeCellWidget(1,led);//删除之前的控件
- // ui->tableWidget->setCellWidget(1,led,CreateQLable(1));//表格中添加Widget
- // LED_flag_vector.replace(1,false);
- // }
- // else
- // {
- // //变绿
- // ui->tableWidget->removeCellWidget(1,led);
- // ui->tableWidget->setCellWidget(1,led,CreateQLable(0));//表格中添加Widget
- // LED_flag_vector.replace(1,true);
- // }
- // }
-
- // if(CurCnt % 5 == 0)
- // {
- // if(LED_flag_vector.at(2))
- // {
- // //变红
- // ui->tableWidget->removeCellWidget(2,led);//删除之前的控件
- // ui->tableWidget->setCellWidget(2,led,CreateQLable(1));//表格中添加Widget
- // LED_flag_vector.replace(2,false);
- // }
- // else
- // {
- // //变绿
- // ui->tableWidget->removeCellWidget(2,led);
- // ui->tableWidget->setCellWidget(2,led,CreateQLable(0));//表格中添加Widget
- // LED_flag_vector.replace(2,true);
- // }
- // }
- }
运行后,效果图:

(1)封装成一个函数。
QWidget *CreateQPushButton(); /* 批量添加QPushButton控件 */
需要注意的是:按钮点击信号的处理,
clicked信号有两个,clicked();和 clicked(bool checked);
此文章使用的是带参数的,所以还要处理函数重载,处理方法和注意事项都放在下方代码中了。
- // 批量添加QPushButton控件
- QWidget *MainWindow::CreateQPushButton()
- {
- QWidget *Widget_btn = new QWidget;
- QVBoxLayout *hLayout = new QVBoxLayout();
- QPushButton *btn = new QPushButton("打开");//添加头文件 #include <QCheckBox>
- btn->setCheckable(true);//必须要有此属性,否则信号发送无效
-
- // 以下3个信号都可以,选择自己习惯使用的就行
- // connect(btn,&QPushButton::toggled,ui->tableWidget,[=](bool checked)
- // {
- // });
-
- //注意:解决信号函数重载方法
- // 1,使用QOverload
- connect(btn,QOverload<bool>::of(&QPushButton::clicked),this,[=](bool checked)
- {
- if(checked)
- {
- btn->setText("关闭");
- }
- else
- {
- btn->setText("打开");
- }
- });
-
- //2.使用函数指针
- // void (QPushButton:: * btn_bool)(bool) = &QPushButton::clicked;
- // connect(btn,btn_bool,this,[=](bool enable)
- // {
- // });
-
- hLayout->addWidget(btn);
- hLayout->setMargin(0);
- hLayout->setAlignment(btn, Qt::AlignCenter);
- Widget_btn->setLayout(hLayout);
-
- return Widget_btn;
- }
(2)使用
在 void setTableWidget(int row,int column);函数中的for循环中调用。代码如下:
- //设置数据
- for(int i = 0;i < row;i++)
- {
- // (2.2.2)批量添加数据
- //序号列,sn是在头文件中定义的常量
- ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
- //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
- ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- //静态数据列,static_data是在头文件中定义的常量
- ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
- ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
-
- // (2.2.3)批量添加控件
- // 批量添加QLable控件,制作LED指示灯,默认是红灯,使用定时器让红绿灯交替执行
- ui->tableWidget->setCellWidget(i,led,CreateQLable(1));
-
- // 批量添加QPushButton控件
- ui->tableWidget->setCellWidget(i, btn, CreateQPushButton());
- }
(3)运行效果

(1)封装成一个函数。
QWidget *CreateQCheckBox(); /* 批量添加QCheckBox控件 */
- //批量添加QCheckBox控件
- QWidget *MainWindow::CreateQCheckBox()
- {
- QWidget *Widget_ckb = new QWidget;
- QVBoxLayout *hLayout = new QVBoxLayout();
- // QPushButton *btn = new QPushButton(tr("按钮 %1").arg(i + 1));
- QCheckBox *ckb = new QCheckBox("选中");//添加头文件 #include <QCheckBox>
- connect(ckb,&QCheckBox::stateChanged,this,[=]()
- {
- if(ckb->checkState() == Qt::Checked)
- {
- ckb->setText("选中");
- }
- else if(ckb->checkState() == Qt::Unchecked)
- {
- ckb->setText("未选中");
- }
- });
- hLayout->addWidget(ckb);
- hLayout->setMargin(0);
- hLayout->setAlignment(ckb, Qt::AlignCenter);
- Widget_ckb->setLayout(hLayout);
-
- return Widget_ckb;
- }
(2)使用
在 void setTableWidget(int row,int column);函数中的for循环中调用。代码如下:
- //设置数据
- for(int i = 0;i < row;i++)
- {
- // (2.2.2)批量添加数据
- //序号列,sn是在头文件中定义的常量
- ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
- //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
- ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- //静态数据列,static_data是在头文件中定义的常量
- ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
- ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
-
- // (2.2.3)批量添加控件
- // 批量添加QLable控件,制作LED指示灯,默认是红灯,使用定时器让红绿灯交替执行
- ui->tableWidget->setCellWidget(i,led,CreateQLable(1));
-
- // 批量添加QPushButton控件
- ui->tableWidget->setCellWidget(i, btn, CreateQPushButton());
-
- // 批量添加QCheckBox控件
- ui->tableWidget->setCellWidget(i, check, CreateQCheckBox());
- }
(3)运行效果

是不是很简单?!! 那么其他控件也可以添加,动手试试看。
此功能,我是参考大佬的做法。
重点来了!!!!!!!!
(1)mainwindow.h中声明变量、函数、槽函数
- public:
- //分页显示
- int pageSize; /* 每一页的行数 */
- int curPage; /* 当前页 */
- private:
- void setCurPage(int n); /* 显示表格当前页 */
- int getPageCount(const int row_count); /* 计算表格总页数 */
- void setTotalPage(const int all); /* 显示表格总页数 */
- void showPageData(); /* 显示每页的数据 */
- private slots:
- void on_PrevPageBtn_clicked(); /* 上一页 */
- void on_NextPageBtn_clicked(); /* 下一页 */
- void on_FirstPageBtn_clicked(); /* 首页 */
- void on_LastPageBtn_clicked(); /* 尾页 */
- void on_lineEdit_textChanged(const QString &arg1); /* 跳转页 */
(2)mainwindow.cpp中初始化变量、定义函数、定义槽函数
在构造函数中变量初始化,默认显示表格第一页,首页、上一页按钮禁止点击
- // 变量初始化,默认显示表格第一页,首页、上一页按钮禁止点击
- pageSize = 10;//每一页默认显示10行数据
- curPage = 0;
- setCurPage(curPage);
- showPageData();

之后定义函数:
- void MainWindow::setCurPage(int n)
- {
- ui->labelCurPage->setText(QString("第 %1 页").arg(n+1));
- }
-
- void MainWindow::setTotalPage(int n)
- {
- ui->labelTotalPage->setText(QString("共 %1 页").arg(n));
- }
- //分页数据
- void MainWindow::showPageData()
- {
- int rowCount = ui->tableWidget->rowCount();
- if(curPage == 0)
- {
- ui->PrevPageBtn->setDisabled(true);
- ui->FirstPageBtn->setDisabled(true);
- }
- else
- {
- ui->PrevPageBtn->setDisabled(false);
- ui->FirstPageBtn->setDisabled(false);
- }
-
- if(curPage == getPageCount(rowCount) - 1)
- {
- ui->NextPageBtn->setDisabled(true);
- ui->LastPageBtn->setDisabled(true);
- }
- else
- {
- ui->NextPageBtn->setDisabled(false);
- ui->LastPageBtn->setDisabled(false);
- }
-
- /* 以下是分页的核心代码 */
- int PageStartRow = pageSize * curPage; /* 每页的起始行 */
- int PageEndRow = 0; /* 每页的结束行 */
-
- //通过判断是否超出tableWidget表格的总行数来获取每页的结束行
- if(PageStartRow + pageSize < rowCount)
- {
- PageEndRow = PageStartRow + pageSize;
- }
- else
- {
- PageEndRow = rowCount;
- }
-
- for(int i = 0; i < rowCount; i++)
- {
- //显示当前页的每行数据并隐藏其他页的数据
- if(i >= PageStartRow && i < PageEndRow)
- {
- ui->tableWidget->setRowHidden(i, false);
- }
- else
- {
- ui->tableWidget->setRowHidden(i, true);
- }
- }
- }
- int MainWindow::getPageCount(const int row_count)
- {
- int pageCnt = 0;
- if(row_count == 0)
- {
- return 0;
- }
- else if(row_count % pageSize == 0)
- {
- pageCnt = row_count / pageSize;
- }
- else
- {
- pageCnt = row_count / pageSize + 1;
- }
- setTotalPage(pageCnt);
- return pageCnt;
- }
为这4个按钮添加点击clicked信号的槽函数。
添加槽函数最简单的方法就是,选中控件,鼠标右击,在弹出菜单中选择“转到槽......”,就可以在头文件和.cpp文件中添加对应的声明和定义。
跳转页的输入框也有自己的 textChanged(const QString &arg1)的信号和槽。
转到槽操作如图所示:


上一页、下一页、首页、尾页、跳转操作的核心代码如下:
- //上一页
- void MainWindow::on_PrevPageBtn_clicked()
- {
- curPage--;
- if(curPage < 0)
- {
- curPage = 0;
- }
- setCurPage(curPage);
- showPageData();
- }
-
- //下一页
- void MainWindow::on_NextPageBtn_clicked()
- {
- curPage++;
- setCurPage(curPage);
- showPageData();
- }
-
- //首页
- void MainWindow::on_FirstPageBtn_clicked()
- {
- curPage = 0;
- setCurPage(curPage);
- showPageData();
- }
-
- //尾页
- void MainWindow::on_LastPageBtn_clicked()
- {
- curPage = getPageCount(ui->tableWidget->rowCount()) -1;
- setCurPage(curPage);
- showPageData();
- }
-
- //跳转页
- void MainWindow::on_lineEdit_textChanged(const QString &arg1)
- {
- int turnPage = arg1.toInt();
- if(turnPage > 0 && turnPage < getPageCount(ui->tableWidget->rowCount()) + 1)
- {
- curPage = turnPage -1;
- setCurPage(curPage);
- showPageData();
- }
- }

分页成功!
在输入框中输入你要查询的数据,当数据发生变化时QLineEdit会发出
textChanged(const QString &arg1);
的信号,为这个信号编写槽函数即可。
在设计界面选中这个输入框,鼠标右击,选择“转到槽......”,就能自动添加下方这个槽函数和定义。
void on_input_textChanged(const QString &arg1); /* 定位到某一行 */
- //定位到指定行
- void MainWindow::on_input_textChanged(const QString &arg1)
- {
- if(arg1 == "")
- {
- return;
- }
-
- QList<QTableWidgetItem *> items;
- QTableWidgetItem *item;
-
- items = ui->tableWidget->findItems(arg1, Qt::MatchExactly);//在表格中查找数据项
-
- //找到了这个数据项
- if(items.length() > 0)
- {
- item = items[0];//获取到数据项
- int r = item->row();//获取所在行
- curPage = r / pageSize;//计算在表格第几页
- setCurPage(curPage);//定位到这一页
- showPageData();//显示这页的数据
- ui->tableWidget->verticalScrollBar()->setSliderPosition(r);//滚动条定位到数据所在位置
- ui->tableWidget->setCurrentItem(item);//将这个数据所在行设置为表格的当前行
- }
- }
运行效果如下:

为这三个按钮的clicked信号,添加槽函数,选中控件鼠标右击,选择“转到槽.....”,在选择“clicked()”信号,即可创建信号和槽的连接。

槽函数声明:
- void on_insertBtn_clicked(); /* 插入一行 */
- void on_addBtn_clicked(); /* 添加一行 */
- void on_delBtn_clicked(); /* 删除一行 */
定义:
- //插入
- void MainWindow::on_insertBtn_clicked()
- {
- int curRow = ui->tableWidget->currentRow();
- ui->tableWidget->insertRow(curRow); //插入一行,但不会自动为单元格创建item,需要手动创建内容
-
- ui->tableWidget->setItem(curRow,0,new QTableWidgetItem(QString::number(curRow)));
- ui->tableWidget->item(curRow,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- //此功能还有待完善
- }
-
- //添加
- void MainWindow::on_addBtn_clicked()
- {
- int curRow = ui->tableWidget->rowCount();
- ui->tableWidget->insertRow(curRow);//在表格尾部添加一行
- ui->tableWidget->setItem(curRow,0,new QTableWidgetItem(QString::number(curRow + 1)));
- ui->tableWidget->item(curRow,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
- //此功能还有待完善
- }
-
- //删除
- void MainWindow::on_delBtn_clicked()
- {
- int curRow=ui->tableWidget->currentRow();
- ui->tableWidget->removeRow(curRow); //删除当前行及其items
- }
运行效果

每次点击表格中某行数据时,就会触发currentCellChanged信号。

为这个信号编写自定义槽函数:
void GetRow(int currentRow, int currentColumn, int previousRow, int previousColumn);/* 单元格改变槽函数 */
在构造函数中连接信号
connect(ui->tableWidget,&QTableWidget::currentCellChanged,this,&MainWindow::GetRow);
自动逸槽函数实现:
- //单元格变化信号槽函数
- void MainWindow::GetRow(int currentRow, int currentColumn, int previousRow, int previousColumn)
- {
- Q_UNUSED(currentColumn);
- Q_UNUSED(previousRow);
- Q_UNUSED(previousColumn);
-
- //显示当前行号,默认显示第一行
- ui->currentRowLineEdit->setText(QString::asprintf("%d",currentRow + 1));
-
- //给表格最后一列设置数据,CellChanged是最后一列的索引号
- ui->tableWidget->setItem(currentRow,CellChanged,new QTableWidgetItem("检测到信号"));
- ui->tableWidget->item(currentRow,CellChanged)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
-
- //状态栏显示
- statusBar()->showMessage(tr("当前单元格坐标是第 %1 行,第 %2 列").arg(currentRow).arg(currentColumn),3000);
- }
效果图:

表格分页等操作
最后,当然是附上源码啦。
加上源码后,文章太太太长了,不方便阅读。
所以,想要源码压缩包的可以私聊我。
源码压缩包:https://download.csdn.net/download/m0_49456900/86506340