QT combobox下拉从树中选择节点

简介

接到一个需求,在Combobox的下来框中,显示一颗树,从树节点中选取项目,如下图所示,记录一下
在这里插入图片描述
查看了Qt的官方文档,发现了void QComboBox::setView(QAbstractItemView *itemView)函数,那么事情似乎就变得简单了,直接构造QTreeView(或者QTreeWidget)对象,然后设置到QCombobox中,似乎就大功告成了。
实验一下:

auto model = new TreeModel(this);
QTreeView *tree = new QTreeView(this);
tree->setHeaderHidden(true);
tree->setModel(model);
ui->comboBox->setView(tree);
ui->comboBox->setModel(model);
tree->expandAll();

短短的几行代码就完成了,以此类推,下拉表格,甚至自定义控制是否都能实现,感兴趣的可以尝试一下。

在初始化时需要使得Combox,选中树节点中的某个孩子节点,使用setRootModelIndex(const QModelIndex &index)

auto parantIndex;	//获取到需要设置节点的父亲节点
ui->comboBox->setRootModelIndex(parantIndex);	//将当前根节点设置为刚找到的父亲节点
ui->comboBox->setCurrentIndex(1);				//设置选中第几个孩子
ui->comboBox->setRootModelIndex(root);			//设置完成后将根节点设置为树的根节点

更新

当设置了树为下拉框对象时,发现并不完美,在折叠或展开树的时候,下拉框会自动收起,这非常影响使用,必须的处理。
解决办法也很多,这里提供三种常用的解决方式,如有大佬有更好的解决办法,欢迎指正。
方案一
自定义QComboBox控件,重写其hidePopup()函数,可以在hidePopup()函数中判断当前是否能够隐藏,详情见qt官方文档
方案二
将需要能够折叠的item设置为不可选中状态,当然,这种方式存在局限性,只适用于只能选择叶子节点的情况,同事此种办法也是最简单的实现方式。只需要在创建树节点时设置其不可选中即可

item->setFlags(item->flags() & ~Qt::ItemIsSelectable);

方案三
设置事件过滤器,经过研究发现,下拉框实在鼠标弹起时隐藏,因此,我们只需要在鼠标弹起时判断是在哪个区域即可。

//设置事件过滤器
ui->comboBox->view()->viewport()->installEventFilter(this);
//事件处理函数
bool MainWindow::eventFilter(QObject *watch, QEvent *e)
{
    if(watch == ui->comboBox->view()->viewport() && e->type() == QEvent::MouseButtonRelease)
    {
        //判断点的是否是折叠按钮
        QMouseEvent *_mouse = static_cast<QMouseEvent*>(e);
        if(nullptr == _mouse)
        {
            return false;
        }

        auto _rect = m_tree->visualItemRect(m_tree->currentItem());
        if(!_rect.contains(_mouse->pos()))
        {
            return true;
        }

    }
    return QMainWindow::eventFilter(watch,e);
}

看个效果
在这里插入图片描述
代码还是放在这里了
链接

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值