使用QComboBox切换工具栏中显示的不同控件集合
实现下拉框联动切换测量控件集的图像查看器
看起来你已经搭好了图像查看器的基础框架,现在需要实现两个下拉框的联动,让工具栏只显示选中测量集里的对应控件,同时保持工具栏紧凑。我来帮你完善这个功能~
先提下现有代码里的小问题:
combo_box1重复添加了两次"measurements set 1",应该把其中一个改成"measurements set 2"- 缺少
P3-P4、P5-P6、P7-P8对应的控件和布局 - 没有实现下拉框选中后的联动逻辑,切换测量集时下拉框选项和控件显示不会变化
核心实现思路
- 用字典映射每个测量集对应的测量项,方便后续扩展新的测量集
- 预先创建所有测量项的控件和布局,初始状态设为隐藏(节省空间)
- 给两个下拉框绑定信号槽,实现联动:
- 切换
combo_box1时,自动更新combo_box2的选项列表 - 切换
combo_box2时,显示对应测量项的控件,隐藏其他无关控件
- 切换
修改后的完整代码
from PySide2.QtWidgets import (QWidget, QApplication, QGraphicsView, QGridLayout, QCheckBox, QLineEdit, QComboBox, QVBoxLayout, QHBoxLayout) from PySide2.QtCore import Qt, Signal, QPoint from PySide2.QtGui import QPixmap, QCursor image_path_str='image.jpg' class View(QGraphicsView): photo_clicked = Signal(QPoint) def __init__(self, parent): super(View, self).__init__(parent) self.scene = QtWidgets.QGraphicsScene(self) self.photo = QtWidgets.QGraphicsPixmapItem() self.scene.addItem(self.photo) self.pixmap = QPixmap(image_path_str) self.photo.setPixmap(self.pixmap) self.setScene(self.scene) self.setDragMode(QGraphicsView.ScrollHandDrag) class Window(QWidget): def __init__(self): super(Window, self).__init__() self.view = View(self) # ---------------------- 创建所有测量项的控件和布局 ---------------------- # P1-P2 布局 self.layout_P1P2 = QGridLayout() # P1 控件 self.checkbox_P1 = QCheckBox("P1", self) self.line_edit_P1_x = QLineEdit(self) self.line_edit_P1_x.setReadOnly(True) self.line_edit_P1_y = QLineEdit(self) self.line_edit_P1_y.setReadOnly(True) # P1 子布局 grid_P1 = QGridLayout() grid_P1.addWidget(self.line_edit_P1_x, 0, 0) grid_P1.addWidget(self.line_edit_P1_y, 1, 0) self.layout_P1P2.addWidget(self.checkbox_P1, 0, 0, Qt.AlignLeft) self.layout_P1P2.addLayout(grid_P1, 0, 1) # P2 控件 self.checkbox_P2 = QCheckBox("P2", self) self.line_edit_P2_x = QLineEdit(self) self.line_edit_P2_x.setReadOnly(True) self.line_edit_P2_y = QLineEdit(self) self.line_edit_P2_y.setReadOnly(True) # P2 子布局 grid_P2 = QGridLayout() grid_P2.addWidget(self.line_edit_P2_x, 0, 0) grid_P2.addWidget(self.line_edit_P2_y, 1, 0) self.layout_P1P2.addWidget(self.checkbox_P2, 1, 0, Qt.AlignLeft) self.layout_P1P2.addLayout(grid_P2, 1, 1) self.layout_P1P2.setContentsMargins(0,0,0,0) self.layout_P1P2.setVisible(False) # 初始隐藏 # P3-P4 布局 self.layout_P3P4 = QGridLayout() self.checkbox_P3 = QCheckBox("P3", self) self.line_edit_P3_x = QLineEdit(self) self.line_edit_P3_x.setReadOnly(True) self.line_edit_P3_y = QLineEdit(self) self.line_edit_P3_y.setReadOnly(True) grid_P3 = QGridLayout() grid_P3.addWidget(self.line_edit_P3_x, 0, 0) grid_P3.addWidget(self.line_edit_P3_y, 1, 0) self.layout_P3P4.addWidget(self.checkbox_P3, 0, 0, Qt.AlignLeft) self.layout_P3P4.addLayout(grid_P3, 0, 1) self.checkbox_P4 = QCheckBox("P4", self) self.line_edit_P4_x = QLineEdit(self) self.line_edit_P4_x.setReadOnly(True) self.line_edit_P4_y = QLineEdit(self) self.line_edit_P4_y.setReadOnly(True) grid_P4 = QGridLayout() grid_P4.addWidget(self.line_edit_P4_x, 0, 0) grid_P4.addWidget(self.line_edit_P4_y, 1, 0) self.layout_P3P4.addWidget(self.checkbox_P4, 1, 0, Qt.AlignLeft) self.layout_P3P4.addLayout(grid_P4, 1, 1) self.layout_P3P4.setContentsMargins(0,0,0,0) self.layout_P3P4.setVisible(False) # P5-P6 布局 self.layout_P5P6 = QGridLayout() self.checkbox_P5 = QCheckBox("P5", self) self.line_edit_P5_x = QLineEdit(self) self.line_edit_P5_x.setReadOnly(True) self.line_edit_P5_y = QLineEdit(self) self.line_edit_P5_y.setReadOnly(True) grid_P5 = QGridLayout() grid_P5.addWidget(self.line_edit_P5_x, 0, 0) grid_P5.addWidget(self.line_edit_P5_y, 1, 0) self.layout_P5P6.addWidget(self.checkbox_P5, 0, 0, Qt.AlignLeft) self.layout_P5P6.addLayout(grid_P5, 0, 1) self.checkbox_P6 = QCheckBox("P6", self) self.line_edit_P6_x = QLineEdit(self) self.line_edit_P6_x.setReadOnly(True) self.line_edit_P6_y = QLineEdit(self) self.line_edit_P6_y.setReadOnly(True) grid_P6 = QGridLayout() grid_P6.addWidget(self.line_edit_P6_x, 0, 0) grid_P6.addWidget(self.line_edit_P6_y, 1, 0) self.layout_P5P6.addWidget(self.checkbox_P6, 1, 0, Qt.AlignLeft) self.layout_P5P6.addLayout(grid_P6, 1, 1) self.layout_P5P6.setContentsMargins(0,0,0,0) self.layout_P5P6.setVisible(False) # P7-P8 布局 self.layout_P7P8 = QGridLayout() self.checkbox_P7 = QCheckBox("P7", self) self.line_edit_P7_x = QLineEdit(self) self.line_edit_P7_x.setReadOnly(True) self.line_edit_P7_y = QLineEdit(self) self.line_edit_P7_y.setReadOnly(True) grid_P7 = QGridLayout() grid_P7.addWidget(self.line_edit_P7_x, 0, 0) grid_P7.addWidget(self.line_edit_P7_y, 1, 0) self.layout_P7P8.addWidget(self.checkbox_P7, 0, 0, Qt.AlignLeft) self.layout_P7P8.addLayout(grid_P7, 0, 1) self.checkbox_P8 = QCheckBox("P8", self) self.line_edit_P8_x = QLineEdit(self) self.line_edit_P8_x.setReadOnly(True) self.line_edit_P8_y = QLineEdit(self) self.line_edit_P8_y.setReadOnly(True) grid_P8 = QGridLayout() grid_P8.addWidget(self.line_edit_P8_x, 0, 0) grid_P8.addWidget(self.line_edit_P8_y, 1, 0) self.layout_P7P8.addWidget(self.checkbox_P8, 1, 0, Qt.AlignLeft) self.layout_P7P8.addLayout(grid_P8, 1, 1) self.layout_P7P8.setContentsMargins(0,0,0,0) self.layout_P7P8.setVisible(False) # ---------------------- 下拉框设置 ---------------------- self.combo_box1 = QComboBox(self) self.combo_box1.addItem("measurements set 1") self.combo_box1.addItem("measurements set 2") # 修复重复添加的问题 self.combo_box2 = QComboBox(self) # 测量集映射字典:key是集合名称,value是对应的测量项和布局 self.measurement_sets = { "measurements set 1": [("P1-P2", self.layout_P1P2), ("P3-P4", self.layout_P3P4)], "measurements set 2": [("P5-P6", self.layout_P5P6), ("P7-P8", self.layout_P7P8)] } # 绑定信号槽 self.combo_box1.currentTextChanged.connect(self.update_combo_box2) self.combo_box2.currentTextChanged.connect(self.show_selected_measurement) # 初始化第一个下拉框的选项 self.update_combo_box2(self.combo_box1.currentText()) # ---------------------- 整体布局 ---------------------- self.vertical1 = QVBoxLayout() self.vertical1.addWidget(self.combo_box1) self.vertical1.addWidget(self.combo_box2) # 添加所有测量布局到工具栏 self.vertical1.addLayout(self.layout_P1P2) self.vertical1.addLayout(self.layout_P3P4) self.vertical1.addLayout(self.layout_P5P6) self.vertical1.addLayout(self.layout_P7P8) self.vertical1.setSpacing(10) # 调整控件间距,保持紧凑 self.vertical2 = QVBoxLayout() self.vertical2.addWidget(self.view) self.horizontal = QHBoxLayout() self.horizontal.addLayout(self.vertical1) self.horizontal.addLayout(self.vertical2) self.horizontal.setStretch(0, 1) # 工具栏占1份宽度 self.horizontal.setStretch(1, 5) # 图像区域占5份宽度,保证大部分空间给图片 self.setLayout(self.horizontal) self.setWindowTitle("Image viewer") self.setGeometry(200, 200, 1000, 800) def update_combo_box2(self, selected_set): """切换第一个下拉框时,更新第二个下拉框的选项""" self.combo_box2.clear() # 获取当前测量集对应的所有测量项 for item_name, _ in self.measurement_sets[selected_set]: self.combo_box2.addItem(item_name) def show_selected_measurement(self, selected_item): """切换第二个下拉框时,显示对应测量控件,隐藏其他""" # 先隐藏所有测量布局 for set_items in self.measurement_sets.values(): for _, layout in set_items: layout.setVisible(False) # 找到选中的测量项对应的布局并显示 for set_items in self.measurement_sets.values(): for item_name, layout in set_items: if item_name == selected_item: layout.setVisible(True) break if __name__ == "__main__": app = QApplication.instance() or QApplication([]) w = Window() w.show() w.raise_() QApplication.setOverrideCursor(QCursor(Qt.CrossCursor)) app.exec_()
关键部分说明
- 测量集映射字典:
self.measurement_sets把每个测量集和对应的测量项、布局绑定在一起,后续要加新的测量集,直接在字典里新增条目就行,不用改太多代码。 - 控件隐藏逻辑:所有测量布局初始都设为
setVisible(False),只有选中时才显示,这样工具栏平时保持紧凑。 - 下拉框联动:通过
currentTextChanged信号触发槽函数,更新选项或切换控件显示,逻辑清晰。 - 布局比例调整:用
setStretch给图像区域分配更多宽度,确保大部分显示空间用于图片展示。
内容的提问来源于stack exchange,提问作者ecjb
相关产品推荐
相关产品推荐

