Qt进阶–Item Views详解(基础,原创,超级详细)

  • Post author:
  • Post category:其他



在设计窗口的控件栏有一种控件叫Item Views,非常有用但是很多人不会,这里详细讲一下.

用处:

按照一定格式现实数据(列表,表格,树),并且可以在对数据操作的时候增加槽函数.

Excel:

还有这种文件树状图:

基本原理:

就是MVC(Model View Controller,模型-视图-控制器/代理):

这个在游戏和网络应用开发都涉及到:


http://c.biancheng.net/view/1864.html


https://zhuanlan.zhihu.com/p/42719287

都讲得不错,其实就是一种解耦的思想.

现在我们知道模型和视图关联,不同的模型要关联不同的视图.

先放一张模型类和视图类的大图:


下面本文主要分三个部分,依次讲解图中三种model/view的配合使用:

1.QStringListModel和QListView的配合使用:

它们的详细用法分为以下几个部分:

1.1.初始化(在父窗口的构造函数中演示):

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    	//QStringListModel可以理解为一个储存着数据的盒子,要先准备好盒子里的初始数据
    QStringList theStrList; //保存初始 StringList
    theStrList<<"北京"<<"上海"<<"天津"<<"河北"<<"山东"<<"四川"<<"重庆"<<"广东"<<"河南"; //初始化 StringList
    
    	//创建模型对象,注意它的构造函数的参数是父窗口,而不是列表视图控件
    theModel=new QStringListModel(this);

    	//setStringList() 函数可以初始化数据模型的字符串列表的内容
    	//也就是把数据装进这个盒子里
    theModel->setStringList(theStrList); 

    	//在这里使用setModel()关联模型和视图
    	//为listView设置数据模型
    ui->listView->setModel(theModel); 

}

1.2.编辑设置:

设置 QListView 的条目是否可以编辑,以及如何进入编辑状态

QListView::setEditTriggers():设置 QListView 的条目是否可以编辑,以及如何进入编辑状态

参数如下(从帮助手册截下来的):

1.3.添加和修改操作:

在列表中添加一行,或者修改某一行的数据


首先要在知道:

模型索引(model index)

模型不提供接口直接给你数据,而是要先获取模型索引对象,

再用模型索引从模型中获取数据.(这个东西看起来多此一举,麻烦了,但在树状视图中就简单了)

具体讲解还是看:http://c.biancheng.net/view/1864.html

讲的非常基础了


同时还要知道


的几个接口:

bool QStringListModel::insertRow (int row):row 是一个行号,表示在 row 行之前插入一个空行,这个行没有内容;


QModelIndex

QStringListModel::index(int row, int column = 0, const

QModelIndex

&parent = QModelIndex()):根据传递的行号、列号、父项的模型索引生成一个模型索引,这个模型索引就是你在模型中获取,修改数据的凭证;int

int QModelIndex::row():返回本模型索引对象的列数;

QModelIndex QListView::currentIndex():返回视图中选中的项的模型索引,很方便;

int QStringListModel::rowCount ():当前模型的总行数;

(这里再说一点,模型中的每个项会有很多role–角色,在不同的条件下显示不同的role,就好像一个人有很多身份,如父亲,职员,丈夫,在不同的场合有不同的身份)

bool QStringListModel::setData(const

QModelIndex

&index, const

QVariant

&value, int role = Qt::EditRole):将index处的项的指定role的数据设为value;

一个项的角色(role)的可选参数如下(也是从帮助手册当的):


结论:


在添加项(行)的步骤:



用insertRow()添加一行准备放数据—->使用index()获取目标项的模型索引—->通过setData()设置项的数据;


修改项(行的步骤):



使用index()获取目标项的模型索引—->通过setData()设置项的数据;


实例代码:

//在列表的最后添加一行
    //添加一个空行做准备
theModel->insertRow(theModel->rowCount()); 
    
    //获取最后一行的模型索引
QModelIndex index=theModel->index(theModel->rowCount()-1);
    
    //根据模型索引修改最后一项的显示角色的数据
theModel->setData(index,"添加的新数据",Qt::DisplayRole);

1.4.删除操作:

删除一行和删除多行,两个QStringListModel提供的接口;

removeRow(int row):删除指定行;

removeRows(int row,int count):从row行开始,删除count列;

1.5:查询操作:

也就是在代码中获取指定位置的项的值

主要就是这个方法:




Q

StringList QStringListModel::stringList() const:就是把模型中的数据取出来

