QTreeView 动态设置复选框

动态设置复选框的步骤

初始化一个QTreeView 的界面,并设置相关的model

// 在ui中新建两个QTreeView 命名为 addedView,notAddView
//初始化QTreeView 界面
 ui->setupUi(this);
 ui->addedView->header()->hide();//表头隐藏
 ui->notAddView->header()->hide();
 //设置model
QStandardItemModel m_addedModel, m_notAddModel;
ui->addedView->setModel(&m_addedModel);
ui->notAddView->setModel(&m_notAddModel);

从数据库或其他地方获取相关数据:QSet<QString> addPeople,QSet<QString> notAddPeople
其中addPeople展示在addedView界面上,notAddPeople展示在notAddView界面上

    if(!addPeople.empty())
	{
		m_addedModel.clear();
        //如果addPeople(群已有成员)存在,则显示在界面上
        if(!addPeople.empty())
		{
            int i=0;
            QSet<QString>::iterator iter;
            for(iter = addPeople.begin(); iter != addPeople.end(); iter++)
			{
                QStandardItem* pTem = new QStandardItem;  // 新建项
				pTem->setText(*iter);                     // 设置显示的名称
				pTem->setCheckable(true);                 // 设置为复选框
				m_addedModel.appendRow(pTem);             // 把新建项插入到模型中
            }
        }
    }

复选框如下图所示
在这里插入图片描述

功能:右边(未添加成员界面)选中复选框,点击添加,被选中的人会移到左边(已有成员)

将按钮和槽函数绑定:

connect(ui->pushButtonAdd, SIGNAL(clicked()), this, SLOT(slot_pushButtonAdd_clicked()));

槽函数思路

  • QStandardItemModel
    资料:函数介绍TableView、QStandardItemModel、QItemSelectionModel
    暂且将该函数理解为管理二位数据的类,我们通过ui->addedView->setModel(&m_addedModel);将视图view和QStandardItemModel 绑定到一起。这样就可以通过QStandardItemModel 来管理显示在视图上的数据了

选中的数据,通过QStandardItemModel 来获取:
首先遍历QStandardItemModel 所有数据,查看哪个复选框被选中了checkState() == Qt::Checked
如果选中了,就新建一个QStandardItem,加入到m_addedModel模型中
代码如下:

QStringList vecIndexs;
	for (int i = 0; i < m_notAddModel.rowCount(); i++) //遍历每一行
	{
		if (m_notAddModel.itemFromIndex(m_notAddModel.index(i, 0))->checkState() == Qt::Checked) //获取每一行的第一列,我只用了一列
		{
			QStandardItem* pItemEx = new QStandardItem(m_notAddModel.itemFromIndex(m_notAddModel.index(i, 0))->text());
			pItemEx->setCheckable(true);
			m_addedModel.appendRow(pItemEx);

		}
		else
		{
			vecIndexs.push_back(m_notAddModel.itemFromIndex(m_notAddModel.index(i, 0))->text());
		}
	}

	m_notAddModel.clear();
	for (size_t i = 0; i < vecIndexs.size(); i++)
	{
		QStandardItem* pItemEx = new QStandardItem(vecIndexs[i]);
		pItemEx->setCheckable(true);
		m_notAddModel.appendRow(pItemEx);
	}

以上是解决:点击按钮,处理复选框的内容。
如果要解决点击复选框,处理复选框,比如点击父节点,全选子节点。

参考: Qt树形控件QTreeView使用2——复选框的设置

通过QStandardItemModel设置的项目,任何改变都会触发void QStandardItemModel::itemChanged(QStandardItem * item)信号
关联项目属性改变的信号和槽
connect ( model ,&QStandardItemModel::itemChanged , this ,&Widget::treeItemChanged );

void Widget : : treeItemChanged ( QStandardItem * item )
{
    if ( item == nullptr )
    return ;
    if ( item - > isCheckable ())
    {
        //如果条目是存在复选框的,那么就进行下面的操作
        Qt : : CheckState state = item - > checkState (); //获取当前的选择状态
        if ( item - > isTristate ())
        {
             //如果条目是三态的,说明可以对子目录进行全选和全不选的设置
            if ( state != Qt : : PartiallyChecked )
            {
                //当前是选中状态,需要对其子项目进行全选
                treeItem_checkAllChild ( item , state == Qt : : Checked ? true : false );
            }
        }
        else
        {
            //说明是两态的,两态会对父级的三态有影响
            //判断兄弟节点的情况
            treeItem_CheckChildChanged ( item );
        }
    }
}

