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

2023-11-08

效果:

废话不多说,上代码

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。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT QComboBox+QTreeView 实现二级或多级菜单并带滚轮 的相关文章

  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • Qt 支持 Windows 蓝牙 API 吗?

    谁能告诉我 Qt 是否支持 Windows 蓝牙 API 如果是这样 您能否分享一些有关如何使用它的信息 自上次答复以来 这个问题的答案发生了一些变化 Qt 5 2 版为 Linux BlueZ 和 BlackBerry 设备实现了蓝牙 A
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li

随机推荐

  • 每日半小时分割

    JS每日半小时分割 结果 如何插入一段漂亮的代码片 结果 如何插入一段漂亮的代码片 去博客设置页面 选择一款你喜欢的代码片高亮样式 下面展示同样高亮的 代码片 An highlighted block function getHalfHou
  • docker容器详解

    Docker容器运行的本质是运行一个进程 该进程在其自己的隔离环境中运行 该环境由Linux内核的特性 如cgroups和namespaces 提供 Docker 容器存在的意义就是为了运行容器中的应用 对外提供服务 所以启动容器的目的就是
  • Topsis算法实践:比较LSTM算法与BP神经网络算法,以chickenpox_dataset为例

    目录 Topsis简介 模型分类与转化 极小转化为极大型 中间最优型转极大值 区间最优 a b 转极大型 计算得分并归一化 LSTM算法预测 数据加载处理 定义和训练LSTM网络 预测并返回误差 BP神经网络预测 数据处理 构建BP神经网络
  • AI制作ICON流程

    AI制作ICON流程 作者 欧日鑫 撰写时间 2019年4月18日 第一个 首先我给大家制作的第一款ICON就是地图ICON 开始我们用圆角矩形工具绘制一个形状 大小跟我效果图一样大就行添加颜色为84b388还有一个半径为10像素 然后我们
  • C# + Socket断线重连 整理

    Socket 连接异常之 由于目标机器积极拒绝 无法连接 System Net Sockets SocketException Connection refused 1 如果是采用TCP udp协议进行连接 检查windows防火墙是否开放
  • MyEclipse反编译Class文件的实现

    对于需要查看Java Class文件源码的筒子们来说 必须在项目中导入Java源码才能查看Class文件的具体实现 这不仅十分的麻烦 因为有时我们并不可以获得Class文件对应的Java源码 今天就给大家介绍一款反编译Class文件的工具
  • python返回值和while循环_Python -While循环递归

    怎么样 def fibonacci n a 0 b 1 if a gt n return a return a fibonacci n b a b 编辑 以下是它的工作原理 该函数通过向下一次调用自身的结果添加一个元素 a 来逐步构建数组
  • 土地基础知识

    土地产权 土地根据所有权分为国有土地和集体土地 国有土地 由国家享有所有权的土地 在我国 国有土地包括城市市区的土地 以及法律规定属于国家所有的农村和城市郊区的土地 集体土地 由农民集体享有所有权的土地 农村和城市郊区的土地 除由法律规定属
  • 【二维码图像矫正增强】基于MATLAB的二维码图像矫正增强处理仿真

    1 软件版本 matlab2013b 2 算法流程概述 通过形态学处理获得二维码部分的图像区域及边界 采用凸包算法来计算边界上的点集 然后根据点集来寻找二维码的四个顶点 然后透视变换矫正 二维码分割得到每个格子中的点 进行二维码图像归一化
  • python爬虫之post请求

    import requests import json import openpyxl url1 https a300010770 casmart com cn shop products headers content type appl
  • 解决macOS中安装应用后提示:无法打开“XXX”,因为无法验证开发者的问题

    如果在网上下载dmg安装包 并安装成功 打开应用时 提示 无法打开 XXX 因为无法验证开发者 解决方法如下 1 点击屏幕左上角的苹果图标 选择菜单 系统偏好设置 2 打开系统偏好设置界面 点击 安全性与隐私 gt 通用 3 在窗口底部会看
  • Android拍摄并进行图像识别(一)

    目录 一 简介 二 程序流程图 三 核心代码解析 1 主界面跳转到拍照界面 2 实现无触摸自动拍照 1 拍照功能 2 预览功能 3 保存照片并返回主界面 四 总结 一 简介 最近在学习实现Android的拍照AI识别功能 主要通过调用手机系
  • TCP/IP协议(分片与分段)的介绍

    TCP IP协议 分片与分段 在传输层TCP分段 在网络层分片 如果只有分片 数据处理时 在传输层tcp分片 数据加个报文头部 然后在网络层ip分片 如果数据遗失 需要传输层重传整个报文 太占资源 所以直接在传输层一步到位 采用分段的方法
  • 千年服务器武功修改,千年私服如何添加武功

    做了GM之后会加装备删装备了 可是武功怎么弄一直摸不着头脑 在几个高手指点下 本人也完成了一次武功的添加 在此献上心德一篇 在1000yServer tgs1000 Init Magic文件里 将自己相印的1层和2层武工名字改了就可以了 雷
  • torch.mul()函数的使用

    参考链接 mul value Tensor 参考链接 torch mul 使用说明 对两个张量进行逐元素乘法 Microsoft Windows 版本 10 0 18363 1256 c 2019 Microsoft Corporation
  • HCIP——网络类型实验

    1 实验要求 1 R2为ISP 其中只能配置IP地址 2 R1 R2之间为HDLC封装 3 R2 R3之间为ppp封装 pap认证 R2为主认证方 4 R2 R4之间为ppp封装 chap认证 R2为主认证方 5 R1 R2 R3构建MGR
  • 一个机器人位于一个 m x n 网格的左上角 。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。问总共有多少条不同的路径?【LeetCodeHot100】

    力扣热题100之62 先贴代码 class Solution public int uniquePaths int m int n 创建棋盘 int board new int m n 将第0列的格子路径设为1 for int i 0 i
  • webpack5基本教程-2

    自动清空上次打包的内容 配置如下 处理其他资源 处理js资源 原因 Webpack 对 js 处理是有限的 只能编译 js 中 ES 模块化语法 不能编译其他语法 导致 js 不能在 IE 等浏览器运行 所以我们希望做一些兼容性处理 其次开
  • JetBrain软件不同版本下载

    通过URL进行老版本下载 针对所有JetBrain产品 包括Pycharm IDEA Clion等 这里以Pycharm为例 windows系统下载 https download jetbrains com cn python pychar
  • QT QComboBox+QTreeView 实现二级或多级菜单并带滚轮

    效果 废话不多说 上代码 ComboBox h pragma once include