使 QComboBox 下拉一个树形结构列表

背景

在项目开发过程中需要使 QComboBox 下拉一个树形列表,直接通过 setModel 和 setView 设置 combox 控件可以实现,但是在单击节点箭头按钮时也会隐藏下拉框的显示。因此需要重新实现 QComboBox 的方法来实现自己控制。

①.通过 QTreeComboBoxView子类化 QTreeWidget 类,以重写 mousePressEvent 事件自己实现节点的展开和收缩,否则会有事件冲突。

②.通过 QTreeListComboBox 子类化 QComboBox 类,以重写 hidePopup 方法,判断条件是否满足。

QTreeComboBoxView

class QTreeComboBoxView : public QTreeWidget
{
  Q_OBJECT
public:
  QTreeComboBoxView(QWidget *parent = Q_NULLPTR) :QTreeWidget(parent) {}
  ~QTreeComboBoxView() {};
protected:
  void mousePressEvent(QMouseEvent *event) override;
signals:
  void treeMousePressed(bool inItem);
};

void QTreeComboBoxView::mousePressEvent(QMouseEvent *event)
{
  auto curIndex = currentIndex();
  auto rect = this->visualRect(curIndex);
  auto buttonRect = QRect(rect.left() - 20, rect.top(), 20, rect.height());
  if (buttonRect.contains(event->pos()))
  {
    if (isExpanded(curIndex)) setExpanded(curIndex, false);
    else setExpanded(curIndex, true);
    emit treeMousePressed( true );
  }
  else
    emit treeMousePressed(false);
}

QTreeListComboBox

class QTreeListComboBox : public QComboBox
{
  Q_OBJECT  
public:
  QTreeListComboBox( QWidget *parent = Q_NULLPTR);
  ~QTreeListComboBox() {};
protected:
  void hidePopup() override;
private:
  bool canHidePopup = true;//允许收缩
public:
  QTreeComboBoxView * displayTreeWidget = nullptr;
private:
  Ui::QTreeListComboBox ui;
};

QTreeListComboBox::QTreeListComboBox( QWidget *parent)
  : QComboBox(parent)
{
  ui.setupUi(this);

  displayTreeWidget = new QTreeComboBoxView(this);
  displayTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  displayTreeWidget->setHeaderHidden(true);

  this->setModel(displayTreeWidget->model());
  this->setView(displayTreeWidget);

  connect(displayTreeWidget, &QTreeComboBoxView::treeMousePressed, [&](bool inItem) {
    canHidePopup = !inItem;
  });

  connect(this, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated), this, [&](int index) {
    hidePopup();
  });
}

void QTreeListComboBox::hidePopup()
{
  if (canHidePopup) QComboBox::hidePopup();    
}

设置分组节点禁止选择

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

代码示例

auto tree = ui.comboBox->displayTreeWidget;

 for (int i = 1;i < 4;i++ )
 {
    QTreeWidgetItem* item = new QTreeWidgetItem(tree, { QString::number(i) });
    item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
    for (int j = 1; j < 5; j++)
    {
      QTreeWidgetItem* sub = new QTreeWidgetItem(item, { QString("%1.%2").arg(i).arg(j) });
    }  
 }

在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值