我们常常会有这样的需求,为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中的下拉框。感兴趣的童鞋请继续关注。

五、源代码下载

上面只是给出了关键代码,如果看不明白,可以参看源代码,也许理解更快。
源代码在这里下载

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