PyQt5 QCheckBox多选时表现为单选 无法叠加显示地图区域问题
问题根因
- 你将所有
QCheckBox添加进了sem_label_group这个QButtonGroup实例,QButtonGroup默认开启exclusive(互斥)属性,无论内部添加的是复选框还是单选按钮,同一时间仅允许一个按钮保持选中状态,这是复选框表现出单选互斥特性的核心原因之一。 - 现有交互逻辑每次触发勾选事件时,仅传入单个选中的类别ID给绘制函数,且每次重绘都从空白底图(
highlight_map.copy())开始,仅绘制当前传入的单个类别,没有收集所有已勾选类别做批量绘制,自然无法实现多区域叠加效果。
修复方案
- 先解决按钮组互斥问题,二选一即可:
# 方案1:复选框不需要QButtonGroup做互斥管理,直接删除addButton这行 # sem_label_group.addButton(self.sem_index[i]) # 方案2:如果需要用QButtonGroup批量管理按钮,主动关闭默认互斥属性 sem_label_group.setExclusive(False)
- 修改勾选事件回调,每次触发时收集所有处于选中状态的类别ID,而非仅记录当前点击的单个类别:
def check_clicked(self): # 收集所有当前勾选的语义类别ID selected_sem_ids = set() for checkbox in self.sem_index: if checkbox.isChecked(): class_name = checkbox.text() sem_id = self.floorMap.classes.index(class_name) selected_sem_ids.add(sem_id) obj = self.floorMap.rooms[self.currentRoom].objects[self.currentObjInd] # 将选中的ID集合传入绘制函数 self.drawObjects(selected_sem_ids, obj.id)
- 修改绘制函数逻辑,遍历物体时只要物体类别属于选中集合就执行绘制,实现多类别叠加:
def drawObjects(self, selected_sems, objId=-1): clr = cm.rainbow(np.linspace(0, 1, len(self.floorMap.classes))) self.drawn_map = self.highlight_map.copy() total_class_count = len(self.floorMap.classes) noDrawInd = total_class_count + 1 allDrawInd = total_class_count if noDrawInd not in selected_sems: for roomID, room in enumerate(self.floorMap.rooms): for obj in room.objects: # 匹配规则:物体类别在选中集合内,或开启了全选 if (obj.semLabel in selected_sems) or (allDrawInd in selected_sems): color = 255 * clr[obj.semLabel, :3] x1, y1, x2, y2 = obj.position if (objId == obj.id) and (roomID == self.currentRoom): cv2.rectangle(self.drawn_map, (x1, y1), (x2, y2), color, -1) else: cv2.rectangle(self.drawn_map, (x1, y1), (x2, y2), color, 1) image = QImage( self.drawn_map, self.drawn_map.shape[1], self.drawn_map.shape[0], self.drawn_map.shape[1] * 3, QImage.Format_RGB888, ) self.edit_pix = QPixmap(image) self.main_image.img = self.edit_pix self.main_image.setPixmap(self.edit_pix)
注意:原代码中用于存储单个选中类别的self.semMapID变量可以删除,所有选中状态直接遍历复选框获取即可,避免出现状态不同步问题。
内容的提问来源于stack exchange,提问作者Zayats
相关产品推荐
相关产品推荐

