QT in QTableWidget

QTableWidget is Qt table component class. QTableWidget After placing a component on the form may be made in the property Property Editor, double-click the component, an editor may open, edit its Colum, Row, and Item.

QTableWidget a basic structure interface assembly shown in Figure 1, this table is set to 6 rows and 5 columns.



The basic structure and the row of the table work area a in FIG. 1 QTableWidget, column index


Line 1 of the table is called a row header, a header is provided for each column, the first column lists called head, its title can be provided, but generally the default title is the line number. Row headers and column headers are generally not editable.

In addition to the row header region and a column header table is a content area, content area is a regular grid-like, as a two-dimensional array, each grid unit is called a cell. Each cell has a row number, column number, line number 1 shows, the variation of the column number.

In QTableWidget table, each cell is a QTable Widgetltem object, you can set text, font, foreground color, background color, icons, and editing can also be set to display markers. Each cell may also store a QVariant data for setting user-defined data.



Example 2 FIG Samp4_9 run time interface


Examples samp4_9 to QTableWidget as the main component, presentations QTableWidget some implementations major operation. Examples of runtime interface 2 shown, this example demonstrates a method to realize the following functions:

  • Set the table columns and rows, provided the header text format.
  • Initialization data table, set a number of examples to fill the data table.
  • Insert rows, add rows, delete the current line.
  • Table traversing all cells, to read a table of contents QPlainTextEdit, the row of data table as a line of text.
  • When selecting a current variation unit cell, the cell information stored in the status bar displayed on the form.

Interface design and initialization

Samp4_9 的主窗体从 QMainWindow 继承而来。在图 2 所示的窗口上,一个 QTableWidget 组件和一个 QPlainTextEdit 组件组成上下分割布局 splitter。左侧的按钮都放在一个 QGroupBox 组件里,釆用 Grid 布局,然后将 groupBox 与 splitter 采用左右分割布局。这是一个典型的三区分割的布局。

在主窗口类 MainWindow 里自定义了一些变量和函数,用于后面的代码实现,下面是在 MainWindow 的 private 部分自定义的变量和函数:

private:
    //自定义单元格Type的类型,在创建单元格的item时使用
    enum CellType{ctName=1000,ctSex,ctBirth,ctNation,ctPartyM,ctScore};
    //各字段在表格中的列号
    enum FieldColNum{colName=0,colSex,colBirth,colNation,colScore,colPartyM};
    QLabel *labCellIndex; //状态栏上用于显示单元格的行号、列号
    QLabel *labCellType; //状态栏上用于显示单元格的type
    QLabel *labStudID; //状态栏上用于显示学号
    void createItemsARow(int rowNo,QString Name,QString Sex,QDate birth,QString Nation,bool isPM,int score) ; //为某一行创建 items

枚举类型 CellType 是用来表示单元格类型的,在创建单元格时使用。枚举类型 FieldColNum 用枚举常量表示各字段在表格中的列号。

在 MainWindow 的构造函数里对界面进行初始化,代码如下:

 
  1. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
  2. {
  3. ui->setupUi(this);
  4. setCentralWidget(ui->splitterMain);
  5. //状态栏初始化创建
  6. labCellIndex = new QLabel ("当前单元格坐标:", this);
  7. labCellIndex->setMinimumWidth(250);
  8. labCellType=new QLabel ("当前单元格类型:",this);
  9. labCellType->setMinimumWidth(200);
  10. labStudID=new QLabel ("学生ID: ", this);
  11. labStudID->setMinimumWidth(200);
  12. ui->statusBar->addWidget (labCellIndex) ; //加到状态栏
  13. ui->statusBar->addWidget(labCellType);
  14. ui->statusBar->addWidget(labStudID);
  15. }

QTableWidget 基本操作

设置表头

