当前位置: 首页 > news >正文

Qt实战:自定义二级选项框 | 附完整源码

1、目的

实现自定义二级选项框,一级选项有子项就没有选项功能,没有子项就有功能。

2、效果

在这里插入图片描述

3、方法

可以通过QToolButton和QMenu结合来实现这个功能。

4、源码
a、头文件
#ifndef SECONDARYCOMBOBOX_H
#define SECONDARYCOMBOBOX_H#include <QMenu>
#include <QToolButton>
#include <QWidget>struct UserData {QString textStr;QString dataStr;QAction *act = nullptr;
};
Q_DECLARE_METATYPE(UserData)/** 需求:二级选项框,一级选项有子项就没有选项功能,没有子项就有功能;**/
class SecondaryComboBox : public QWidget {Q_OBJECTpublic:explicit SecondaryComboBox(QWidget *parent = 0);~SecondaryComboBox();QString currentData() const;QString currentText() const;void setCurrentData(const QString &data);// 一次加入全部数据void addLists(const QList<QPair<QString, QString>> &firstList,const QList<QList<QPair<QString, QString>>> &secondList);signals:void currentDataChange();private:QToolButton *toolBtn = nullptr;QMenu *toolMenu = nullptr;QList<UserData> userDataList;
};#endif  // SECONDARYCOMBOBOX_H
b、源文件
#include "secondarycombobox.h"#include <QVBoxLayout>const char propertyStr[5] = "data";SecondaryComboBox::SecondaryComboBox(QWidget *parent) : QWidget(parent) {QVBoxLayout *lay = new QVBoxLayout(this);lay->setMargin(0);toolBtn = new QToolButton(this);toolMenu = new QMenu(this);toolBtn->setMinimumSize(100, 30);toolBtn->setPopupMode(QToolButton::MenuButtonPopup);toolBtn->setMenu(toolMenu);lay->addWidget(toolBtn);
}SecondaryComboBox::~SecondaryComboBox() {}QString SecondaryComboBox::currentData() const {QString retStr;QVariant var = toolBtn->property(propertyStr);if (var.canConvert<UserData>()) {UserData uData = var.value<UserData>();retStr = uData.dataStr;}return retStr;
}QString SecondaryComboBox::currentText() const { return toolBtn->text(); }void SecondaryComboBox::setCurrentData(const QString &data) {bool isFind = false;UserData newData;for (int i = 0; i < userDataList.size(); i++) {UserData uData = userDataList.at(i);if (uData.dataStr == data) {isFind = true;newData = uData;break;}}QVariant var = toolBtn->property(propertyStr);if (!isFind) {if (userDataList.size() == 0) return;newData = userDataList.at(0);}if (var.canConvert<UserData>()) {UserData curData = var.value<UserData>();if (curData.dataStr != newData.dataStr) {toolBtn->setText(newData.textStr);QVariant var = QVariant::fromValue(newData);toolBtn->setProperty(propertyStr, var);emit currentDataChange();}} else {toolBtn->setText(newData.textStr);QVariant var = QVariant::fromValue(newData);toolBtn->setProperty(propertyStr, var);emit currentDataChange();}
}void SecondaryComboBox::addLists(const QList<QPair<QString, QString>> &firstList,const QList<QList<QPair<QString, QString>>> &secondList) {if (firstList.size() != secondList.size()) return;QString firstText;UserData firstUseData;bool isFirst = true;for (int i = 0; i < firstList.size(); i++) {const QPair<QString, QString> &pair = firstList.at(i);const QList<QPair<QString, QString>> &list = secondList.at(i);if (list.size() == 0) {QAction *act = new QAction(pair.first, this);UserData uData;uData.textStr = pair.first;uData.dataStr = pair.second;uData.act = act;QVariant var = QVariant::fromValue(uData);act->setProperty(propertyStr, var);userDataList.push_back(uData);toolMenu->addAction(act);if (isFirst) {firstText = pair.first;firstUseData = uData;isFirst = false;}connect(act, &QAction::triggered, [=]() {bool isChange = true;QVariant var = toolBtn->property(propertyStr);if (var.canConvert<UserData>()) {UserData uData = var.value<UserData>();if (uData.act == act) {isChange = false;}}if (isChange) {toolBtn->setText(act->text());toolBtn->setProperty(propertyStr, act->property(propertyStr));emit currentDataChange();}});} else {QMenu *menu = new QMenu(pair.first, this);for (int j = 0; j < list.size(); j++) {QPair<QString, QString> pair = list.at(j);QAction *act = new QAction(pair.first, this);UserData uData;uData.textStr = pair.first;uData.dataStr = pair.second;uData.act = act;QVariant var = QVariant::fromValue(uData);act->setProperty(propertyStr, var);userDataList.push_back(uData);menu->addAction(act);if (isFirst) {firstText = pair.first;firstUseData = uData;isFirst = false;}connect(act, &QAction::triggered, [=]() {bool isChange = true;QVariant var = toolBtn->property(propertyStr);if (var.canConvert<UserData>()) {UserData uData = var.value<UserData>();if (uData.act == act) {isChange = false;}}if (isChange) {toolBtn->setText(act->text());toolBtn->setProperty(propertyStr, act->property(propertyStr));emit currentDataChange();}});}toolMenu->addMenu(menu);}}
}

点击下载完整代码

对你有用就点个赞👍,以后需要用到就收藏⭐

http://www.lqws.cn/news/463087.html

相关文章:

  • 【Linux第四章】gcc、makefile、git、GDB
  • 【日志系统-时间戳】
  • 告别线程爆炸:我如何用 Spring WebFlux 构建一个端到端响应式应用
  • ad24智能pdf输出的装配图没有四个边角那里的圆孔
  • 面试题-ts中的typeof
  • 读者写者问题与读写锁自旋锁
  • OpenAI与微软的未来合作之路:充满挑战的AI竞赛与共赢
  • STM32F103C8T6 学习笔记摘要(二)
  • Knife4j 使用详解
  • (详细介绍)线性代数中的零空间(Null Space)
  • GitHub Copilot快捷键
  • JVM(8)——详解分代收集算法
  • linux生产环境下根据关键字搜索指定日志文件命令
  • Android多进程数据共享:SharedPreferences替代方案详解
  • RocketMQ--为什么性能不如Kafka?
  • 黑马头条-数据管理平台
  • Codeforces Round 1028 (Div. 2) A-C
  • ByteMD Markdown编辑器详细解释修改编辑器默认样式(高度300px)
  • Sublime text启用vim
  • 力扣刷题(第六十四天)
  • 咨询大师——解读96页麦肯锡金字塔原理【附全文阅读】
  • Qt输入数据验证的方法
  • 服务器架构---三高是什么
  • Ruby 范围(Range)
  • 如何用 eBPF 实现 Kubernetes 网络可观测性?实战指南
  • DM8故障分析工具-AWR报告
  • PY32学习(2)-搭建Keil环境
  • 基于SpringBoot+Uniapp的活动中心预约小程序(协同过滤算法、腾讯地图、二维码识别)
  • Linux 内核中 TCP 协议栈的输出实现:tcp_output.c 文件解析
  • 蓝牙数据通讯,实现内网电脑访问外网电脑