我们常常会有这样的需求,为QTableView增加复选框checkbox和选择下拉框combbox,毕竟依靠键盘输入不是很好约束其规范性。下面我们逐个来介绍。完成之后的效果如下:
一、准备TableView
1、数据准备
数据大家可以随意准备,有的话有自己的数据,没有的话就用网上的在线数据生成,这样的网站比较多了,搜索一下就可以找到,我这个就是网上自动生成的,自己增加了一个表头而已。
需要测试的也可以拿我这份:
ID 介绍人 姓名 江湖名称 性别 英文名 入会
wangabao 丹丽棠 王阿宝 欧阳阿宝 男性 aaron_abbott 0
liabian 翦国诚 李阿扁 百里阿扁 女性 abby_acevedo 1
zhangabin 帅超雄 张阿宾 淳于阿宾 男性 abdul_acosta 0
liuacai 崇军君 刘阿才 澹台阿才 女性 abe_adams 0
chenacai 晋军君 陈阿财 第五阿财 男性 abel_adkins 1
yangachun 丹理达 杨阿春 东方阿春 男性 abigail_aguilar 0
huangacong 帅宝麟 黄阿聪 独孤阿聪 女性 abraham_aguirre 0
wuada 崇宝麟 吴阿达 端木阿达 女性 ada_albert 1
zhaoada 邱津晶 赵阿大 段干阿大 男性 adam_alexander 1
zhouae 植丽棠 周阿娥 公孙阿娥 女性 adan_alford 1
2、界面和Model&View准备
完成界面的控件拖放后,直接在窗体构造函数中写代码
setCentralWidget(ui->TableView);
theModel = new QStandardItemModel(this);//数据模型
theSelection = new QItemSelectionModel(theModel);//选择模型
ui->TableView->setModel(theModel);//数据模型
ui->TableView->setSelectionModel(theSelection);//选择模型
3、普通tableview的加载
tableview实现的关键代码:
int rowcount=filedata.count();
theModel->setRowCount(rowcount-1);
QString header=filedata.at(0);
QStringList headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts);
theModel->setHorizontalHeaderLabels(headerList);
QString oneRowTextlist;
QStandardItem *mitem;
QStringList contentList;
int i,j;
for (i=1;i<rowcount;i++) {
oneRowTextlist=filedata.at(i); //从filedata中获取一行的内容
contentList=oneRowTextlist.split(QRegExp("\\s+"),QString::SkipEmptyParts);//一个或多个空格、TAB等分隔符隔开的字符串分解为多个字符串
for (j=0;j<6;j++)
{
mitem=new QStandardItem(contentList.at(j));//创建item
theModel->setItem(i-1,j,mitem); //为模型的i行j列位置设置Item
}
这里实现的tableview就是我们最常见的表格,双击修改:
缺点很显然,对于逻辑值输入可以很随意,不利于后面的数据存储。
二、增加复选框checkbox
我们首先为“入会”栏增加复选框。
复选框的增加QStandardItemModel已经提供了,应该说是最容易的了。调用QStandardItemModel的setitem及配合setCheckable可完成。
int rowcount=filedata.count();
theModel->setRowCount(rowcount-1);
QString header=filedata.at(0);
QStringList headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts);
theModel->setHorizontalHeaderLabels(headerList);
QString oneRowTextlist;
QStandardItem *mitem,*checkItem;
QStringList contentList;
int i,j;
for (i=1;i<rowcount;i++) {
oneRowTextlist=filedata.at(i); //从filedata中获取一行的内容
contentList=oneRowTextlist.split(QRegExp("\\s+"),QString::SkipEmptyParts);//一个或多个空格、TAB等分隔符隔开的字符串分解为多个字符串
for (j=0;j<7;j++)
{
mitem=new QStandardItem(contentList.at(j));//创建item
theModel->setItem(i-1,j,mitem); //为模型的i行j列位置设置Item
}
checkItem=new QStandardItem(headerList.at(j));//最后一列是Checkable,设置
checkItem->setCheckable(true);
checkItem->setCheckState((contentList.at(j)=="0")?Qt::Unchecked:Qt::Checked);
theModel->setItem(i-1,j,checkItem); //为模型的某个行列位置设置Item
我们可以看到,入会一栏由0或1变成了复选框了。
三、增加下拉框commbox
下拉框的增加有很多中方式,这里介绍最简单的一种方式,直接在tableview中增加,其实还是以利用消息槽及自定义下拉框的代理来完成。
//filedata接收来自filecontentString的内容,由读取文本函数完成
int rowcount=filedata.count();
theModel->setRowCount(rowcount-1);
QString header=filedata.at(0);
QStringList headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts);
theModel->setHorizontalHeaderLabels(headerList);
QString oneRowTextlist;
QStandardItem *mitem,*checkItem;
QStringList contentList;
QComboBox* cmb;
int i,j;
for (i=1;i<rowcount;i++) {
oneRowTextlist=filedata.at(i); //从filedata中获取一行的内容
contentList=oneRowTextlist.split(QRegExp("\\s+"),QString::SkipEmptyParts);//一个或多个空格、TAB等分隔符隔开的字符串分解为多个字符串
for (j=0;j<6;j++)
{
mitem=new QStandardItem(contentList.at(j));//创建item
theModel->setItem(i-1,j,mitem); //为模型的i行j列位置设置Item
}
checkItem=new QStandardItem(headerList.at(j));//最后一列是Checkable,设置
checkItem->setCheckable(true);
checkItem->setCheckState((contentList.at(j)=="0")?Qt::Unchecked:Qt::Checked);
theModel->setItem(i-1,j,checkItem); //为模型的某个行列位置设置Item
cmb = new QComboBox();
cmb->addItems({"男性", "女性"});
cmb->setCurrentText(contentList.at(4));
cmb->setStyleSheet ("QComboBox { border-radius: 3px;border: 1px ;selection-color: black;selection-background-color: darkgray; } QFrame { border: 0px; } QComboBox::drop-down{background-color: white;}");
ui->TableView->setIndexWidget(theModel->index(i-1,4),cmb);//直接用tableview来设置Item为combbox
为了使下拉框与tableview表格风格统一,我们这里通过setStyleSheet设置了combbox的风格,效果如下:
四、读入文本数据代码
1、读入函数
此函数负责将文本数据读入,放入变量filecontentString中供上面提到的tableview的使用,由filedata变量接收;
void MainWindow::getfileStream()
{
QString curPath,fileName,str;
curPath=QCoreApplication::applicationDirPath(); //获取应用程序的路径
//调用打开文件对话框打开一个文件
fileName=QFileDialog::getOpenFileName(this,tr("打开一个文件"),curPath,
"井斜数据文件(*.txt);;所有文件(*.*)");
if (fileName.isEmpty())
return ; //
QStringList fFileContent;//
QFile file(fileName); //以文件方式读出
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream aStream(&file); //用文本流读取文件
while (!aStream.atEnd())
{
str=aStream.readLine();//读取文件的一行
fFileContent.append(str); //添加到StringList
}
file.close();
filecontentString= fFileContent;
}
}
2、中文乱码的处理
使用上面的函数可能会遇到乱码,关键看大家建立工程时使用的是什么编码utf-8还是GBK的,反正中国人就这两者之一,不对你就两个交换一下
第一种方式,可以给文本流增加编码设置
QTextStream aStream(&file); //用文本流读取文件
aStream.setCodec("UTF-8");//设置文件流编码方式
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream aStream(&file); //用文本流读取文件
aStream.setCodec("UTF-8");//设置文件流编码方式
while (!aStream.atEnd())
{
str=aStream.readLine();//读取文件的一行
fFileContent.append(str); //添加到StringList
}
file.close();
filecontentString= fFileContent;
}
第二种,可以给文件直接编码设置
QTextCodec *codec = QTextCodec::codecForName("UTF-8");//添加
QStringList fFileContent;//
QTextCodec *codec = QTextCodec::codecForName("utf-8");//添加
QFile file(fileName); //以文件方式读出
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
while (!file.atEnd())
{
str=codec->toUnicode(file.readLine());//读取文件的一行
fFileContent.append(str); //添加到StringList
}
file.close();
filecontentString= fFileContent;
}
有时间,我们再整理其他两种方式实现的tableview中的下拉框。感兴趣的童鞋请继续关注。
五、源代码下载
上面只是给出了关键代码,如果看不明白,可以参看源代码,也许理解更快。
源代码在这里下载