界面上的“设置表头”按钮实现对表头的设置,其 clicked() 信号的槽函数代码如下:

 
  1. void MainWindow::on_btnSetHeader_clicked()
  2. { //设置表头
  3. QTableWidgetItem *headerItem;
  4. QStringList headerText;
  5. headerText<<"姓 名"<<"性 别"<<"出生日期"<<"民 族"<<"分数"<<"是否党员"; //表头标题用QStringList来表示
  6. //ui->tableInfo->setHorizontalHeaderLabels(headerText);
  7. ui->tableInfo->setColumnCount(headerText.count());//列数设置为与 headerText的行数相等
  8. for (int i=0;i<ui->tableInfo->columnCount();i++)//列编号从0开始
  9. {
  10. //cellItem=ui->tableInfo->horizontalHeaderItem(i);
  11. headerItem=new QTableWidgetItem(headerText.at(i)); //新建一个QTableWidgetItem, headerText.at(i)获取headerText的i行字符串
  12. QFont font=headerItem->font();//获取原有字体设置
  13. font.setBold(true);//设置为粗体
  14. font.setPointSize(12);//字体大小
  15. headerItem->setTextColor(Qt::red);//字体颜色
  16. headerItem->setFont(font);//设置字体
  17. ui->tableInfo->setHorizontalHeaderItem(i,headerItem); //设置表头单元格的Item
  18. }
  19.  
  20. ui->tableInfo->setItemDelegateForColumn(colScore,&spinDelegate);//设置自定义代理组件
  21. }

行表头各列的文字标题由一个 QStringList 对象 headerText 初始化存储,如果只是设置行表头各列的标题,使用下面一行语句即可:

ui->tableInfo->setHorizontalHeaderLabels(headerText);

如果需要进行更加具体的格式设置,需要为行表头的每个单元格创建一个 QTableWidgetItem 类型的变量,并进行相应设置。

在一个表格中,不管是表头还是工作区,每个单元格都是一个 QTableWidgetItem 对象。QTableWidgetItem 对象存储了单元格的所有内容,包括字标题、格式设置,以及关联的数据。上面程序中的 for 循环遍历 headerText 的每一行,用每一行的文字创建一个 QTableWidgetItem 对象 headerltem,然后设置 headerItem 的字体大小为 12、粗体、红色,然后将 headerltem 赋给表头的某一列:

ui->tableInfo->setHorizontalHeaderItern (i, headerItem);

初始化表格数据

界面上的“初始化表格数据”按钮根据表格的行数,生成数据填充表格,并为每个单元格生成 QTableWidgetItem 对象,设置相应属性。下面是 btnlniData 的 clicked() 信号的槽函数代码:

 
  1. void MainWindow::on_btnIniData_clicked()
  2. { //初始化表格内容
  3. QString strName,strSex;
  4. bool isParty=false;
  5.  
  6. QDate birth;
  7. birth.setDate(1980,4,7);//初始化一个日期
  8. ui->tableInfo->clearContents();//只清除工作区,不清除表头
  9.  
  10. int Rows=ui->tableInfo->rowCount(); //数据区行数,
  11. for (int i=0;i<Rows;i++) //数据区第1行的编号为0,所以范围是0~rowCount()-1
  12. {
  13. strName=QString::asprintf("学生%d",i); //学生姓名
  14. if ((i % 2)==0) //分奇数,偶数行设置性别,及其图标
  15. strSex="男";
  16. else
  17. strSex="女";
  18.  
  19. createItemsARow(i, strName, strSex, birth,"汉族",isParty,70); //为某一行创建items
  20.  
  21. birth=birth.addDays(20); //日期加20天
  22. isParty =!isParty;
  23. }
  24. }

QTableWidget::clearContents() 函数清除表格数据区的所有内容,但是不清除表头。

QTableWidget::rowCount() 函数返回表格数据区的行数。

在 for 循环里为每一行生成需要显示的数据,然后调用自定义函数 createItemsARow(),为表格一行的各个单元格生成 QTableWidgetItem 对象。

createItemsARow() 是在窗体类里自定义的函数,其实现代码如下:

纯文本复制
 


设置好 item 的各种属性之后,用 QTableWidget 的 setItem 函数将 item 设置为单元格的项,例如:

ui->tableInfo->setItem(rowNo,MainWindow::colName,item);

在 currentCellChanged() 信号中,传递的参数 currentRow 和 currentColumn 表示当前单元格的行号和列号,通过这两个编号可以得到单元格的 QTableWidgetltem 对象 item。

获得 item 之后,通过 type() 函数得到单元格的类型参数,这个类型就是为单元格创建 QTableWidgetItem 对象时传递的类型参数。

