• QTableWidget的初始化、批量添加数据、批量添加控件、分页跳转、定位到指定行、添加/插入/删除行的功能实现


    目录

    前言

    一、新建项目

    二、设置主窗口标题和图标

    三、界面设计

    四、QTableWidget的初始化

    五、 QTableWidget中批量添加数据

    六、QTableWidget中批量添加控件

    1.批量添加QLable控件,制作LED指示灯

    2.批量添加QPushButton控件,实现“打开”/“关闭”的切换

    3.批量添加QCheckBox控件,实现“选中”/“未选中”的切换

    七、QTableWidget的分页跳转

    1)、控件显示页数和总页数

    2)、分页显示数据(此功能的核心代码)

    3)、上一页、下一页、首页、尾页、跳转操作

    4)、效果图

    八、通过滚动条定位到指定行

    九、QTableWidget中添加/插入/删除行

    十、监听单元格改变信号

    十一、源码


    前言

    先看效果动图:

    表格分页等操作

    下面开始实现每个功能。 

    一、新建项目

    新建项目很简单,就不具体详述了,不会的自己摸索以下,已经会的可以跳过。我的项目名称是QT_QTableWidget

    二、设置主窗口标题和图标

    项目创建完成后,点击左下角的绿色按钮,先运行下是否报错。如图:

    没有报错,就可以正常编写代码了。

    首先把项目标题和项目图标设置一下。

    1.项目标题设置:

    在构造函数中敲出下面一行代码。

    this->setWindowTitle(tr("QTableWidget批量添加数据、批量添加控件、分页跳转、定位到指定行、添加/插入/删除行的功能实现"));

     2.项目图标设置:

    设置图标需要将图片放入到项目的资源文件中,否则,无法设置。

    (1)创建资源文件操作

    鼠标放在项目名上,鼠标右击,在弹出的菜单中选择“Add New.....”,再次弹出一个提示框,依次选择“Qt”和Qt资源文件,之后按着如下截图依次操作。

     

     

     

     

     

     

    (2)设置图标

    在构造函数中,添加以下代码:

    1. // 设置图标必须要创建资源文件,并将所需要的图片添加到项目中,复制图片的资源路径
    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)界面设计图如下

    四、QTableWidget的初始化

    在mainwindow.h中声明初始化函数:

    1. private:
    2. void setTableWidget(int row,int column); /* QTableWidget的初始化 */

    在mainwindow.cpp中添加定义,并设置QTableWidget的相关属性,这些属性都是最常见的必不可少的,可以根据需求更改,如下代码:

    1. //QTableWidget的初始化
    2. void MainWindow::setTableWidget(int row,int column)
    3. {
    4. ui->tableWidget->resizeRowsToContents();//调整行内容大小
    5. ui->tableWidget->setColumnCount(column);//设置列数
    6. ui->tableWidget->setRowCount(row);//设置行数
    7. ui->tableWidget->horizontalHeader()->setDefaultSectionSize(200);//标题头的大小
    8. ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);//横向先自适应宽度
    9. ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);//然后设置要根据内容使用宽度的列
    10. //设置标题头的文字
    11. QStringList header;
    12. header<< tr("编号") << tr("静态数据") << tr("LED指示灯") << tr("按钮控件") << tr("Check Box控件") << "单元格改变的信号处理操作" ;
    13. ui->tableWidget->setHorizontalHeaderLabels(header);
    14. //设置标题头的字体样式
    15. QFont font = ui->tableWidget->horizontalHeader()->font();
    16. font.setBold(true);
    17. ui->tableWidget->horizontalHeader()->setFont(font);
    18. ui->tableWidget->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
    19. ui->tableWidget->verticalHeader()->setDefaultSectionSize(10); //设置行距
    20. ui->tableWidget->setFrameShape(QFrame::NoFrame); //设置无边框
    21. ui->tableWidget->setShowGrid(true); //设置不显示格子线
    22. ui->tableWidget->verticalHeader()->setVisible(false); //设置行号列,true为显示
    23. ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
    24. ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
    25. ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
    26. ui->tableWidget->horizontalHeader()->resizeSection(0,100);//设置表头第一列的宽度为100
    27. ui->tableWidget->horizontalHeader()->setFixedHeight(30); //设置表头的高度
    28. ui->tableWidget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
    29. ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:white;}"); //设置表头背景色
    30. //设置水平、垂直滚动条样式,添加头文件 #include <QScrollBar>
    31. ui->tableWidget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
    32. "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
    33. "QScrollBar::handle:hover{background:gray;}"
    34. "QScrollBar::sub-line{background:transparent;}"
    35. "QScrollBar::add-line{background:transparent;}");
    36. ui->tableWidget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
    37. "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
    38. "QScrollBar::handle:hover{background:gray;}"
    39. "QScrollBar::sub-line{background:transparent;}"
    40. "QScrollBar::add-line{background:transparent;}");
    41. ui->tableWidget->clearContents();//清除表格数据区的所有内容,但是不清除表头
    42. }

    设置好后,在构造函数中调用,设置表格为50行,6列:

    setTableWidget(50,6);

    运行后,效果如下:

    五、 QTableWidget中批量添加数据

    在添加数据时,我将每一列的索引值都用一个常量进行标识,是为了方便查询和修改。

    在mainwindow.h中声明6个常量:

    1. private:
    2. const int sn = 0; /* 序号列 */
    3. const int static_data = 1; /* 静态数据列 */
    4. const int led = 2; /* LED列 */
    5. const int btn = 3; /* 按钮列 */
    6. const int check = 4; /* checkbox列 */
    7. const int CellChanged = 5; /* 单元格改变时列 */

    现在开始添加数据,核心代码为:

    1. //设置数据
    2. for(int i = 0;i < row;i++)
    3. {
    4. // (2.2.2)批量添加数据
    5. //序号列,sn是在头文件中定义的常量
    6. ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
    7. //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
    8. ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    9. //静态数据列,static_data是在头文件中定义的常量
    10. ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
    11. ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    12. }

     把这一段代码,放在 void            setTableWidget(int row,int column);函数中,

    1. //QTableWidget的初始化
    2. void MainWindow::setTableWidget(int row,int column)
    3. {
    4. ui->tableWidget->resizeRowsToContents();//调整行内容大小
    5. ui->tableWidget->setColumnCount(column);//设置列数
    6. ui->tableWidget->setRowCount(row);//设置行数
    7. ui->tableWidget->horizontalHeader()->setDefaultSectionSize(200);//标题头的大小
    8. ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);//横向先自适应宽度
    9. ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);//然后设置要根据内容使用宽度的列
    10. //设置标题头的文字
    11. QStringList header;
    12. header<< tr("编号") << tr("静态数据") << tr("LED指示灯") << tr("按钮控件") << tr("Check Box控件") << "单元格改变的信号处理操作" ;
    13. ui->tableWidget->setHorizontalHeaderLabels(header);
    14. //设置标题头的字体样式
    15. QFont font = ui->tableWidget->horizontalHeader()->font();
    16. font.setBold(true);
    17. ui->tableWidget->horizontalHeader()->setFont(font);
    18. ui->tableWidget->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
    19. ui->tableWidget->verticalHeader()->setDefaultSectionSize(10); //设置行距
    20. ui->tableWidget->setFrameShape(QFrame::NoFrame); //设置无边框
    21. ui->tableWidget->setShowGrid(true); //设置不显示格子线
    22. ui->tableWidget->verticalHeader()->setVisible(false); //设置行号列,true为显示
    23. ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
    24. ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
    25. ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
    26. ui->tableWidget->horizontalHeader()->resizeSection(0,100);//设置表头第一列的宽度为100
    27. ui->tableWidget->horizontalHeader()->setFixedHeight(30); //设置表头的高度
    28. ui->tableWidget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
    29. ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:white;}"); //设置表头背景色
    30. //设置水平、垂直滚动条样式,添加头文件 #include <QScrollBar>
    31. ui->tableWidget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
    32. "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
    33. "QScrollBar::handle:hover{background:gray;}"
    34. "QScrollBar::sub-line{background:transparent;}"
    35. "QScrollBar::add-line{background:transparent;}");
    36. ui->tableWidget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
    37. "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
    38. "QScrollBar::handle:hover{background:gray;}"
    39. "QScrollBar::sub-line{background:transparent;}"
    40. "QScrollBar::add-line{background:transparent;}");
    41. ui->tableWidget->clearContents();//清除表格数据区的所有内容,但是不清除表头
    42. //设置数据
    43. for(int i = 0;i < row;i++)
    44. {
    45. // (2.2.2)批量添加数据
    46. //序号列,sn是在头文件中定义的常量
    47. ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
    48. //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
    49. ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    50. //静态数据列,static_data是在头文件中定义的常量
    51. ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
    52. ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    53. }
    54. }

     运行后,效果图如下:

    六、QTableWidget中批量添加控件

    只列举3中控件的添加,其他控件与之一样,就不一一列举了。

    QTableWidget添加控件需要用到下面方法:

    1.批量添加QLable控件,制作LED指示灯

    需求:批量添加50个QLable控件,制作LED指示灯,默认是红灯,使用定时器让红绿灯交替执行。

    (1)在mainwindow.h中声明添加控件的函数

    QWidget         *CreateQLable(int flag);     /* 指示灯 */

    (2) 在mainwindow.cpp中添加定义

    因为需要创建50个LED灯,所以需要封装一个函数,然后for循环依次创建出50个即可。

    1. //添加QLable控件,制作LED灯
    2. QWidget *MainWindow::CreateQLable(int flag)
    3. {
    4. QLabel *lab = new QLabel();
    5. lab->setFixedSize(QSize(12,12));
    6. switch (flag)
    7. {
    8. case 0:
    9. //绿灯
    10. 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));\
    11. border-radius: 6px;");
    12. break;
    13. case 1:
    14. //红灯
    15. 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));\
    16. border-radius: 6px;");
    17. break;
    18. }
    19. QHBoxLayout *vLayout = new QHBoxLayout(); //水平布局
    20. QWidget *Widget_lab = new QWidget(); //新建Widget
    21. vLayout->addWidget(lab); //布局中添加了控件
    22. vLayout->setMargin(0); //水平垂直居中必须使用此属性,不然不是想要的效果
    23. vLayout->setAlignment(lab,Qt::AlignVCenter); //水平垂直居中
    24. Widget_lab->setLayout(vLayout); //Widget中添加布局
    25. // ui->tableWidget->setCellWidget(0,2,Widget_lab);//某个单元格中添加1个控件
    26. return Widget_lab;
    27. }

     (3)使用

    在 void     setTableWidget(int row,int column);函数中调用。

    1. //QTableWidget的初始化
    2. void MainWindow::setTableWidget(int row,int column)
    3. {
    4. ui->tableWidget->resizeRowsToContents();//调整行内容大小
    5. ui->tableWidget->setColumnCount(column);//设置列数
    6. ui->tableWidget->setRowCount(row);//设置行数
    7. ui->tableWidget->horizontalHeader()->setDefaultSectionSize(200);//标题头的大小
    8. ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);//横向先自适应宽度
    9. ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);//然后设置要根据内容使用宽度的列
    10. //设置标题头的文字
    11. QStringList header;
    12. header<< tr("编号") << tr("静态数据") << tr("LED指示灯") << tr("按钮控件") << tr("Check Box控件") << "单元格改变的信号处理操作" ;
    13. ui->tableWidget->setHorizontalHeaderLabels(header);
    14. //设置标题头的字体样式
    15. QFont font = ui->tableWidget->horizontalHeader()->font();
    16. font.setBold(true);
    17. ui->tableWidget->horizontalHeader()->setFont(font);
    18. ui->tableWidget->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
    19. ui->tableWidget->verticalHeader()->setDefaultSectionSize(10); //设置行距
    20. ui->tableWidget->setFrameShape(QFrame::NoFrame); //设置无边框
    21. ui->tableWidget->setShowGrid(true); //设置不显示格子线
    22. ui->tableWidget->verticalHeader()->setVisible(false); //设置行号列,true为显示
    23. ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
    24. ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
    25. ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
    26. ui->tableWidget->horizontalHeader()->resizeSection(0,100);//设置表头第一列的宽度为100
    27. ui->tableWidget->horizontalHeader()->setFixedHeight(30); //设置表头的高度
    28. ui->tableWidget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
    29. ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:white;}"); //设置表头背景色
    30. //设置水平、垂直滚动条样式,添加头文件 #include <QScrollBar>
    31. ui->tableWidget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
    32. "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
    33. "QScrollBar::handle:hover{background:gray;}"
    34. "QScrollBar::sub-line{background:transparent;}"
    35. "QScrollBar::add-line{background:transparent;}");
    36. ui->tableWidget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
    37. "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
    38. "QScrollBar::handle:hover{background:gray;}"
    39. "QScrollBar::sub-line{background:transparent;}"
    40. "QScrollBar::add-line{background:transparent;}");
    41. ui->tableWidget->clearContents();//清除表格数据区的所有内容,但是不清除表头
    42. //设置数据
    43. for(int i = 0;i < row;i++)
    44. {
    45. // (2.2.2)批量添加数据
    46. //序号列,sn是在头文件中定义的常量
    47. ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
    48. //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
    49. ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    50. //静态数据列,static_data是在头文件中定义的常量
    51. ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
    52. ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    53. // (2.2.3)批量添加控件
    54. // 批量添加QLable控件,制作LED指示灯,默认是红灯,使用定时器让红绿灯交替执行
    55. ui->tableWidget->setCellWidget(i,led,CreateQLable(1));
    56. }
    57. }

    (4)运行效果

     (5)使用定时器,让LED红绿交替闪烁(3中闪烁形式)

    在mainwindow.h中声明定时器:

    QTimer          *led_timer;

    在mainwindow.cpp中添加定义,添加头文件 #include

    led_timer = new QTimer(this);

    要实现红绿交换,需要状态标志来表示是红色还是绿色,我这里只列举3个LED的闪烁,剩下的按着这个方法来即可。

    核心代码:

    头文件:

    1. private:
    2. QTimer *led_timer;
    3. int CurCnt = -1;
    4. bool flag = false;
    5. //不同指示灯的状态标志位,只举出3个例子,其他都是相同操作,不在赘述
    6. bool LED0_flag = false;
    7. bool LED1_flag = false;
    8. bool LED2_flag = false;
    9. QVector<bool> LED_flag_vector;

    在构造函数中添加以下代码,每隔1s变一次:

    1. LED_flag_vector << LED0_flag << LED1_flag << LED2_flag ;
    2. led_timer = new QTimer(this);
    3. led_timer->start(1000);//1s变一次
    4. connect(led_timer,&QTimer::timeout,this,&MainWindow::on_led_timer);

    定时器信号的槽函数为:

    1. public slots:
    2. void on_led_timer();
    1. void MainWindow::on_led_timer()
    2. {
    3. if((CurCnt >= 50) || (CurCnt == -1))
    4. {
    5. CurCnt = 0;
    6. }
    7. else
    8. {
    9. CurCnt++;
    10. }
    11. // 1)、同一时间只有一个指示灯亮
    12. for(int j = 0; j < 50; j++)
    13. {
    14. if(j == CurCnt)
    15. {
    16. ui->tableWidget->removeCellWidget(j,led);//删除控件,防止追加
    17. ui->tableWidget->setCellWidget(j,led,CreateQLable(0));
    18. }
    19. else
    20. {
    21. ui->tableWidget->removeCellWidget(j,led);
    22. ui->tableWidget->setCellWidget(j,led,CreateQLable(1));
    23. }
    24. }
    25. // 2)、所有指示灯同时变红变绿,解开以下注释即可查看效果
    26. // if(flag)
    27. // {
    28. // for(int j = 0; j < 50; j++)
    29. // {
    30. // //变红
    31. // ui->tableWidget->removeCellWidget(j,led);
    32. // ui->tableWidget->setCellWidget(j,led,CreateQLable(1));//表格中添加Widget
    33. // flag = false;
    34. // }
    35. // }
    36. // else
    37. // {
    38. // for(int j = 0; j < 50; j++)
    39. // {
    40. // //变绿
    41. // ui->tableWidget->removeCellWidget(j,led);
    42. // ui->tableWidget->setCellWidget(j,led,CreateQLable(0));//表格中添加Widget
    43. // flag = true;
    44. // }
    45. // }
    46. // 3)、所有指示灯互不干扰,解开以下注释即可查看效果
    47. // if(LED_flag_vector.at(0))
    48. // {
    49. // //变红
    50. // ui->tableWidget->removeCellWidget(0,led);//删除之前的控件
    51. // ui->tableWidget->setCellWidget(0,led,CreateQLable(1));//表格中添加Widget
    52. // LED_flag_vector.replace(0,false);
    53. // }
    54. // else
    55. // {
    56. // //变绿
    57. // ui->tableWidget->removeCellWidget(0,led);
    58. // ui->tableWidget->setCellWidget(0,led,CreateQLable(0));//表格中添加Widget
    59. // LED_flag_vector.replace(0,true);
    60. // }
    61. // if(CurCnt % 3 == 0)
    62. // {
    63. // if(LED_flag_vector.at(1))
    64. // {
    65. // //变红
    66. // ui->tableWidget->removeCellWidget(1,led);//删除之前的控件
    67. // ui->tableWidget->setCellWidget(1,led,CreateQLable(1));//表格中添加Widget
    68. // LED_flag_vector.replace(1,false);
    69. // }
    70. // else
    71. // {
    72. // //变绿
    73. // ui->tableWidget->removeCellWidget(1,led);
    74. // ui->tableWidget->setCellWidget(1,led,CreateQLable(0));//表格中添加Widget
    75. // LED_flag_vector.replace(1,true);
    76. // }
    77. // }
    78. // if(CurCnt % 5 == 0)
    79. // {
    80. // if(LED_flag_vector.at(2))
    81. // {
    82. // //变红
    83. // ui->tableWidget->removeCellWidget(2,led);//删除之前的控件
    84. // ui->tableWidget->setCellWidget(2,led,CreateQLable(1));//表格中添加Widget
    85. // LED_flag_vector.replace(2,false);
    86. // }
    87. // else
    88. // {
    89. // //变绿
    90. // ui->tableWidget->removeCellWidget(2,led);
    91. // ui->tableWidget->setCellWidget(2,led,CreateQLable(0));//表格中添加Widget
    92. // LED_flag_vector.replace(2,true);
    93. // }
    94. // }
    95. }

     运行后,效果图:

    2.批量添加QPushButton控件,实现“打开”/“关闭”的切换

    (1)封装成一个函数。

     QWidget         *CreateQPushButton();      /* 批量添加QPushButton控件 */

    需要注意的是:按钮点击信号的处理,

     clicked信号有两个,clicked();和 clicked(bool checked);

    此文章使用的是带参数的,所以还要处理函数重载,处理方法和注意事项都放在下方代码中了。

    1. // 批量添加QPushButton控件
    2. QWidget *MainWindow::CreateQPushButton()
    3. {
    4. QWidget *Widget_btn = new QWidget;
    5. QVBoxLayout *hLayout = new QVBoxLayout();
    6. QPushButton *btn = new QPushButton("打开");//添加头文件 #include <QCheckBox>
    7. btn->setCheckable(true);//必须要有此属性,否则信号发送无效
    8. // 以下3个信号都可以,选择自己习惯使用的就行
    9. // connect(btn,&QPushButton::toggled,ui->tableWidget,[=](bool checked)
    10. // {
    11. // });
    12. //注意:解决信号函数重载方法
    13. // 1,使用QOverload
    14. connect(btn,QOverload<bool>::of(&QPushButton::clicked),this,[=](bool checked)
    15. {
    16. if(checked)
    17. {
    18. btn->setText("关闭");
    19. }
    20. else
    21. {
    22. btn->setText("打开");
    23. }
    24. });
    25. //2.使用函数指针
    26. // void (QPushButton:: * btn_bool)(bool) = &QPushButton::clicked;
    27. // connect(btn,btn_bool,this,[=](bool enable)
    28. // {
    29. // });
    30. hLayout->addWidget(btn);
    31. hLayout->setMargin(0);
    32. hLayout->setAlignment(btn, Qt::AlignCenter);
    33. Widget_btn->setLayout(hLayout);
    34. return Widget_btn;
    35. }

    (2)使用

    在 void     setTableWidget(int row,int column);函数中的for循环中调用。代码如下:

    1. //设置数据
    2. for(int i = 0;i < row;i++)
    3. {
    4. // (2.2.2)批量添加数据
    5. //序号列,sn是在头文件中定义的常量
    6. ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
    7. //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
    8. ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    9. //静态数据列,static_data是在头文件中定义的常量
    10. ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
    11. ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    12. // (2.2.3)批量添加控件
    13. // 批量添加QLable控件,制作LED指示灯,默认是红灯,使用定时器让红绿灯交替执行
    14. ui->tableWidget->setCellWidget(i,led,CreateQLable(1));
    15. // 批量添加QPushButton控件
    16. ui->tableWidget->setCellWidget(i, btn, CreateQPushButton());
    17. }

    (3)运行效果

    3.批量添加QCheckBox控件,实现“选中”/“未选中”的切换

     (1)封装成一个函数。

    QWidget         *CreateQCheckBox();      /* 批量添加QCheckBox控件 */
    1. //批量添加QCheckBox控件
    2. QWidget *MainWindow::CreateQCheckBox()
    3. {
    4. QWidget *Widget_ckb = new QWidget;
    5. QVBoxLayout *hLayout = new QVBoxLayout();
    6. // QPushButton *btn = new QPushButton(tr("按钮 %1").arg(i + 1));
    7. QCheckBox *ckb = new QCheckBox("选中");//添加头文件 #include <QCheckBox>
    8. connect(ckb,&QCheckBox::stateChanged,this,[=]()
    9. {
    10. if(ckb->checkState() == Qt::Checked)
    11. {
    12. ckb->setText("选中");
    13. }
    14. else if(ckb->checkState() == Qt::Unchecked)
    15. {
    16. ckb->setText("未选中");
    17. }
    18. });
    19. hLayout->addWidget(ckb);
    20. hLayout->setMargin(0);
    21. hLayout->setAlignment(ckb, Qt::AlignCenter);
    22. Widget_ckb->setLayout(hLayout);
    23. return Widget_ckb;
    24. }

    (2)使用

    在 void     setTableWidget(int row,int column);函数中的for循环中调用。代码如下:

    1. //设置数据
    2. for(int i = 0;i < row;i++)
    3. {
    4. // (2.2.2)批量添加数据
    5. //序号列,sn是在头文件中定义的常量
    6. ui->tableWidget->setItem(i,sn,new QTableWidgetItem(QString::number(i+1)));
    7. //内容水平垂直居中,注意一定要先设置内容,此属性才会有效
    8. ui->tableWidget->item(i,sn)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    9. //静态数据列,static_data是在头文件中定义的常量
    10. ui->tableWidget->setItem(i,static_data,new QTableWidgetItem(tr("我是静态数据 %1").arg(i + 1)));
    11. ui->tableWidget->item(i,static_data)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    12. // (2.2.3)批量添加控件
    13. // 批量添加QLable控件,制作LED指示灯,默认是红灯,使用定时器让红绿灯交替执行
    14. ui->tableWidget->setCellWidget(i,led,CreateQLable(1));
    15. // 批量添加QPushButton控件
    16. ui->tableWidget->setCellWidget(i, btn, CreateQPushButton());
    17. // 批量添加QCheckBox控件
    18. ui->tableWidget->setCellWidget(i, check, CreateQCheckBox());
    19. }

    (3)运行效果

    是不是很简单?!! 那么其他控件也可以添加,动手试试看。 

    七、QTableWidget的分页跳转

    此功能,我是参考大佬的做法。

    参考:Qt::实现qtablewidget分页功能

    重点来了!!!!!!!!

    (1)mainwindow.h中声明变量、函数、槽函数

    1. public:
    2. //分页显示
    3. int pageSize; /* 每一页的行数 */
    4. int curPage; /* 当前页 */
    5. private:
    6. void setCurPage(int n); /* 显示表格当前页 */
    7. int getPageCount(const int row_count); /* 计算表格总页数 */
    8. void setTotalPage(const int all); /* 显示表格总页数 */
    9. void showPageData(); /* 显示每页的数据 */
    10. private slots:
    11. void on_PrevPageBtn_clicked(); /* 上一页 */
    12. void on_NextPageBtn_clicked(); /* 下一页 */
    13. void on_FirstPageBtn_clicked(); /* 首页 */
    14. void on_LastPageBtn_clicked(); /* 尾页 */
    15. void on_lineEdit_textChanged(const QString &arg1); /* 跳转页 */

    (2)mainwindow.cpp中初始化变量、定义函数、定义槽函数

    在构造函数中变量初始化,默认显示表格第一页,首页、上一页按钮禁止点击

    1. // 变量初始化,默认显示表格第一页,首页、上一页按钮禁止点击
    2. pageSize = 10;//每一页默认显示10行数据
    3. curPage = 0;
    4. setCurPage(curPage);
    5. showPageData();

    之后定义函数:

    1)、控件显示页数和总页数

    1. void MainWindow::setCurPage(int n)
    2. {
    3. ui->labelCurPage->setText(QString("第 %1 页").arg(n+1));
    4. }
    5. void MainWindow::setTotalPage(int n)
    6. {
    7. ui->labelTotalPage->setText(QString("共 %1 页").arg(n));
    8. }

    2)、分页显示数据(此功能的核心代码)

    1. //分页数据
    2. void MainWindow::showPageData()
    3. {
    4. int rowCount = ui->tableWidget->rowCount();
    5. if(curPage == 0)
    6. {
    7. ui->PrevPageBtn->setDisabled(true);
    8. ui->FirstPageBtn->setDisabled(true);
    9. }
    10. else
    11. {
    12. ui->PrevPageBtn->setDisabled(false);
    13. ui->FirstPageBtn->setDisabled(false);
    14. }
    15. if(curPage == getPageCount(rowCount) - 1)
    16. {
    17. ui->NextPageBtn->setDisabled(true);
    18. ui->LastPageBtn->setDisabled(true);
    19. }
    20. else
    21. {
    22. ui->NextPageBtn->setDisabled(false);
    23. ui->LastPageBtn->setDisabled(false);
    24. }
    25. /* 以下是分页的核心代码 */
    26. int PageStartRow = pageSize * curPage; /* 每页的起始行 */
    27. int PageEndRow = 0; /* 每页的结束行 */
    28. //通过判断是否超出tableWidget表格的总行数来获取每页的结束行
    29. if(PageStartRow + pageSize < rowCount)
    30. {
    31. PageEndRow = PageStartRow + pageSize;
    32. }
    33. else
    34. {
    35. PageEndRow = rowCount;
    36. }
    37. for(int i = 0; i < rowCount; i++)
    38. {
    39. //显示当前页的每行数据并隐藏其他页的数据
    40. if(i >= PageStartRow && i < PageEndRow)
    41. {
    42. ui->tableWidget->setRowHidden(i, false);
    43. }
    44. else
    45. {
    46. ui->tableWidget->setRowHidden(i, true);
    47. }
    48. }
    49. }
    1. int MainWindow::getPageCount(const int row_count)
    2. {
    3. int pageCnt = 0;
    4. if(row_count == 0)
    5. {
    6. return 0;
    7. }
    8. else if(row_count % pageSize == 0)
    9. {
    10. pageCnt = row_count / pageSize;
    11. }
    12. else
    13. {
    14. pageCnt = row_count / pageSize + 1;
    15. }
    16. setTotalPage(pageCnt);
    17. return pageCnt;
    18. }

    3)、上一页、下一页、首页、尾页、跳转操作

    为这4个按钮添加点击clicked信号的槽函数。

    添加槽函数最简单的方法就是,选中控件,鼠标右击,在弹出菜单中选择“转到槽......”,就可以在头文件和.cpp文件中添加对应的声明和定义。

    跳转页的输入框也有自己的 textChanged(const QString &arg1)的信号和槽。

    转到槽操作如图所示:

      

     上一页、下一页、首页、尾页、跳转操作的核心代码如下:

    1. //上一页
    2. void MainWindow::on_PrevPageBtn_clicked()
    3. {
    4. curPage--;
    5. if(curPage < 0)
    6. {
    7. curPage = 0;
    8. }
    9. setCurPage(curPage);
    10. showPageData();
    11. }
    12. //下一页
    13. void MainWindow::on_NextPageBtn_clicked()
    14. {
    15. curPage++;
    16. setCurPage(curPage);
    17. showPageData();
    18. }
    19. //首页
    20. void MainWindow::on_FirstPageBtn_clicked()
    21. {
    22. curPage = 0;
    23. setCurPage(curPage);
    24. showPageData();
    25. }
    26. //尾页
    27. void MainWindow::on_LastPageBtn_clicked()
    28. {
    29. curPage = getPageCount(ui->tableWidget->rowCount()) -1;
    30. setCurPage(curPage);
    31. showPageData();
    32. }
    33. //跳转页
    34. void MainWindow::on_lineEdit_textChanged(const QString &arg1)
    35. {
    36. int turnPage = arg1.toInt();
    37. if(turnPage > 0 && turnPage < getPageCount(ui->tableWidget->rowCount()) + 1)
    38. {
    39. curPage = turnPage -1;
    40. setCurPage(curPage);
    41. showPageData();
    42. }
    43. }

    4)、效果图

     分页成功!

    八、通过滚动条定位到指定行

    在输入框中输入你要查询的数据,当数据发生变化时QLineEdit会发出

    textChanged(const QString &arg1);

    的信号,为这个信号编写槽函数即可。

    在设计界面选中这个输入框,鼠标右击,选择“转到槽......”,就能自动添加下方这个槽函数和定义。

    void   on_input_textChanged(const QString &arg1);  /* 定位到某一行 */
    1. //定位到指定行
    2. void MainWindow::on_input_textChanged(const QString &arg1)
    3. {
    4. if(arg1 == "")
    5. {
    6. return;
    7. }
    8. QList<QTableWidgetItem *> items;
    9. QTableWidgetItem *item;
    10. items = ui->tableWidget->findItems(arg1, Qt::MatchExactly);//在表格中查找数据项
    11. //找到了这个数据项
    12. if(items.length() > 0)
    13. {
    14. item = items[0];//获取到数据项
    15. int r = item->row();//获取所在行
    16. curPage = r / pageSize;//计算在表格第几页
    17. setCurPage(curPage);//定位到这一页
    18. showPageData();//显示这页的数据
    19. ui->tableWidget->verticalScrollBar()->setSliderPosition(r);//滚动条定位到数据所在位置
    20. ui->tableWidget->setCurrentItem(item);//将这个数据所在行设置为表格的当前行
    21. }
    22. }

    运行效果如下:

    九、QTableWidget中添加/插入/删除行

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

     槽函数声明:

    1. void on_insertBtn_clicked(); /* 插入一行 */
    2. void on_addBtn_clicked(); /* 添加一行 */
    3. void on_delBtn_clicked(); /* 删除一行 */

     定义:

    1. //插入
    2. void MainWindow::on_insertBtn_clicked()
    3. {
    4. int curRow = ui->tableWidget->currentRow();
    5. ui->tableWidget->insertRow(curRow); //插入一行,但不会自动为单元格创建item,需要手动创建内容
    6. ui->tableWidget->setItem(curRow,0,new QTableWidgetItem(QString::number(curRow)));
    7. ui->tableWidget->item(curRow,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    8. //此功能还有待完善
    9. }
    10. //添加
    11. void MainWindow::on_addBtn_clicked()
    12. {
    13. int curRow = ui->tableWidget->rowCount();
    14. ui->tableWidget->insertRow(curRow);//在表格尾部添加一行
    15. ui->tableWidget->setItem(curRow,0,new QTableWidgetItem(QString::number(curRow + 1)));
    16. ui->tableWidget->item(curRow,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    17. //此功能还有待完善
    18. }
    19. //删除
    20. void MainWindow::on_delBtn_clicked()
    21. {
    22. int curRow=ui->tableWidget->currentRow();
    23. ui->tableWidget->removeRow(curRow); //删除当前行及其items
    24. }

     运行效果

    十、监听单元格改变信号

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

     为这个信号编写自定义槽函数:

    void   GetRow(int currentRow, int currentColumn, int previousRow, int previousColumn);/* 单元格改变槽函数 */

    在构造函数中连接信号

    connect(ui->tableWidget,&QTableWidget::currentCellChanged,this,&MainWindow::GetRow);

     自动逸槽函数实现:

    1. //单元格变化信号槽函数
    2. void MainWindow::GetRow(int currentRow, int currentColumn, int previousRow, int previousColumn)
    3. {
    4. Q_UNUSED(currentColumn);
    5. Q_UNUSED(previousRow);
    6. Q_UNUSED(previousColumn);
    7. //显示当前行号,默认显示第一行
    8. ui->currentRowLineEdit->setText(QString::asprintf("%d",currentRow + 1));
    9. //给表格最后一列设置数据,CellChanged是最后一列的索引号
    10. ui->tableWidget->setItem(currentRow,CellChanged,new QTableWidgetItem("检测到信号"));
    11. ui->tableWidget->item(currentRow,CellChanged)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    12. //状态栏显示
    13. statusBar()->showMessage(tr("当前单元格坐标是第 %1 行,第 %2 列").arg(currentRow).arg(currentColumn),3000);
    14. }

     效果图:

    十一、源码

    表格分页等操作

    最后,当然是附上源码啦。

    加上源码后,文章太太太长了,不方便阅读。

    所以,想要源码压缩包的可以私聊我。

    源码压缩包:https://download.csdn.net/download/m0_49456900/86506340

  • 相关阅读:
    React 中 react-i18next 切换语言( 项目国际化 )
    set | map | multiset | multimap 快速上手
    联想Filez助力知名生物制药企业 建立业务数据安全体系
    代码随想录第40天|62.不同路径,63. 不同路径 II
    基于JAVA铝塑门窗的研制和生产管理计算机毕业设计源码+数据库+lw文档+系统+部署
    Leetcode.2867 统计树中的合法路径数目
    相机标定基本原理
    .Net大数据平台Microsoft.Spark环境构建 附可运行源码。
    Android 图像格式HAL_PIXEL_FORMAT_* vs ImageFormt.*对应关系
    npm install报错 缺少python
  • 原文地址:https://blog.csdn.net/m0_49456900/article/details/126598625