这里的逻辑是:点击复选框就会触发 QStandardItemModel::itemChanged 信号,查看当前项的状态,对它进行操作。
和上一个事件对比:点击按钮,需要遍历所有项目QStandardItem,一个个查看是否选中(不知道有没有更好的方法)

问题:没有搞清楚 QItemSelectionModel干吗用的?
我弄混了的概念
QTreeView使用总结5,选中信号处理
Qt 学习之路:视图选择 (QItemSelectionModel)
Qt模型/视图框架(一)

QT MVC的概念

Qt Model/View(模型/视图)结构(无师自通)
模型-视图 编程

模型

所有的基于项数据的数据模型(Model)都是基于 QAbstractltemModel 类的,这个类定义了视图组件和代理存取数据的接口。数据无需存储在数据模型里,数据可以是其他类、文件、数据库或任何数据源。
在这里插入图片描述

QStringListModel 用来保存一列QString项。
QStandardItemModel 管理更复杂是树形数据结构,每一个条目都可以保存任意数据。
QFileSystemModel 提供了本地文件系统的文件和目录信息。
QSqlQueryModel, QSqlTableModel, 和 QSqlRelationalTableModel 通过模型/视图的约定规则来访问数据库。

目前用到的是 QStandardItemModel

添加数据

往表格添加数据:

QStandardItemModel tableModel(4, 4);
    for (int row = 0; row < 4; ++row){
        for (int column = 0; column < 4; ++column) {
            QStandardItem *item = new QStandardItem(QString("%0,%1").arg(row).arg(column));
            tableModel.setItem(row, column, item);
       }
    }
    QTableView tableView;
    tableView.setModel( & tableModel );

添加角色

QStandarItemModel *m_model = new QStandarItemModel ;
 QStandardItem *item = new QStandardItem;
 item->setData(QVariant(getVariantList(info)), Qt::DisplayRole);
 item->setData(QVariant(iconSize()), Qt::SizeHintRole);
 m_model->appendRow(item);

获取角色

QString name=item->data(Qt::SizeHintRole);

其中QStandardItem初始化 QStandardItem(Qstring a) 界面会显示a字符串

获取数据

参考QStandardItemModel的用法

在视图上设置模型之后,通常需要对用户操作做出反应,例如单击项目。由于QAbstractItemView提供基于QModelIndex的信号和函数,您需要一种方法来获得与给定QModelIndex对应的q标准化,反之亦然。itemFromIndex()和indexFromItem()提供了这个映射。itemFromIndex()的典型应用包括获取项目目前的索引视图,并获取项对应于一个索引由QAbstractItemView信号,如QAbstractItemView:点击()。首先在你的类中连接视图的符号

	 QTreeView *treeView = new QTreeView(this);
	 treeView->setModel(myStandardItemModel);
	 connect(treeView, SIGNAL(clicked(QModelIndex)),this, SLOT(clicked(QModelIndex)));
   当您收到信号时,您在给定的模型索引上调用itemFromIndex(),以获得指向该项目的指针:
 void MyWidget::clicked(const QModelIndex &index)
 {
     QStandardItem *item = myStandardItemModel->itemFromIndex(index);
 }
    相反,当您希望调用以索引为参数的模型/视图函数时,您必须获得项目的QModelIndex。您可以通过使用model的indexFromItem()函数来获得索引,也可以通过调用q标准化tem::index()来获得该索引:

treeView->scrollTo(item->index());

返过的错误

m_addedModel.itemFromIndex(m_addedModel.index(i, 0))->data().toString()

当时 m_addedModel.index(i, 0)并没有设置 data,即,

QStandardItem* pItemEx = new QStandardItem(vecIndexs[i]);
		pItemEx->setData(strDatas.at(i));//这一步没有

所以那一行没有获取到数据

视图

视图用于显示模型中的数据

槽函数

QTreeView使用总结5,选中信号处理

Q_SIGNALS:
    void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
    void currentChanged(const QModelIndex &current, const QModelIndex &previous);
    void currentRowChanged(const QModelIndex &current, const QModelIndex &previous);
    void currentColumnChanged(const QModelIndex &current, const QModelIndex &previous);
    void modelChanged(QAbstractItemModel *model);

例子:

//a.h
void SlotModelItemClickedShowBaseInfo(const QModelIndex &current, const QModelIndex &previous);


//a.cpp
connect(ui->treeView->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(SlotModelItemClickedShowBaseInfo(const QModelIndex &, const QModelIndex &)));

void a::SlotModelItemClickedShowBaseInfo(const QModelIndex &current, const QModelIndex &previous) {
	QStandardItem* item = m_model.itemFromIndex(current);
	if (item)
	{
		QString modelName = item->text();
		ui->label->setText(modelName);
	}
}
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值