再获取同一行的“姓名”单元格的项,用data()函数提取自定义数据,也就是创建单元格时存储的学生 ID。


下面是界面上“插入行” “添加行”“删除当前行”按钮的响应代码。在插入行之后,会调用 createItemsARow() 函数,为新创建的空行的各单元格构造 QTableWidgetItem 对象:

 

自动调整行高和列宽

 

这几个函数实际上是 QTableWidget 的父类 QTableView 的函数。

其他属性控制

 

遍历表格读取数据

  1. void MainWindow::createItemsARow(int rowNo,QString Name,QString Sex,QDate birth,QString Nation,bool isPM,int score)
  2. { //为一行的单元格创建 Items
  3. QTableWidgetItem *item;
  4. QString str;
  5. uint StudID=201605000; //学号基数
  6.  
  7. //姓名
  8. //新建一个Item,设置单元格type为自定义的MainWindow::ctName
  9. item=new QTableWidgetItem(Name,MainWindow::ctName);
  10. item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); //文本对齐格式
  11. StudID +=rowNo; //学号=基数+ 行号
  12. item->setData(Qt::UserRole,QVariant(StudID)); //设置studID为data
  13. ui->tableInfo->setItem(rowNo,MainWindow::colName,item); //为单元格设置Item
  14.  
  15. //性别
  16. QIcon icon;
  17. if (Sex=="男")
  18. icon.addFile(":/images/icons/boy.ico");
  19. else
  20. icon.addFile(":/images/icons/girl.ico");
  21. item=new QTableWidgetItem(Sex,MainWindow::ctSex); //新建一个Item,设置单元格type为自定义的 MainWindow::ctSex
  22. item->setIcon(icon);
  23. item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//为单元格设置Item
  24. ui->tableInfo->setItem(rowNo,MainWindow::colSex,item);//为单元格设置Item
  25.  
  26. //出生日期
  27. str=birth.toString("yyyy-MM-dd"); //日期转换为字符串
  28. item=new QTableWidgetItem(str,MainWindow::ctBirth);//新建一个Item,设置单元格type为自定义的 MainWindow::ctBirth
  29. item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); //文本对齐格式
  30. ui->tableInfo->setItem(rowNo,MainWindow::colBirth,item);//为单元格设置Item
  31.  
  32. //民族
  33. item=new QTableWidgetItem(Nation,MainWindow::ctNation); //新建一个Item,设置单元格type为自定义的 MainWindow::ctNation
  34. item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本对齐格式
  35. ui->tableInfo->setItem(rowNo,MainWindow::colNation,item);//为单元格设置Item
  36.  
  37. //是否党员
  38. item=new QTableWidgetItem("党员",MainWindow::ctPartyM);//新建一个Item,设置单元格type为自定义的 MainWindow::ctPartyM
  39. item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本对齐格式
  40. if (isPM)
  41. item->setCheckState(Qt::Checked);
  42. else
  43. item->setCheckState(Qt::Unchecked);
  44. item->setBackgroundColor(Qt::yellow);//Qt::green lightGray yellow
  45. ui->tableInfo->setItem(rowNo,MainWindow::colPartyM,item);//为单元格设置Item
  46.  
  47. //分数
  48. str.setNum(score);
  49. item=new QTableWidgetItem(str,MainWindow::ctScore);//新建一个Item,设置单元格type为自定义的 MainWindow::ctPartyM
  50. item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本对齐格式
  51. ui->tableInfo->setItem(rowNo,MainWindow::colScore,item);//为单元格设置Item
  52. }
  53. 该表格的每一行有5列,为每一个单元格都创建一个 QTableWidgetItem 类型的变量 item,并做相应的设置。

    创建 QTableWidgetItem 使用的构造函数的原型为:

    QTableWidgetItem::QTableWidgetItem (const QString &text, int type = Type)

    其中,第一个参数作为单元格的显示文字,第二个参数作为节点的类型。

    例如创建“姓名”单元格对象时的语句是:

    cellItem=new QtableWidgetItem(Name,MainWindow::ctName);

    其中,MainWindow::ctName 是定义的枚举类型 CellType 的一个常量值。

    “姓名”单元格还调用 setData() 函数设置了一个自定义的数据,存储的是学生 ID。

    cellItem->setData(Qt::UserRole,QVariant(StudID));

    这个自定义数据是不显示在界面上的,但是与单元格相关联。

    QTableWidgetItem 有一些函数对单元格进行属性设置,如下:
  54. setTextAlignment (int alignment):设置文字对齐方式。
  55. setBackground(const QBrush &brush):设置单元格背景颜色。
  56. setForeground(const QBrush &brush):设置单元格前景色。
  57. setIcon(const QIcon &icon):为单元格设置一个显不图标。
  58. setFont(const QFont &font):为单元格显示文字设置字体。
  59. setCheckState(Qt::CheckState state):设置单元格勾选状态,单元格里出现一个QCheckBox组件。
  60. setFlags(Qt::ItemFlags flags):设置单元格的一些属性标记。
  61. 其中,MainWindow::colName 是定义的枚举类型 FieldColNum 的一个常量值。

    这样初始化设置后,就可以得到如图 2 所示的运行时的表格内容。表格里并没有显示学号,学号是“姓名”单元格的关联数据。

    获得当前单元格数据

    当鼠标在表格上单击单元格时,被选中的单元格是当前单元格。通过 QTableWidget 的 currentColumn() 和 currentRow() 可以获得当前单元格的列编号和行编号。

    当前单元格发生切换时,会发射 currentCellChanged() 信号和 currentItemChanged() 信号,两个信号都可以利用,只是传递的参数不同。

    对 currentCellChanged() 信号编写槽函数,用于获取当前单元格的数据,以及当前行的学生的学号信息,代码如下:
     
  62. void MainWindow::on_tableInfo_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
  63. {//当前选择单元格发生变化时的响应
  64. Q_UNUSED(previousRow);
  65. Q_UNUSED(previousColumn);
  66.  
  67. QTableWidgetItem* item=ui->tableInfo->item(currentRow,currentColumn); //获取单元格的 Item
  68. if (item==NULL)
  69. return;
  70.  
  71. labCellIndex->setText(QString::asprintf("当前单元格坐标:%d 行,%d 列",currentRow,currentColumn));
  72.  
  73. int cellType=item->type();//获取单元格的类型
  74. labCellType->setText(QString::asprintf("当前单元格类型:%d",cellType));
  75.  
  76. item=ui->tableInfo->item(currentRow,MainWindow::colName); //取当前行第1列的单元格的 item
  77. int ID=item->data(Qt::UserRole).toInt();//读取用户自定义数据
  78. labStudID->setText(QString::asprintf("学生ID:%d",ID));//学生ID
  79. }
  80. QTableWidget 处理行操作的函数如下:
  81. insertRow(int row):在行号为row的行前面插入一行,如果row等于或大于总行数,则在表格最后添加一行。insertRow()函数只是插入一个空行,不会为单元格创建QTableWidgetItem对象,需要手工为单元格创建。
  82. removeRow(int row):删除行号为 row 的行。
  83. void MainWindow::on_btnInsertRow_clicked()
  84. { //插入一行
  85. //int curRow;
  86. int curRow=ui->tableInfo->currentRow();//当前行号
  87.  
  88. ui->tableInfo->insertRow(curRow); //插入一行,但不会自动为单元格创建item
  89. createItemsARow(curRow, "新学生", "男",
  90. QDate::fromString("1990-1-1","yyyy-M-d"),"苗族",true,60 ); //为某一行创建items
  91. }
  92. void MainWindow::on_btnAppendRow_clicked()
  93. { //添加一行
  94. //int curRow;
  95. int curRow=ui->tableInfo->rowCount();//当前行号
  96. ui->tableInfo->insertRow(curRow);//在表格尾部添加一行
  97. createItemsARow(curRow, "新生", "女",
  98. QDate::fromString("2000-1-1","yyyy-M-d"),"满族",false,50 ); //为某一行创建items
  99. }
  100. void MainWindow::on_btnDelCurRow_clicked()
  101. {//删除当前行及其items
  102. //int curRow;
  103. int curRow=ui->tableInfo->currentRow();//当前行号
  104. ui->tableInfo->removeRow(curRow); //删除当前行及其items
  105. }
  106. QTableWidget 有几个函数自动调整表格的行高和列宽,分别如下:
  107. resizeColumnsToContents():自动调整所有列的宽度,以适应其内容。
  108. resizeColumnToContents(int column):自动调整列号为 co/www 的列的宽度。
  109. resizeRowsToContents():自动调整所有行的高度,以适应其内容。
  110. resizeRowToContents(int row):自动调整行号为 raw 的行的高度。
  111. 设置表格内容是否可编辑:QTableWidget 的 EditTriggers 属性表示是否可编辑,以及进入编辑状态的方式。界面上的"表格可编辑"复选框的槽函数代码为:
     
    1. void MainWindow::on_chkBoxTabEditable_clicked(bool checked)
    2. { //设置编辑模式
    3. if (checked)
    4. //双击或获取焦点后单击,进入编辑状态
    5. ui->tableInfo->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
    6. else
    7. ui->tableInfo->setEditTriggers(QAbstractItemView::NoEditTriggers); //不允许编辑
    8. }
  112. 设置行表头、列表头是否显示:horizontalHeader()获取行表头,verticalHeader()获取列表头,然后可设置其可见性。
     
    1. void MainWindow::on_chkBoxHeaderH_clicked(bool checked)
    2. {
    3. //是否显示水平表头
    4. ui->tableInfo->horizontalHeader()->setVisible(checked);
    5. }
    6. void MainWindow::on_chkBoxHeaderV_clicked(bool checked)
    7. {
    8. //是否显示垂直表头
    9. ui->tableInfo->verticalHeader()->setVisible(checked);
    10. }
  113. 间隔行底色:setAltematingRowColors() 函数可以设置表格的行是否用交替底色显示,若为交替底色,则间隔的一行会用灰色作为底色。具体底色的设置需要用 styleSheet,在后续章节会有介绍。
     
    1. void MainWindow::on_chkBoxRowColor_clicked(bool checked)
    2. {
    3. ui->tableInfo->setAlternatingRowColors(checked);
    4. }
  114. 选择模式:setSelectionBehavior() 函数可以设置选择方式为单元格选择,还是行选择:
     
    1. void MainWindow::on_rBtnSelectItem_clicked()
    2. {//选择行为:单元格选择
    3. ui->tableInfo->setSelectionBehavior(QAbstractltemView::Selectltems);
    4. }
    5. void MainWindow::on_rBtnSelectRow_clicked()
    6. {//选择行为:行选择
    7. ui->tableInfo->setSelectionBehavior(QAbstractltemView::SelectRows);
    8. }
  115. “读取表格内容到文本”按钮演示了将表格数据区的内容全部读出的方法,它将每个单元格的文字读出,同一行的单元格的文字用空格分隔开,作为文本的一行,然后将这行文字作为文本编辑器的一行内容,代码如下:
    纯文本复制
     
  116. void MainWindow::on_btnReadToEdit_clicked()
  117. {//将 QTableWidget的所有行的内容提取字符串,显示在QPlainTextEdit里
  118. QString str;
  119. QTableWidgetItem *cellItem;
  120.  
  121. ui->textEdit->clear(); //文本编辑器清空
  122. for (int i=0;i<ui->tableInfo->rowCount();i++) //逐行处理
  123. {
  124. str=QString::asprintf("第 %d 行: ",i+1);
  125. for (int j=0;j<ui->tableInfo->columnCount()-1;j++) //逐列处理,但最后一列是check型,单独处理
  126. {
  127. cellItem=ui->tableInfo->item(i,j); //获取单元格的item
  128. str=str+cellItem->text()+" "; //字符串连接
  129. }
  130. cellItem=ui->tableInfo->item(i,colPartyM); //最后一列,党员
  131. if (cellItem->checkState()==Qt::Checked) //根据check状态显示文字
  132. str=str+"党员";
  133. else
  134. str=str+"群众";
  135. ui->textEdit->appendPlainText(str); //添加到编辑框作为一行
  136. }
  137. }
发布了21 篇原创文章 · 获赞 2 · 访问量 2197

Guess you like

Origin blog.csdn.net/conimade/article/details/104397401