如何为QComboBox控件添加子菜单?
为QComboBox添加子菜单的两种实现方法
方法一:用自定义QMenu替换默认下拉列表
这种方式直接用QMenu搭建带层级的菜单结构,替换QComboBox默认的冗长下拉列表,适合需要子菜单、快捷键或图标的复杂场景。
from PyQt5.QtWidgets import (QApplication, QComboBox, QMenu, QAction) import sys app = QApplication(sys.argv) combo = QComboBox() # 构建主菜单和子菜单 main_menu = QMenu() # 添加「文件」顶级菜单及子项 file_menu = main_menu.addMenu("文件") file_menu.addAction("新建") file_menu.addAction("打开") # 添加「编辑」顶级菜单,再嵌套「格式」子菜单 edit_menu = main_menu.addMenu("编辑") format_submenu = edit_menu.addMenu("格式") format_submenu.addAction("加粗") format_submenu.addAction("斜体") # 把自定义菜单设为QComboBox的下拉弹出组件 combo.setMenu(main_menu) # 绑定点击事件:选中菜单项时更新QComboBox的显示文本 def update_combo_text(action): combo.setCurrentText(action.text()) # 遍历所有菜单项,绑定触发事件 for action in main_menu.actions(): if action.menu(): for sub_action in action.menu().actions(): if sub_action.menu(): for sub_sub_action in sub_action.menu().actions(): sub_sub_action.triggered.connect(lambda _, a=sub_sub_action: update_combo_text(a)) else: sub_action.triggered.connect(lambda _, a=sub_action: update_combo_text(a)) else: action.triggered.connect(lambda _, a=action: update_combo_text(a)) combo.show() sys.exit(app.exec_())
方法二:用树形模型+视图实现层级下拉
这种方式靠Qt的模型-视图架构,把QComboBox的下拉视图换成树形视图,用模型构建层级数据,适合结构化数据展示的场景。
from PyQt5.QtWidgets import (QApplication, QComboBox, QTreeView) from PyQt5.QtGui import QStandardItemModel, QStandardItem import sys app = QApplication(sys.argv) combo = QComboBox() # 创建树形数据模型 model = QStandardItemModel() # 构建「文件」分支 file_item = QStandardItem("文件") file_item.appendRow(QStandardItem("新建")) file_item.appendRow(QStandardItem("打开")) model.appendRow(file_item) # 构建「编辑」->「格式」分支 edit_item = QStandardItem("编辑") format_item = QStandardItem("格式") format_item.appendRow(QStandardItem("加粗")) format_item.appendRow(QStandardItem("斜体")) edit_item.appendRow(format_item) model.appendRow(edit_item) # 把树形视图设为QComboBox的下拉视图 tree_view = QTreeView() tree_view.setModel(model) tree_view.setRootIsDecorated(True) # 显示展开/折叠的小箭头 tree_view.setHeaderHidden(True) # 隐藏表头 combo.setView(tree_view) # 可选:调整下拉列表的最小宽度 combo.view().setMinimumWidth(200) # 选中项时,把完整层级路径设为显示文本 def on_item_selected(index): path = [] current_item = model.itemFromIndex(index) # 往上遍历父项,拼凑完整路径 while current_item: path.append(current_item.text()) current_item = current_item.parent() path.reverse() combo.setCurrentText(" > ".join(path)) combo.currentIndexChanged.connect(on_item_selected) combo.show() sys.exit(app.exec_())
内容的提问来源于stack exchange,提问作者Suresh Kumar
相关产品推荐
相关产品推荐

