QTableWidget 用法总结
QTableWidget是QT程序中常用的显示数据表格的空间,很类似于VC、C#中的DataGrid。说到QTableWidget,就必须讲一下它跟QTabelView的区别了。QTableWidget是QTableView的子类,主要的区别是QTableView可以使用自定义的数据模型来显示内容(也就是先要通过setModel来绑定数据源),而QTableWidget则只能使用标准的数据模型,并且其单元格数据是QTableWidgetItem的对象来实现的(也就是不需要数据源,将逐个单元格内的信息填好即可)。这主要体现在QTableView类中有setModel成员函数,而到了QTableWidget类中,该成员函数变成了私有。使用QTableWidget就离不开QTableWidgetItem。QTableWidgetItem用来表示表格中的一个单元格,正个表格都需要用逐个单元格构建起来。
一. 对QTableWidget本身的效果实现
1. 将表格变为禁止编辑
在默认情况下,表格里的字符是可以更改的,比如双击一个单元格,就可以修改原来的内容,如果想禁止用户的这种操作,让这个表格对用户只读,可以这样:
tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
QAbstractItemView.NoEditTriggers是QAbstractItemView.EditTrigger枚举中的一个,都是触发修改单元格内容的条件:
0
1
2
4
8
16
31
0
1
2
如果两种都要设置,只要用 Qt.AlignHCenter | Qt.AlignVCenter 的方式即可
3. 合并单元格效果的实现:
tableWidget->setSpan(0, 0, 3, 1) # 其参数为: 要改变单元格的 1行数 2列数 要合并的 3行数 4列数
4. 设置单元格的大小
首先,可以指定某个行或者列的大小
还可以将行和列的大小设为与内容相匹配
5. 获得单击单元格的内容
通过实现 itemClicked (QTableWidgetItem *) 信号的槽函数,就可以获得鼠标单击到的单元格指针,进而获得其中的文字信息
connect(tableWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(getItem(QTreeWidgetItem*,int)));
//将itemClicked信号与函数getItem绑定
6.QTableWidget要调整表格行宽主要涉及以下一个函数
resizeColumnsToContents(); 根据内容调整列宽 resizeColumnToContents(int col); 根据内容自动调整给定列宽horizontalHeader()->setResizeMode 把给定列设置为给定模式主要模式有Stretch和Fixed
7.
int row = rowCount(); removeRow(row);//清除已有的行列 setShowGrid(true);//显示表格线verticalHeader()->setVisible(false);//隐藏左边垂直 QHeaderView *headerView = horizontalHeader(); headerView->setMovable(false);//去除表头的移动 headerView->resizeSection(0,284);//设置第一列宽 headerView->resizeSection(1,127);//设置第二列宽 headerView->setResizeMode(QHeaderView::Fixed);//列表不能移动 headerView->setClickable(false);//不响应鼠标单击 setEditTriggers(QTableWidget::NoEditTriggers);//不能编辑 setSelectionBehavior(QTableWidget::SelectRows);//一次选中一行 setSelectionMode(QAbstractItemView::SingleSelection);//只能单选 /*QScrollBar *scrollBar = horizontalScrollBar(); scrollBar->hide();*/ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//去掉水平滚动条setVerticalScrollMode(QAbstractItemView::ScrollPerItem);//垂直滚动条按项移动 setAutoScroll(false);//去掉自动滚动
//控件刚开始的时候左边默认自带序列号,如果想去掉左边的行号,加上下面的代码就可以了。QHeaderView* headerView = table的名字->verticalHeader();headerView->setHidden(true);
//显示最后一行 使用scrollToItem方法
int row=ui->tabWigDataShow->rowCount();
if(row-1>0)
{
ui->tabWigDataShow->scrollToItem( ui->tabWigDataShow->item(row-1,0), QAbstractItemView::PositionAtBottom);
}
-----------------
Qt提供 QTableWidget作为表格的类以实现表格的基本功能,表格中所装载的每一个单元格由类QTableWidgetItem提供。这是基于表格实现 Qt提供的一个基础类,若想实现定制表格和单元格的功能则需要派生重写,使用Qt经典的MV结构 QTableView+QAbstractItemMode来实现。
关于QTableWidget+QTableWidgetItem使用方法简介:
通常在使用这对组合以实现表格基本功能时,通常的做法是:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
示例代码一:
QTableWidget* tableWidget = new QTableWidget;
tableWidget->setRowCount(11); // 设置表格的行数
tableWidget->setColumnCount(11); // 设置表格的列数
// 为表格的每一行每一列设置一个可以装载数据的item
for(int nRow = 0; nRow < 11; nRow++)
{
for(int nColumn = 0; nColumn < 11; nColumn++);
{
QTableWidgetItem* item = new QTableWidgetItem;
tableWidget->setItem(nRow, nColumn, item);
}
}
// 通过索引访问表格中的单元格并赋值
QTableWidgetItem* item = tableWidget->itemAt(3, 3);
item->setText(“MyTableItem”);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
OK!如果你仅仅是操作表格的单元格上述代码没有问题,但是如果你一旦涉及到表格的单元格合并时,这样操作表格就会出问题!
下面是笔者在开发过程中实现表格合并时遇到的一些问题及相关的解决方法:
问题一:如果按照示例代码一方式创建表格和单元格进行表格合并时
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tableWidget->setSpan(0, 0, 1, 11);
QTableWidgetItem* itemGet = tableWidget->itemAt(0, 0);
itemGet->setTextAlignment(Qt::AlignHCenter);
itemGet->setText(“MyTableItem(0, 0)”);
/* OK!上述代码没问题,实现第一行单元格的合并和设置text */
itemGet = NULL;
itemGet = tableWidget->itemAt(1, 1);
itemGet->setTextAlignment(Qt::AlignHCenter);
itemGet->setText(“MyTableItem(1, 1)”);
/* Error!这里就出问题了,itemAt(1, 1)返回的仍然是itemAt(0, 0)所指向的单元格。就是由表格合并函数tableWidget->setSpan()所带来的问题,表格合并使得itemAt()等相关的索引函数出现问题。(具体原因还不太清楚)*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
解决方法:
(1) 既然setSpan()函数破坏了itemAt()的索引,我们可以通过重新建立新的item的方式进行访问方法如下:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QTableWidgetItem* newItem = new QTableWidgetItem;
tableWidget->setItem(1, 1, newItem);
newItem->setTextAlignment(Qt::AlignHCenter);
newItem->setText(“MyTableItem(1, 1)”);
/* 这样就可以实现表格其它位置单元格的赋值操作 */
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(2) 不在创建QTableWidget时为单元格动态创建QTableWidgetItem,而是在用到某个单元格是再动态创建QTableWidgetItem。(推荐使用这种方法,避免内存泄露)
问题二:和问题一的情况相同都是由于索引而产生的,这次是由于selectedRange()索引错误而产生。
使用TableWidget生成表格后,希望通过鼠标的选择合并单元格,这时会发现只有第一次调用selectedRange()能正确返回鼠标所选择的单元格的范围并执行合并成功,第二次以后selectedRanged()返回的永远是鼠标选择范围的第一单元格。
解决方法:使用函数selectedRanges()。该函数将返回QList对象,里面包含了被鼠标选择的所有单元格的位置,这样我们就可以实现多次合并。代码如下:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tableWidget->setSpan(tableWidget->selectedRanges().first().topRow(),
tableWidget->selectedRanges().first().leftColumn(),
tableWidget->selectedRanges().last().bottomRow() –
tableWidget->selectedRanges().first().topRow() + 1,
tableWidget->selectedRanges().last().rightColumn() -
tableWidget->selectedRanges().first().leftColumn() + 1);