然后你再对获取到的QStringList指定位置查询就好.

2.QStandardItemModel和QTableView的配合使用:

有了上面的操作经验,这个也很简单了,但还是有几点区别说明一下:

1.模型类和视图类都变了,注意一下;

2.在表格中还涉及到了表头

3.在选择的时候,可以一次选中多个单元格,为了知道获取的单元格,就又多了个类QItemSelectionModel用来获取选中单元格的模型索引;

4.比列表方便的是,表格添加行的时候不用先创建空白行了

5.其他的思想,套路大同小异,聪明的你们一定看帮助文档就能搞定

基本操作代码演示:


说明:在主窗口中建立QTableView控件,下面的代码是主窗口的构造函数代码,在其中进行了一些基本操作(建议复制放到Qt里面看):

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
    //这个就是数据模型
    QStandardItemModel* themodel;
    
    //这个是方便获得模型索引的类对象,由数据模型构造(在后面)
    QItemSelectionModel*theselection;
    
    //这里创建一个五行七列的表格
    themodel=new QStandardItemModel(5,7,this);
    
    //根据数据模型创建选择模型
    theselection=new QItemSelectionModel(themodel);
    
    //关联数据模型和视图模型
    ui->tableView->setModel(themodel);
    
    //关联视图模型和选择模型
    ui->tableView->setSelectionModel(theselection);
    
    //设置选择模式,具体参数及含义看帮助文档吧
    ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);

    //下面依次进行一些基本操作:

    //1.首先是初始化表格内容:
    QStandardItem*item;
    for(int i=0;i<themodel->columnCount();i++){
        for(int j=0;j<themodel->rowCount();j++){
            item=new QStandardItem(QString::number((i+1)*(j+1)));//这里注意一下,QStandard构造时参数要求是QString
            item->setCheckable(true);//这个函数可以给每个小格加个勾选框
            //底下这个是核心方法.
            themodel->setItem(j,i,item);
            /*void QStandardItemModel::setItem(int row, int column, QStandardItem *item)
            不用索引模型,直接修改,方便不少*/
        }
    }

    
    
    //2.设置表格表头,水平反向和竖直反向的都要有:
    QStringList horizontalHeader= QStringList();
    horizontalHeader<<"周一"<<"周二"<<"周三"<<"周四"<<"周五"<<"周六"<<"周日";
        //底下这个是核心方法
    themodel->setHorizontalHeaderLabels(horizontalHeader);
    /*void QTableView::setVerticalHeader(QHeaderView *header)
        这个设置表头的是view而不是model,
        显然,表头的数据不归数据模型管,
        所以表头不算在列数和行数内*/
        //竖直表头同理
    QStringList vertical=QStringList();
    vertical<<"no.1"<<"no.2"<<"no.3"<<"no.4"<<"no.5";
    themodel->setVerticalHeaderLabels(vertical);

    
    
    
    //3.添加一行
    QList<QStandardItem*> newrow;
    for(int i=0;i<themodel->columnCount();i++){
        newrow<<new QStandardItem("0");
    }
        //底下这个是核心方法
    themodel->insertRow(themodel->rowCount(),newrow);
    //删除同理.方法是:QList<QStandardItem *> QStandardItemModel::takeRow(int row)


    //4.获取选中的单元格并操作
        //获取选择单元格的模型索引列表
    QModelIndexList selectedIndex=theselection->selectedIndexes();
    
    for (int i=0;i<selectedIndex.count();i++)
    {     //获取一个模型索引
        QModelIndex aIndex=selectedIndex.at(i);
            //获取项数据
        QStandardItem* aItem=themodel->itemFromIndex(aIndex);
        //然后就可以对项数据进行操作了
    }


    //5.查看某处的单元格的勾选框选中情况
    QStandardItem* aItem=themodel->item(1,2); //最后一列是逻辑型
    if (aItem->checkState()==Qt::Checked){
        //这里就是对勾选中的单元格进行的操作
    }

    
}


待改进:更改table的显示样式,更好看一些,能表头独立颜色,单元格颜色交错开那种,还有右键菜单,菜单这个可以看这个博客


https://blog.csdn.net/weixin_33912445/article/details/91743835?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-8


;

3.QStandardItemModel和QTreeView的配合使用:


https://blog.csdn.net/dpsying/article/details/80383752

这个博客讲的很不错了,等我再了解了解;



版权声明:本文为realliyuhao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。