QT QComboBox+QTreeView 实现二级或多级菜单并带滚轮

效果:

废话不多说,上代码

ComboBox.h

#pragma once
#include <QObject>
#include <QWidget>
#include <QComboBox>
#include <QListWidget>
#include <QMessageBox>
#include <QTreeView>
#include <QStandardItem>
#include <QMouseEvent>
#include "TreeView.h"
#include "ComboBox.h"

class ComboBox : public QComboBox
{
	Q_OBJECT
public:
	ComboBox(QWidget *parent = 0);
	~ComboBox();

public:
	void hidePopup();
	void showPopup();
    TreeView *m_pTreeView;

signals:

	private slots :
		void SetEditModel(bool _editModel);
	    void SetCurrentToolTip(const QString &tooltip);
private:

	bool _editMode = true;
};

 ComboBox.cpp

#include "ComboBox.h"

ComboBox::ComboBox(QWidget *parent)
	: QComboBox(parent)
{
    m_pTreeView = new TreeView(this);
    connect(m_pTreeView, SIGNAL(SignalClickExpandOrCollape(bool)), this, SLOT(SetEditModel(bool)));
    connect(this, SIGNAL(currentTextChanged(QString)), this, SLOT(SetCurrentToolTip(QString)));

    m_pTreeView->setHeaderHidden(true);
    m_pTreeView->header();
    m_pTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers); // 不可选项编辑



    this->setView(m_pTreeView);
    //设置宽度数值小加上数据多的情况下会出现滚动条
    this->view()->setFixedHeight(100);
}

ComboBox::~ComboBox()
{

}

// 解决垂直滚动条出现,多次popup时item错乱的问题  (重要)
void ComboBox::hidePopup()
{
	if (!_editMode)
	{
        m_pTreeView->setLastIndex();
        m_pTreeView->scrollToTop();
		QComboBox::hidePopup();
	}
	_editMode = false;
}

void ComboBox::showPopup()
{
    QComboBox::showPopup();
    m_pTreeView->scrollToTop();
}


void ComboBox::SetEditModel(bool _editModel)
{
    this->_editMode = _editModel;
}

void ComboBox::SetCurrentToolTip(const QString &tooltip)
{
	this->setToolTip(tooltip);
}

TreeView.h

#pragma once
#include <QObject>
#include <QTreeView>
#include <QMouseEvent>

class TreeView : public QTreeView
{
	Q_OBJECT

public:
	TreeView(QWidget *parent = 0);
	~TreeView();

	void setLastIndex();
	void initLastIndex();
signals:
	void SignalClickExpandOrCollape(bool _editModel);

protected:
	void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

private:
	QModelIndex m_lastPressIndex;
};

TreeView.cpp

#include "TreeView.h"
#include <QStandardItem>
#include <QHeaderView>
#include <QDebug>
TreeView::TreeView(QWidget *parent)
	: QTreeView(parent)
{
}

TreeView::~TreeView()
{
}

void TreeView::mousePressEvent(QMouseEvent *event)
{
    qDebug()<<"clicked";
	int isExpandError = -1;
	QModelIndex index;
	if (event->button() == Qt::LeftButton)          //是否左键按下
	{
		index = indexAt(event->pos());  //取出按下点的元素索引index
		if (index.isValid())                   //判断index是否有效
		{
			//你的处理
			QRect rect = visualRect(index);
			QRect expandOrCollape = QRect(rect.left() - 20, rect.top(), 20, rect.height());

			if (isExpanded(index)){
				isExpandError = 1;
			}
			else{
				isExpandError = 0;
			}
			//判断是否点击的是三角形
			if (expandOrCollape.contains(event->pos()))
				emit SignalClickExpandOrCollape(true);
			else{
				emit SignalClickExpandOrCollape(false);
				isExpandError = -1;
			}
            m_lastPressIndex = index;
		}

	}
    QTreeView::mousePressEvent(event);
	if (isExpandError != -1){
		if (isExpanded(index) && isExpandError == 1){
			setExpanded(index, false);
		}
		else if (!isExpanded(index) && isExpandError == 0){
			setExpanded(index, true);
		}
	}
}

void TreeView::setLastIndex()
{
	setCurrentIndex(m_lastPressIndex);
}

void TreeView::initLastIndex()
{
	m_lastPressIndex = QModelIndex();
}

实现方式创建个widget把这个box塞进去

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    box=new ComboBox(this);
    QStandardItemModel *model = new QStandardItemModel();

    QStandardItem *item1 = new QStandardItem("四年级");

    model->setItem(0,0,item1);

    QStandardItem *item00 = new QStandardItem("张三");
    QStandardItem *item10 = new QStandardItem("张四");
    QStandardItem *item20 = new QStandardItem("张五");
    
    model->item(0,0)->setChild(0,0,item00);
    model->item(0,0)->setChild(1,0,item10);
    model->item(0,0)->setChild(2,0,item20);

    QStandardItem *item2 = new QStandardItem("五年级");

    model->setItem(1,0,item2);

    QStandardItem *item200 = new QStandardItem("李三");
    QStandardItem *item210 = new QStandardItem("李四");
    QStandardItem *item220 = new QStandardItem("李五");

    model->item(1,0)->setChild(0,0,item200);
    model->item(1,0)->setChild(1,0,item210);
    model->item(1,0)->setChild(2,0,item220);

    box->setModel(model);
    box->m_pTreeView->initLastIndex();
    box->setGeometry(0,0,200,80);
}

