[bugfix] 修复card显示异常问题

This commit is contained in:
Sam 2025-02-23 21:35:34 +08:00
parent 6b0aeed713
commit f3465fc623
2 changed files with 108 additions and 60 deletions

View File

@ -296,50 +296,46 @@ class CardItemDelegate(QStyledItemDelegate):
self.edit_mode = False
self.edit_rect = QRect()
self.editing_param_index = -1
self.selected_param_index = -1 # 添加选中参数的索引跟踪
self.selected_param_index = -1
self.editing_field = None # 添加字段标识:'name', 'description' 或 None
def editorEvent(self, event, model, option, index):
data = index.data(Qt.ItemDataRole.UserRole)
if not data or not data.params:
if not data:
return False
params_rect = self.getParamsRect(option.rect)
pos = event.pos()
# 计算参数项的位置
param_height = 24
spacing = 4
indent = 20
# 检查是否点击在标题或描述区域
title_rect = self.getTitleRect(option.rect)
desc_rect = self.getDescriptionRect(option.rect)
if event.type() == QEvent.MouseButtonDblClick:
if title_rect.contains(pos):
self.editing_field = 'name'
self.edit_rect = title_rect
self.parent().edit(index)
return True
elif desc_rect.contains(pos):
self.editing_field = 'description'
self.edit_rect = desc_rect
self.parent().edit(index)
return True
# 检查是否点击在参数区域内
for i, param in enumerate(data.params):
param_rect = QRect(
params_rect.left() + indent,
params_rect.top() + i * (param_height + spacing),
params_rect.width() - indent,
param_height
)
# 创建实际的点击检测区域(考虑滚动位置)
actual_rect = QRect(
param_rect.left(),
param_rect.top(),
param_rect.width(),
param_rect.height()
)
if actual_rect.contains(pos):
if event.type() == QEvent.MouseButtonPress:
# 单击选中
self.selected_param_index = i
self.parent().viewport().update()
return True
elif event.type() == QEvent.MouseButtonDblClick:
# 双击编辑
self.editing_param_index = i
self.edit_rect = actual_rect
self.parent().edit(index)
return True
params_rect = self.getParamsRect(option.rect)
if params_rect.contains(pos):
if event.type() == QEvent.MouseButtonPress:
# 单击选中
self.selected_param_index = self.getParamIndex(pos, params_rect)
self.parent().viewport().update()
return True
elif event.type() == QEvent.MouseButtonDblClick:
# 双击编辑
self.editing_param_index = self.getParamIndex(pos, params_rect)
self.edit_rect = self.getParamRect(self.selected_param_index, params_rect)
self.parent().edit(index)
return True
# 点击空白区域取消选中
if event.type() == QEvent.MouseButtonPress and self.selected_param_index != -1:
@ -353,23 +349,30 @@ class CardItemDelegate(QStyledItemDelegate):
if not data:
return None
if self.editing_param_index >= 0 and self.editing_param_index < len(data.params):
editor = QLineEdit(parent)
editor = QLineEdit(parent)
editor.setStyleSheet("""
QLineEdit {
background-color: #2C2C2C;
color: white;
border: 1px solid #346792;
border-radius: 4px;
padding: 2px;
}
""")
if self.editing_field == 'name':
editor.setText(data.name)
elif self.editing_field == 'description':
editor.setText(data.description)
elif self.editing_param_index >= 0 and self.editing_param_index < len(data.params):
editor.setText(data.params[self.editing_param_index].name)
editor.setStyleSheet("""
QLineEdit {
background-color: #2C2C2C;
color: white;
border: 1px solid #346792;
border-radius: 4px;
padding: 2px;
}
""")
return editor
return None
return editor
def updateEditorGeometry(self, editor, option, index):
if self.editing_param_index >= 0:
if self.editing_field in ['name', 'description']:
editor.setGeometry(self.edit_rect)
elif self.editing_param_index >= 0:
params_rect = self.getParamsRect(option.rect)
param_height = 24
spacing = 4
@ -385,18 +388,32 @@ class CardItemDelegate(QStyledItemDelegate):
editor.setGeometry(editor_rect)
def setEditorData(self, editor, index):
if isinstance(editor, QLineEdit):
data = index.data(Qt.ItemDataRole.UserRole)
if self.editing_param_index >= 0 and self.editing_param_index < len(data.params):
editor.setText(data.params[self.editing_param_index].name)
if not isinstance(editor, QLineEdit):
return
data = index.data(Qt.ItemDataRole.UserRole)
if self.editing_field == 'name':
editor.setText(data.name)
elif self.editing_field == 'description':
editor.setText(data.description)
elif self.editing_param_index >= 0:
editor.setText(data.params[self.editing_param_index].name)
def setModelData(self, editor, model, index):
if isinstance(editor, QLineEdit):
data = index.data(Qt.ItemDataRole.UserRole)
if self.editing_param_index >= 0 and self.editing_param_index < len(data.params):
data.params[self.editing_param_index].name = editor.text()
model.setData(index, data, Qt.ItemDataRole.UserRole)
self.editing_param_index = -1
if not isinstance(editor, QLineEdit):
return
data = index.data(Qt.ItemDataRole.UserRole)
if self.editing_field == 'name':
data.name = editor.text()
elif self.editing_field == 'description':
data.description = editor.text()
elif self.editing_param_index >= 0:
data.params[self.editing_param_index].name = editor.text()
model.setData(index, data, Qt.ItemDataRole.UserRole)
self.editing_field = None
self.editing_param_index = -1
def paint(self, painter, option, index):
if not index.isValid():
@ -518,6 +535,37 @@ class CardItemDelegate(QStyledItemDelegate):
painter.drawText(text_rect, Qt.AlignLeft | Qt.AlignVCenter, param.name)
painter.restore()
def getParamIndex(self, pos, rect):
"""根据点击位置获取参数索引"""
if not rect.contains(pos):
return -1
param_height = 24
spacing = 4
indent = 20
# 计算点击位置对应的参数索引
relative_y = pos.y() - rect.top()
index = relative_y // (param_height + spacing)
# 确保索引在有效范围内
if 0 <= index < len(self.parent().currentItem().data(Qt.ItemDataRole.UserRole).params):
return index
return -1
def getParamRect(self, index, rect):
"""获取指定参数索引的矩形区域"""
param_height = 24
spacing = 4
indent = 20
return QRect(
rect.left() + indent,
rect.top() + index * (param_height + spacing),
rect.width() - indent,
param_height
)
if __name__ == '__main__':
app = QApplication(sys.argv)