疑点:

创建的QStandardItem为什么吗不给treeviee而是给combobox?

按我的理解就是QT的控件时基于MVC架构的item相当于模型,treeview相当于视图层,而我们操作控件相当于控制层。他们是一个整体,这里相当于是给combobox这个控件设置了一个treeview的视图,而元素是属于box的,所以model应该给box。

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Qt中的QComboBox是一个下拉列表框控件,可以用于选择单个项。它提供了一组方法和信号槽来管理下拉框中的项,可以方便地添加、删除和修改选项。 QTableView是一个表格视图控件,可以用于显示二维数据。它通过提供模型-视图的机制,将数据与表格视图分离,使得数据的管理和展示更加灵活。QTableView可以显示不同的模型,并提供了编辑、排序和过滤等功能。 在使用QComboBoxQTableView时,可以结合使用两者来实现一些复杂的功能。例如,可以将QComboBox用作QTableView的筛选条件选择器。利用QComboBox的信号槽机制,在选择不同的筛选条件时,响应的更新QTableView的内容,从而实现数据的动态过滤显示。 另外,还可以使用QComboBox来选择QTableView中的编辑项。用户可以通过下拉框选择要编辑的行或列,然后通过QTableView提供的函数来修改表格中的数据。这样,用户可以方便地对表格的特定内容进行编辑和管理。 总之,QtQComboBoxQTableView是两个非常有用的控件,可以分别用于选择和展示数据。通过巧妙地结合使用,可以实现一些复杂的功能,提高用户体验和开发效率。 ### 回答2: Qt是一款流行的跨平台的C++开发框架,提供了丰富的图形用户界面(GUI)工具。QComboBoxQt中的一个组件,它是一个下拉列表框,允许用户选择一个或多个选项。QTableView是Qt中的另一个组件,它是一个表格视图,用于显示二维数据。 QComboBoxQTableView可以很好地结合使用,以提供更丰富和交互性的用户界面。例如,可以将QComboBox用作QTableView的过滤器,允许用户选择不同的选项来过滤和显示特定的数据。 要在QComboBox中显示选项,可以使用addItem()方法添加选项,也可以使用setModel()方法设置数据模型。在QTableView中显示数据,通常需要使用QStandardItemModel或QAbstractTableModel作为数据模型,并使用setModel()方法将其设置给QTableView。 在QComboBox中选择选项后,可以通过信号和槽机制来响应选择的变化,并更新QTableView中显示的数据。例如,可以在QComboBox的currentIndexChanged()信号的槽函数中,根据选择的选项更新QTableView的数据模型,然后通过重新设置数据模型更新QTableView的显示。 除了基本功能外,还可以通过自定义QComboBoxQTableView的样式和控件来实现更丰富的用户界面。还可以使用QComboBox的其他方法,如currentIndex()获取当前选择的索引,currentText()获取当前选择的文本等。 总而言之,QtQComboBoxQTableView组件为开发者提供了一种方便和灵活的方式来处理下拉列表和表格数据,使用户界面更加友好和交互性。 ### 回答3: Qt是一种跨平台的C++应用程序开发框架,提供了丰富的UI控件和功能模块,其中包括QComboBoxQTableView。 QComboBox是用来显示和选择多个选项中的一个的下拉列表控件。它的特点是可以添加多个选项,用户可以通过下拉列表来选择不同的选项。QComboBox可以实现单选和多选功能,还可以通过信号和槽机制来响应用户的选择动作。 QTableView是用来显示二维表格数据的控件。它以表格的形式将数据呈现给用户,用户可以通过鼠标或键盘来对表格进行操作,例如选择单元格、编辑单元格内容、排序、过滤等。QTableView还支持数据模型和视图的分离,可以通过自定义的数据模型来呈现不同的数据类型。 在使用Qt中的QComboBoxQTableView时,可以通过不同的方法来设置和获取它们的属性,例如设置选项列表、设置显示文本、设置当前选项、设置表格数据、设置表头等。还可以通过信号和槽机制来处理用户的交互操作,例如响应选项选择事件、响应表格数据变化事件等。 QComboBoxQTableView都可以通过样式表来进行界面的美化,并且可以通过自定义子类来扩展其功能。同时,Qt提供了丰富的文档和示例代码,方便开发者学习和使用这些控件。 总之,Qt中的QComboBoxQTableView是常用的UI控件,可以方便地实现下拉列表和表格数据的展示和交互操作。通过灵活的属性设置和信号槽机制,能够满足不同的使用需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值